diff --git a/src/Umbraco.Web.UI.Client/schemas/api/api.yml b/src/Umbraco.Web.UI.Client/schemas/api/api.yml index 5b1a95d5cb..a63055d72a 100644 --- a/src/Umbraco.Web.UI.Client/schemas/api/api.yml +++ b/src/Umbraco.Web.UI.Client/schemas/api/api.yml @@ -544,6 +544,10 @@ components: MetaPropertyEditorUI: type: object properties: + propertyEditors: + type: array + items: + type: string icon: type: string group: @@ -560,6 +564,7 @@ components: defaultConfig: type: object required: + - propertyEditors - icon - group IManifestPropertyEditorUI: diff --git a/src/Umbraco.Web.UI.Client/schemas/generated-schema.ts b/src/Umbraco.Web.UI.Client/schemas/generated-schema.ts index 5fba7f4b22..38d29ae3eb 100644 --- a/src/Umbraco.Web.UI.Client/schemas/generated-schema.ts +++ b/src/Umbraco.Web.UI.Client/schemas/generated-schema.ts @@ -174,6 +174,7 @@ export interface components { view: string; }; MetaPropertyEditorUI: { + propertyEditors: string[]; icon: string; group: string; prevalues?: { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/data-type/data-type.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/data-type/data-type.context.ts index 2c23ebb6e9..7199ba1320 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/data-type/data-type.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/data-type/data-type.context.ts @@ -11,6 +11,7 @@ export class UmbDataTypeContext { hasChildren: false, parentKey: '', isTrashed: false, + propertyEditorAlias: '', propertyEditorUIAlias: '', }); public readonly data: Observable = this._data.asObservable(); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/data-type/views/edit/editor-view-data-type-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/data-type/views/edit/editor-view-data-type-edit.element.ts index c91669c659..56d3e8a56b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/data-type/views/edit/editor-view-data-type-edit.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/data-type/views/edit/editor-view-data-type-edit.element.ts @@ -1,16 +1,17 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, LitElement } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { Subscription, distinctUntilChanged } from 'rxjs'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { when } from 'lit-html/directives/when.js'; +import { Subscription, distinctUntilChanged, map } from 'rxjs'; import { UmbModalService } from '../../../../../core/services/modal'; import { UmbContextConsumerMixin } from '../../../../../core/context'; -import type { ManifestPropertyEditorUI } from '../../../../../core/models'; import { UmbDataTypeContext } from '../../data-type.context'; import type { DataTypeEntity } from '../../../../../mocks/data/data-type.data'; 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') export class UmbEditorViewDataTypeEditElement extends UmbContextConsumerMixin(LitElement) { static styles = [UUITextStyles, css``]; @@ -19,25 +20,55 @@ export class UmbEditorViewDataTypeEditElement extends UmbContextConsumerMixin(Li _dataType?: DataTypeEntity; @state() - private _propertyEditorUIs: Array = []; + private _propertyEditorIcon = ''; + + @state() + private _propertyEditorName = ''; + + @state() + private _propertyEditorAlias = ''; + + @state() + private _propertyEditorUIIcon = ''; + + @state() + private _propertyEditorUIName = ''; + + @state() + private _propertyEditorUIAlias = ''; - private _extensionRegistry?: UmbExtensionRegistry; private _dataTypeContext?: UmbDataTypeContext; + private _extensionRegistry?: UmbExtensionRegistry; + private _propertyEditorStore?: UmbPropertyEditorStore; private _dataTypeSubscription?: Subscription; + private _propertyEditorSubscription?: Subscription; + private _propertyEditorUISubscription?: Subscription; + private _availablePropertyEditorUIsSubscription?: Subscription; private _modalService?: UmbModalService; constructor() { super(); + this.consumeContext('umbModalService', (modalService) => { + this._modalService = modalService; + }); + + // TODO: wait for more contexts this.consumeContext('umbDataTypeContext', (dataTypeContext) => { this._dataTypeContext = dataTypeContext; this._observeDataType(); }); - this.consumeContext('umbModalService', (modalService) => { - this._modalService = modalService; + this.consumeContext('umbPropertyEditorStore', (propertyEditorStore) => { + 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()) .subscribe((dataType: DataTypeEntity) => { 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(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 }); modalHandler?.onClose().then((returnValue) => { - if (!this._dataType || !returnValue.selection) return; + if (!returnValue.selection) return; const propertyEditorAlias = returnValue.selection[0]; - this._dataType.propertyEditorAlias = propertyEditorAlias; - this._dataTypeContext?.update({ propertyEditorAlias }); + this._selectPropertyEditor(propertyEditorAlias); }); } + private _selectPropertyEditor(propertyEditorAlias: string) { + if (!this._dataType) return; + + this._dataType.propertyEditorAlias = propertyEditorAlias; + this._dataTypeContext?.update({ propertyEditorAlias }); + } + private _openPropertyEditorUIPicker() { if (!this._dataType) return; @@ -73,38 +165,81 @@ export class UmbEditorViewDataTypeEditElement extends UmbContextConsumerMixin(Li const modalHandler = this._modalService?.propertyEditorUIPicker({ selection }); modalHandler?.onClose().then((returnValue) => { - if (!this._dataType || !returnValue.selection) return; + if (!returnValue.selection) return; const propertyEditorUIAlias = returnValue.selection[0]; - this._dataType.propertyEditorUIAlias = propertyEditorUIAlias; - this._dataTypeContext?.update({ propertyEditorUIAlias }); + this._selectPropertyEditorUI(propertyEditorUIAlias); }); } + private _selectPropertyEditorUI(propertyEditorUIAlias: string) { + if (!this._dataType) return; + + this._dataType.propertyEditorUIAlias = propertyEditorUIAlias; + this._dataTypeContext?.update({ propertyEditorUIAlias }); + } + disconnectedCallback(): void { super.disconnectedCallback(); this._dataTypeSubscription?.unsubscribe(); + this._propertyEditorSubscription?.unsubscribe(); + this._propertyEditorUISubscription?.unsubscribe(); + this._availablePropertyEditorUIsSubscription?.unsubscribe(); } render() { return html` -

