diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/icon/icon.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/icon/icon.element.ts index 7608213899..550fde3d81 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/icon/icon.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/icon/icon.element.ts @@ -49,7 +49,9 @@ export class UmbIconElement extends UmbLitElement { UmbTextStyles, css` :host { - display: contents; + display: flex; + justify-content: center; + align-items: center; } `, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/menu-item/manifests.ts index 300913745e..6604cf0ea2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/menu-item/manifests.ts @@ -3,13 +3,13 @@ import type { ManifestMenuItem } from '@umbraco-cms/backoffice/extension-registr const menuItem: ManifestMenuItem = { type: 'menuItem', alias: 'Umb.MenuItem.Extensions', - name: 'Extensions Menu Item', - weight: 0, + name: 'Extension Insights Menu Item', + weight: 200, meta: { - label: 'Extensions', + label: 'Extension Insights', icon: 'icon-wand', entityType: 'extension-root', - menus: ['Umb.Menu.Settings'], + menus: ['Umb.Menu.AdvancedSettings'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/workspace/extension-root-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/workspace/extension-root-workspace.element.ts index 198f495da2..9c701cf6e7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/workspace/extension-root-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/workspace/extension-root-workspace.element.ts @@ -7,7 +7,10 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; export class UmbExtensionRootWorkspaceElement extends UmbLitElement { render() { return html` - + `; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/settings/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/settings/manifests.ts index 0f84871955..a87b8da871 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/settings/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/settings/manifests.ts @@ -23,16 +23,13 @@ export const manifests = [ type: 'menu', alias: 'Umb.Menu.Settings', name: 'Settings Menu', - meta: { - label: 'Settings', - }, }, { type: 'sectionSidebarApp', kind: 'menu', alias: 'Umb.SectionSidebarMenu.Settings', name: 'Settings Section Sidebar Menu', - weight: 200, + weight: 300, meta: { label: 'Settings', menu: 'Umb.Menu.Settings', @@ -44,5 +41,27 @@ export const manifests = [ }, ], }, + { + type: 'menu', + alias: 'Umb.Menu.AdvancedSettings', + name: 'Advanced Settings Menu', + }, + { + type: 'sectionSidebarApp', + kind: 'menu', + alias: 'Umb.SectionSidebarMenu.AdvancedSettings', + name: 'Advanced Settings Section Sidebar Menu', + weight: 100, + meta: { + label: 'Advanced', + menu: 'Umb.Menu.AdvancedSettings', + }, + conditions: [ + { + alias: 'Umb.Condition.SectionAlias', + match: UMB_SETTINGS_SECTION_ALIAS, + }, + ], + }, ...welcomeDashboardManifests, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/collection/repository/data-type-collection.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/collection/repository/data-type-collection.server.data-source.ts index c6dd9ce6f5..558131b3e8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/collection/repository/data-type-collection.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/collection/repository/data-type-collection.server.data-source.ts @@ -5,6 +5,7 @@ import { DataTypeResource } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbCollectionDataSource } from '@umbraco-cms/backoffice/collection'; import type { DataTypeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { type ManifestPropertyEditorUi, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; /** * A data source that fetches the data-type collection data from the server. @@ -14,6 +15,7 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; */ export class UmbDataTypeCollectionServerDataSource implements UmbCollectionDataSource { #host: UmbControllerHost; + #manifestPropertyEditorUis: Array = []; /** * Creates an instance of UmbDataTypeCollectionServerDataSource. @@ -22,6 +24,12 @@ export class UmbDataTypeCollectionServerDataSource implements UmbCollectionDataS */ constructor(host: UmbControllerHost) { this.#host = host; + umbExtensionsRegistry + .byType('propertyEditorUi') + .subscribe((manifestPropertyEditorUIs) => { + this.#manifestPropertyEditorUis = manifestPropertyEditorUIs; + }) + .unsubscribe(); } /** @@ -48,6 +56,7 @@ export class UmbDataTypeCollectionServerDataSource implements UmbCollectionDataS unique: item.id, name: item.name, propertyEditorUiAlias: item.editorUiAlias!, + icon: this.#manifestPropertyEditorUis.find((ui) => ui.alias === item.editorUiAlias!)?.meta.icon, }; return dataTypeDetail; diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/components/data-type-flow-input/data-type-flow-input.element.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/components/data-type-flow-input/data-type-flow-input.element.ts index 2f888c4a5b..d89712a6da 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/components/data-type-flow-input/data-type-flow-input.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/components/data-type-flow-input/data-type-flow-input.element.ts @@ -78,8 +78,6 @@ export class UmbInputDataTypeElement extends FormControlMixin(UmbLitElement) { this.#editDataTypeModal?.open({}, 'edit/' + this._ids![0]); }} standalone> - - diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/components/ref-data-type/ref-data-type.element.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/components/ref-data-type/ref-data-type.element.ts index 4af4380ec5..e144ad4b2e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/components/ref-data-type/ref-data-type.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/components/ref-data-type/ref-data-type.element.ts @@ -1,7 +1,8 @@ import { UmbDataTypeDetailRepository } from '../../repository/detail/data-type-detail.repository.js'; -import { UUIRefNodeElement } from '@umbraco-cms/backoffice/external/uui'; +import { UUIIconRequestEvent, UUIRefNodeElement } from '@umbraco-cms/backoffice/external/uui'; import { html, customElement, property, state, css } from '@umbraco-cms/backoffice/external/lit'; import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; /** * @element umb-ref-data-type @@ -10,8 +11,10 @@ import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; */ @customElement('umb-ref-data-type') export class UmbRefDataTypeElement extends UmbElementMixin(UUIRefNodeElement) { + @state() protected fallbackIcon = - ''; + ``; + //icon-circle-dotted.svg @property({ type: String, attribute: 'data-type-id' }) public get dataTypeId(): string | undefined { @@ -28,8 +31,11 @@ export class UmbRefDataTypeElement extends UmbElementMixin(UUIRefNodeElement) { (dataType) => { if (dataType) { this.name = dataType.name ?? ''; - this.propertyEditorUiAlias = dataType.editorUiAlias ?? ''; this.propertyEditorSchemaAlias = dataType.editorAlias ?? ''; + if (dataType.editorUiAlias ?? '' !== this.propertyEditorUiAlias) { + this.propertyEditorUiAlias = dataType.editorUiAlias ?? ''; + this.#getIconFromUiAlias(); + } } }, 'dataType', @@ -53,6 +59,37 @@ export class UmbRefDataTypeElement extends UmbElementMixin(UUIRefNodeElement) { @state() propertyEditorSchemaAlias = ''; + async #getIconFromUiAlias() { + if (!this.propertyEditorUiAlias) return; + this.observe( + umbExtensionsRegistry.byTypeAndAlias('propertyEditorUi', this.propertyEditorUiAlias), + async (manifestPropertyEditorUi) => { + const icon = manifestPropertyEditorUi?.meta.icon; + /** [LI] We have the icon name now, but because this element extends from uui-ref-node, it wants the icon via the icon slot. + * From what I can see, this is not possible via this file, but this is the file that have the datatype data.... + * Instead, overwriting the fallbackIcon property which requires a SVG... */ + if (icon) { + this.#requestIconSVG(icon); + } + }, + ), + '_observeIcon'; + } + + #requestIconSVG(iconName: string) { + if (iconName !== '' && iconName !== null) { + const event = new UUIIconRequestEvent(UUIIconRequestEvent.ICON_REQUEST, { + detail: { iconName: iconName }, + }); + this.dispatchEvent(event); + if (event.icon !== null) { + event.icon.then((iconSvg: string) => { + this.fallbackIcon = iconSvg; + }); + } + } + } + protected renderDetail() { const details: string[] = []; diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-data-type-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-data-type-picker-modal.element.ts index 9df268dfcf..23d0012b14 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-data-type-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-data-type-picker-modal.element.ts @@ -86,7 +86,7 @@ export class UmbDataTypePickerFlowDataTypePickerModalElement extends UmbModalBas ? html`
  • - + ${dataType.name}
    diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts index af03a97473..d0d634e4e0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts @@ -1,4 +1,3 @@ -import { UmbDataTypeTreeRepository } from '../../tree/data-type-tree.repository.js'; import { UMB_DATATYPE_WORKSPACE_MODAL } from '../../workspace/data-type-workspace.modal-token.js'; import { UMB_DATA_TYPE_ENTITY_TYPE } from '../../entity.js'; import { UmbDataTypeCollectionRepository } from '../../collection/index.js'; @@ -275,10 +274,10 @@ export class UmbDataTypePickerFlowModalElement extends UmbModalBaseElement< dataTypes, (dataType) => dataType.unique, (dataType) => - html`
  • + html`
  • - + ${dataType.name}
    diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/data-type-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/data-type-item.server.data-source.ts index d2963a59c1..6e5faabc94 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/data-type-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/data-type-item.server.data-source.ts @@ -3,6 +3,9 @@ import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository' import type { DataTypeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { DataTypeResource } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { type ManifestPropertyEditorUi, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; + +let manifestPropertyEditorUis: Array = []; /** * A server data source for Data Type items @@ -19,11 +22,19 @@ export class UmbDataTypeItemServerDataSource extends UmbItemServerDataSourceBase * @param {UmbControllerHost} host * @memberof UmbDataTypeItemServerDataSource */ + constructor(host: UmbControllerHost) { super(host, { getItems, mapper, }); + + umbExtensionsRegistry + .byType('propertyEditorUi') + .subscribe((manifestPropertyEditorUIs) => { + manifestPropertyEditorUis = manifestPropertyEditorUIs; + }) + .unsubscribe(); } } @@ -35,5 +46,6 @@ const mapper = (item: DataTypeItemResponseModel): UmbDataTypeItemModel => { unique: item.id, name: item.name, propertyEditorUiAlias: item.editorUiAlias || '', // TODO: why can this be undefined or null on the server? + icon: manifestPropertyEditorUis.find((ui) => ui.alias === item.editorUiAlias)?.meta.icon, }; }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/types.ts index d798ac80cc..185aa5cba4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/types.ts @@ -2,4 +2,5 @@ export interface UmbDataTypeItemModel { unique: string; name: string; propertyEditorUiAlias: string; + icon?: string; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/data-type-tree.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/data-type-tree.server.data-source.ts index d4fda7664a..7f0af01905 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/data-type-tree.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/data-type-tree.server.data-source.ts @@ -4,6 +4,9 @@ import { UmbTreeServerDataSourceBase } from '@umbraco-cms/backoffice/tree'; import type { DataTypeTreeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { DataTypeResource } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { type ManifestPropertyEditorUi, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; + +let manifestPropertyEditorUis: Array = []; /** * A data source for a data type tree that fetches data from the server @@ -26,12 +29,19 @@ export class UmbDataTypeTreeServerDataSource extends UmbTreeServerDataSourceBase getChildrenOf, mapper, }); + umbExtensionsRegistry + .byType('propertyEditorUi') + .subscribe((manifestPropertyEditorUIs) => { + manifestPropertyEditorUis = manifestPropertyEditorUIs; + }) + .unsubscribe(); } } -const getRootItems = (args: UmbTreeRootItemsRequestArgs) => +const getRootItems = async (args: UmbTreeRootItemsRequestArgs) => { // eslint-disable-next-line local-rules/no-direct-api-import - DataTypeResource.getTreeDataTypeRoot({ skip: args.skip, take: args.take }); + return DataTypeResource.getTreeDataTypeRoot({ skip: args.skip, take: args.take }); +}; const getChildrenOf = (args: UmbTreeChildrenOfRequestArgs) => { if (args.parentUnique === null) { @@ -48,6 +58,7 @@ const mapper = (item: DataTypeTreeItemResponseModel): UmbDataTypeTreeItemModel = return { unique: item.id, parentUnique: item.parent?.id || null, + icon: manifestPropertyEditorUis.find((ui) => ui.alias === item.editorUiAlias)?.meta.icon, name: item.name, entityType: item.isFolder ? 'data-type-folder' : 'data-type', isFolder: item.isFolder, diff --git a/src/Umbraco.Web.UI.Client/src/packages/dictionary/menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/dictionary/menu/manifests.ts index bd909ef43c..f11c647652 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/dictionary/menu/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/dictionary/menu/manifests.ts @@ -8,9 +8,6 @@ const menu: ManifestMenu = { type: 'menu', alias: UMB_DICTIONARY_MENU_ALIAS, name: 'Dictionary Menu', - meta: { - label: 'Dictionary', - }, }; const menuItem: ManifestMenuItemTreeKind = { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/menu.manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/menu.manifests.ts index 6bb7fe2726..72a75a52bf 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/menu.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/menu.manifests.ts @@ -6,9 +6,6 @@ const menu: ManifestMenu = { type: 'menu', alias: UMB_CONTENT_MENU_ALIAS, name: 'Content Menu', - meta: { - label: 'Content', - }, }; export const manifests = [menu]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/menu-item/manifests.ts index 90e1fb7c0b..34a5fff422 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/menu-item/manifests.ts @@ -3,13 +3,13 @@ import type { ManifestMenuItem } from '@umbraco-cms/backoffice/extension-registr const menuItem: ManifestMenuItem = { type: 'menuItem', alias: 'Umb.MenuItem.LogViewer', - name: 'LogViewer Menu Item', + name: 'Log Viewer Menu Item', weight: 300, meta: { label: 'Log Viewer', icon: 'icon-box-alt', entityType: 'logviewer', - menus: ['Umb.Menu.Settings'], + menus: ['Umb.Menu.AdvancedSettings'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/menu.manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/menu.manifests.ts index 7f7f2a0444..b10c33a8be 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/menu.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/menu.manifests.ts @@ -6,9 +6,6 @@ const menu: ManifestMenu = { type: 'menu', alias: UMB_MEDIA_MENU_ALIAS, name: 'Media Menu', - meta: { - label: 'Media', - }, }; export const manifests = [menu]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/menu.manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/menu.manifests.ts index cdefc905ff..a807f482be 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/menu.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/menu.manifests.ts @@ -4,9 +4,6 @@ const menu: ManifestMenu = { type: 'menu', alias: 'Umb.Menu.Media', name: 'Media Menu', - meta: { - label: 'Media', - }, }; export const manifests = [menu]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relation-types/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relation-types/menu-item/manifests.ts index ef111632a2..297b8c6f93 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relation-types/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relation-types/menu-item/manifests.ts @@ -6,11 +6,11 @@ const menuItem: ManifestTypes = { kind: 'tree', alias: 'Umb.MenuItem.RelationTypes', name: 'Relation Types Menu Item', - weight: 500, + weight: 100, meta: { treeAlias: UMB_RELATION_TYPE_TREE_ALIAS, label: 'Relation Types', - menus: ['Umb.Menu.Settings'], + menus: ['Umb.Menu.AdvancedSettings'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/menu.manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/menu.manifests.ts index 0b1437c2b5..a353119dea 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/menu.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/menu.manifests.ts @@ -6,9 +6,6 @@ const menu: ManifestMenu = { type: 'menu', alias: 'Umb.Menu.Templating', name: 'Templating Menu', - meta: { - label: 'Templating', - }, }; const menuSectionSidebarApp: ManifestTypes = { @@ -16,7 +13,7 @@ const menuSectionSidebarApp: ManifestTypes = { kind: 'menu', alias: 'Umb.SectionSidebarMenu.Templating', name: 'Templating Section Sidebar Menu', - weight: 100, + weight: 200, meta: { label: 'Templating', menu: 'Umb.Menu.Templating',