Property Editor

- - - - - - + ${this._renderPropertyEditor()} + ${when(this._dataType?.propertyEditorAlias, () => html` ${this._renderPropertyEditorUI()} `)}
+ `; + } -

Property Editor UI

- - - - - - - + private _renderPropertyEditor() { + return html` +

Property Editor

+ + ${this._dataType?.propertyEditorAlias + ? html` + + + + + + + + ` + : html``} + `; + } + + private _renderPropertyEditorUI() { + return html` +

Property Editor UI

+ + ${this._dataType?.propertyEditorUIAlias + ? html` + + + + + + + + ` + : html``} `; } } diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/property-editor-picker/modal-layout-property-editor-picker.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/property-editor-picker/modal-layout-property-editor-picker.element.ts index c257ba4441..bd94b36ab8 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/property-editor-picker/modal-layout-property-editor-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/property-editor-picker/modal-layout-property-editor-picker.element.ts @@ -1,4 +1,5 @@ import { css, html, LitElement } from 'lit'; +import { repeat } from 'lit/directives/repeat.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property, state } from 'lit/decorators.js'; import { UmbContextConsumerMixin } from '../../../../context'; @@ -6,15 +7,76 @@ import { UmbContextConsumerMixin } from '../../../../context'; import type { Subscription } from 'rxjs'; import type { UmbModalHandler } from '../../modal-handler'; 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 { selection?: Array; + multiple?: boolean; + submitLabel?: string; } @customElement('umb-modal-layout-property-editor-picker') 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 }) modalHandler?: UmbModalHandler; @@ -23,10 +85,15 @@ export class UmbModalLayoutPropertyEditorPickerElement extends UmbContextConsume data?: UmbModalPropertyEditorPickerData; @state() - private _propertyEditors: Array = []; + private _filteredPropertyEditors: Array = []; @state() - private _selection?: Array; + private _selection: Array = []; + + @state() + private _submitLabel = 'Select'; + + private _propertyEditors: Array = []; private _propertyEditorStore?: UmbPropertyEditorStore; private _propertyEditorsSubscription?: Subscription; @@ -42,17 +109,52 @@ export class UmbModalLayoutPropertyEditorPickerElement extends UmbContextConsume connectedCallback(): void { super.connectedCallback(); - this._selection = this.data?.selection || []; + this._selection = this.data?.selection ?? []; + this._submitLabel = this.data?.submitLabel ?? this._submitLabel; } private _observePropertyEditors() { this._propertyEditorsSubscription = this._propertyEditorStore?.getAll().subscribe((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() { - this.modalHandler?.close({ selection: this._selection }); + this.modalHandler?.close(); } private _submit() { @@ -67,14 +169,39 @@ export class UmbModalLayoutPropertyEditorPickerElement extends UmbContextConsume render() { return html` - ${this._propertyEditors.map((propertyEditor) => html`
${propertyEditor.name}
`)}
+ ${this._renderFilter()} ${this._renderGrid()}
- +
`; } + + private _renderFilter() { + return html` + + `; + } + + private _renderGrid() { + return html`
    + ${repeat( + this._filteredPropertyEditors, + (propertyEditor) => propertyEditor.alias, + (propertyEditor) => html`
  • + +
  • ` + )} +
`; + } } declare global { diff --git a/src/Umbraco.Web.UI.Client/src/core/stores/property-editor.store.ts b/src/Umbraco.Web.UI.Client/src/core/stores/property-editor.store.ts index 056802fa78..60d53e92b3 100644 --- a/src/Umbraco.Web.UI.Client/src/core/stores/property-editor.store.ts +++ b/src/Umbraco.Web.UI.Client/src/core/stores/property-editor.store.ts @@ -1,4 +1,4 @@ -import { BehaviorSubject, Observable } from 'rxjs'; +import { BehaviorSubject, map, Observable } from 'rxjs'; import { PropertyEditor } from '../../mocks/data/property-editor.data'; export class UmbPropertyEditorStore { @@ -16,4 +16,48 @@ export class UmbPropertyEditorStore { return this.items; } + + getByAlias(alias: string): Observable { + // 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) { + 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]); + } } diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/data-type.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/data-type.data.ts index aa57b12f01..bef941756d 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/data-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/data-type.data.ts @@ -16,8 +16,10 @@ export const data: Array = [ isTrashed: false, hasChildren: false, icon: '', - propertyEditorAlias: 'Umb.PropertyEditor.Text', - propertyEditorUIAlias: 'Umb.PropertyEditorUI.Text', + propertyEditorAlias: '', + propertyEditorUIAlias: '', + //propertyEditorAlias: 'Umbraco.TextBox', + //propertyEditorUIAlias: 'Umb.PropertyEditorUI.Text', }, { key: 'dt-2', @@ -27,7 +29,7 @@ export const data: Array = [ isTrashed: false, hasChildren: false, icon: '', - propertyEditorAlias: 'Umb.PropertyEditor.Textarea', + propertyEditorAlias: 'Umbraco.TextArea', propertyEditorUIAlias: 'Umb.PropertyEditorUI.Textarea', }, { @@ -38,7 +40,7 @@ export const data: Array = [ isTrashed: false, hasChildren: false, icon: '', - propertyEditorAlias: 'Umb.PropertyEditor.Custom', + propertyEditorAlias: 'Umbraco.Custom', propertyEditorUIAlias: 'My.PropertyEditorUI.Custom', }, { @@ -49,7 +51,7 @@ export const data: Array = [ isTrashed: false, hasChildren: false, icon: '', - propertyEditorAlias: 'Umb.PropertyEditor.ContextExample', + propertyEditorAlias: 'Umbraco.Custom', propertyEditorUIAlias: 'Umb.PropertyEditorUI.ContextExample', }, { @@ -60,7 +62,7 @@ export const data: Array = [ isTrashed: false, hasChildren: false, icon: '', - propertyEditorAlias: 'Umb.PropertyEditor.ContentPicker', + propertyEditorAlias: 'Umbraco.ContentPicker', propertyEditorUIAlias: 'Umb.PropertyEditorUI.ContentPicker', }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/property-editor.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/property-editor.data.ts index 461fbf5c15..b019560c53 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/property-editor.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/property-editor.data.ts @@ -15,7 +15,7 @@ export const data: Array = [ { alias: 'Umbraco.BlockGrid', name: 'Block Grid', - icon: 'icon-thumbnail-list', + icon: 'umb:thumbnail-list', editor: { view: '', }, @@ -23,7 +23,7 @@ export const data: Array = [ { alias: 'Umbraco.BlockList', name: 'Block List', - icon: 'icon-thumbnail-list', + icon: 'umb:thumbnail-list', editor: { view: '', }, @@ -31,7 +31,7 @@ export const data: Array = [ { alias: 'Umbraco.CheckBoxList', name: 'Checkbox list', - icon: 'icon-bulleted-list', + icon: 'umb:bulleted-list', editor: { view: '', }, @@ -39,7 +39,7 @@ export const data: Array = [ { alias: 'Umbraco.ColorPicker', name: 'Color Picker', - icon: 'icon-colorpicker', + icon: 'umb:colorpicker', editor: { view: '', }, @@ -47,7 +47,7 @@ export const data: Array = [ { alias: 'Umbraco.ContentPicker', name: 'Content Picker', - icon: 'icon-autofill', + icon: 'umb:autofill', editor: { view: '', }, @@ -55,7 +55,7 @@ export const data: Array = [ { alias: 'Umbraco.DateTime', name: 'Date/Time', - icon: 'icon-time', + icon: 'umb:time', editor: { view: '', }, @@ -63,7 +63,7 @@ export const data: Array = [ { alias: 'Umbraco.Decimal', name: 'Decimal', - icon: 'icon-autofill', + icon: 'umb:autofill', editor: { view: '', }, @@ -71,7 +71,7 @@ export const data: Array = [ { alias: 'Umbraco.DropDown.Flexible', name: 'Dropdown', - icon: 'icon-indent', + icon: 'umb:indent', editor: { view: '', }, @@ -79,7 +79,7 @@ export const data: Array = [ { alias: 'Umbraco.EmailAddress', name: 'Email address', - icon: 'icon-message', + icon: 'umb:message', editor: { view: '', }, @@ -87,7 +87,7 @@ export const data: Array = [ { alias: 'Umbraco.ColorPicker.EyeDropper', name: 'Eye Dropper Color Picker', - icon: 'icon-colorpicker', + icon: 'umb:colorpicker', editor: { view: '', }, @@ -95,7 +95,7 @@ export const data: Array = [ { alias: 'Umbraco.UploadField', name: 'File upload', - icon: 'icon-download-alt', + icon: 'umb:download-alt', editor: { view: '', }, @@ -103,7 +103,7 @@ export const data: Array = [ { alias: 'Umbraco.Grid', name: 'Grid layout', - icon: 'icon-layout', + icon: 'umb:layout', editor: { view: '', }, @@ -111,7 +111,7 @@ export const data: Array = [ { alias: 'Umbraco.ImageCropper', name: 'Image Cropper', - icon: 'icon-crop', + icon: 'umb:crop', editor: { view: '', }, @@ -119,7 +119,7 @@ export const data: Array = [ { alias: 'Umbraco.Label', name: 'Label', - icon: 'icon-readonly', + icon: 'umb:readonly', editor: { view: '', }, @@ -127,7 +127,7 @@ export const data: Array = [ { alias: 'Umbraco.ListView', name: 'List view', - icon: 'icon-thumbnail-list', + icon: 'umb:thumbnail-list', editor: { view: '', }, @@ -135,7 +135,7 @@ export const data: Array = [ { alias: 'Umbraco.MarkdownEditor', name: 'Markdown editor', - icon: 'icon-code', + icon: 'umb:code', editor: { view: '', }, @@ -143,7 +143,7 @@ export const data: Array = [ { alias: 'Umbraco.MediaPicker3', name: 'Media Picker', - icon: 'icon-picture', + icon: 'umb:picture', editor: { view: '', }, @@ -151,7 +151,7 @@ export const data: Array = [ { alias: 'Umbraco.MediaPicker', name: 'Media Picker (legacy)', - icon: 'icon-picture', + icon: 'umb:picture', editor: { view: '', }, @@ -159,7 +159,7 @@ export const data: Array = [ { alias: 'Umbraco.MemberGroupPicker', name: 'Member Group Picker', - icon: 'icon-users-alt', + icon: 'umb:users-alt', editor: { view: '', }, @@ -167,7 +167,7 @@ export const data: Array = [ { alias: 'Umbraco.MemberPicker', name: 'Member Picker', - icon: 'icon-user', + icon: 'umb:user', editor: { view: '', }, @@ -175,7 +175,7 @@ export const data: Array = [ { alias: 'Umbraco.MultiUrlPicker', name: 'Multi URL Picker', - icon: 'icon-link', + icon: 'umb:link', editor: { view: '', }, @@ -183,7 +183,7 @@ export const data: Array = [ { alias: 'Umbraco.MultiNodeTreePicker', name: 'Multinode Treepicker', - icon: 'icon-page-add', + icon: 'umb:page-add', editor: { view: '', }, @@ -191,7 +191,7 @@ export const data: Array = [ { alias: 'Umbraco.NestedContent', name: 'Nested Content', - icon: 'icon-thumbnail-list', + icon: 'umb:thumbnail-list', editor: { view: '', }, @@ -199,7 +199,7 @@ export const data: Array = [ { alias: 'Umbraco.Integer', name: 'Numeric', - icon: 'icon-autofill', + icon: 'umb:autofill', editor: { view: '', }, @@ -207,7 +207,7 @@ export const data: Array = [ { alias: 'Umbraco.RadioButtonList', name: 'Radio button list', - icon: 'icon-target', + icon: 'umb:target', editor: { view: '', }, @@ -215,7 +215,7 @@ export const data: Array = [ { alias: 'Umbraco.MultipleTextstring', name: 'Repeatable textstrings', - icon: 'icon-ordered-list', + icon: 'umb:ordered-list', editor: { view: '', }, @@ -223,7 +223,7 @@ export const data: Array = [ { alias: 'Umbraco.TinyMCE', name: 'Rich Text Editor', - icon: 'icon-browser-window', + icon: 'umb:browser-window', editor: { view: '', }, @@ -231,7 +231,7 @@ export const data: Array = [ { alias: 'Umbraco.Slider', name: 'Slider', - icon: 'icon-navigation-horizontal', + icon: 'umb:navigation-horizontal', editor: { view: '', }, @@ -239,7 +239,7 @@ export const data: Array = [ { alias: 'Umbraco.Tags', name: 'Tags', - icon: 'icon-tags', + icon: 'umb:tags', editor: { view: '', }, @@ -247,7 +247,7 @@ export const data: Array = [ { alias: 'Umbraco.TextArea', name: 'Textarea', - icon: 'icon-application-window-alt', + icon: 'umb:application-window-alt', editor: { view: '', }, @@ -255,7 +255,7 @@ export const data: Array = [ { alias: 'Umbraco.TextBox', name: 'Textbox', - icon: 'icon-autofill', + icon: 'umb:autofill', editor: { view: '', }, @@ -263,7 +263,7 @@ export const data: Array = [ { alias: 'Umbraco.TrueFalse', name: 'Toggle', - icon: 'icon-checkbox', + icon: 'umb:checkbox', editor: { view: '', }, @@ -271,7 +271,15 @@ export const data: Array = [ { alias: 'Umbraco.UserPicker', name: 'User Picker', - icon: 'icon-user', + icon: 'umb:user', + editor: { + view: '', + }, + }, + { + alias: 'Umbraco.Custom', + name: 'Custom Property Editor', + icon: 'umb:document', editor: { view: '', }, @@ -287,6 +295,10 @@ class UmbPropertyEditorData extends UmbData { getAll() { return this.data; } + + getByAlias(alias: string) { + return this.data.find((x) => x.alias === alias); + } } export const umbPropertyEditorData = new UmbPropertyEditorData(); diff --git a/src/Umbraco.Web.UI.Client/src/mocks/domains/manifests.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/domains/manifests.handlers.ts index 0d29036c86..b6845dab9d 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/domains/manifests.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/domains/manifests.handlers.ts @@ -30,6 +30,7 @@ export const manifestDevelopmentHandler = rest.get(umbracoPath('/manifests'), (_ meta: { icon: 'document', group: 'common', + propertyEditors: ['Umbraco.Custom'], }, }, { diff --git a/src/Umbraco.Web.UI.Client/src/mocks/domains/property-editor.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/domains/property-editor.handlers.ts index b6a6b2a9e4..6bd3fe83a8 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/domains/property-editor.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/domains/property-editor.handlers.ts @@ -9,4 +9,14 @@ export const handlers = [ 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])); + }), ]; diff --git a/src/Umbraco.Web.UI.Client/src/temp-internal-manifests.ts b/src/Umbraco.Web.UI.Client/src/temp-internal-manifests.ts index cfc61f5746..70d4f03098 100644 --- a/src/Umbraco.Web.UI.Client/src/temp-internal-manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/temp-internal-manifests.ts @@ -138,6 +138,7 @@ export const internalManifests: Array Promise Promise Promise Promise import('./backoffice/property-editors/content-picker/property-editor-content-picker.element'), meta: { + propertyEditors: ['Umbraco.ContentPicker'], icon: 'document', group: 'common', }, diff --git a/src/Umbraco.Web.UI.Client/temp-schema-generator/manifests.ts b/src/Umbraco.Web.UI.Client/temp-schema-generator/manifests.ts index 70fc40c1d5..a4f0e2883d 100644 --- a/src/Umbraco.Web.UI.Client/temp-schema-generator/manifests.ts +++ b/src/Umbraco.Web.UI.Client/temp-schema-generator/manifests.ts @@ -113,6 +113,7 @@ export interface MetaTreeItemAction { weight: number; } export interface MetaPropertyEditorUI extends IPrevalues { + propertyEditors: Array; icon: string; group: string; }