diff --git a/src/packages/core/menu/components/menu-item/menu-item-default.element.ts b/src/packages/core/menu/components/menu-item/menu-item-default.element.ts index 75fbc48075..916598bc99 100644 --- a/src/packages/core/menu/components/menu-item/menu-item-default.element.ts +++ b/src/packages/core/menu/components/menu-item/menu-item-default.element.ts @@ -45,7 +45,8 @@ export class UmbMenuItemDefaultElement extends UmbLitElement implements UmbMenuI + .label=${this.localize.string(this.manifest.meta.label ?? this.manifest.name)} + .entityType=${this.manifest.meta.entityType}> `; } diff --git a/src/packages/user/manifests.ts b/src/packages/user/manifests.ts index 96353d28f7..d649d8f06f 100644 --- a/src/packages/user/manifests.ts +++ b/src/packages/user/manifests.ts @@ -1,6 +1,6 @@ import { manifests as userGroupManifests } from './user-group/manifests.js'; import { manifests as userManifests } from './user/manifests.js'; -import { manifests as userSectionManifests } from './user-section/manifests.js'; +import { manifests as userSectionManifests } from './section/manifests.js'; import { manifests as currentUserManifests } from './current-user/manifests.js'; import { manifests as userPermissionManifests } from './user-permission/manifests.js'; import { manifests as changePasswordManifests } from './change-password/manifests.js'; diff --git a/src/packages/user/user-section/constants.ts b/src/packages/user/section/constants.ts similarity index 100% rename from src/packages/user/user-section/constants.ts rename to src/packages/user/section/constants.ts diff --git a/src/packages/user/user-section/index.ts b/src/packages/user/section/index.ts similarity index 100% rename from src/packages/user/user-section/index.ts rename to src/packages/user/section/index.ts diff --git a/src/packages/user/section/manifests.ts b/src/packages/user/section/manifests.ts new file mode 100644 index 0000000000..bb49da5322 --- /dev/null +++ b/src/packages/user/section/manifests.ts @@ -0,0 +1,31 @@ +import { UMB_USER_MANAGEMENT_SECTION_ALIAS } from './constants.js'; +import { manifests as sectionSidebarAppManifests } from './sidebar-app/manifests.js'; +import { manifests as menuManifests } from './menu/manifests.js'; +import type { + ManifestSection, + ManifestTypes, + UmbBackofficeManifestKind, +} from '@umbraco-cms/backoffice/extension-registry'; + +const section: ManifestSection = { + type: 'section', + alias: UMB_USER_MANAGEMENT_SECTION_ALIAS, + name: 'User Management Section', + weight: 600, + meta: { + label: '#sections_users', + pathname: 'user-management', + }, + conditions: [ + { + alias: 'Umb.Condition.SectionUserPermission', + match: UMB_USER_MANAGEMENT_SECTION_ALIAS, + }, + ], +}; + +export const manifests: Array = [ + section, + ...sectionSidebarAppManifests, + ...menuManifests, +]; diff --git a/src/packages/user/section/menu/constants.ts b/src/packages/user/section/menu/constants.ts new file mode 100644 index 0000000000..7bf050d53c --- /dev/null +++ b/src/packages/user/section/menu/constants.ts @@ -0,0 +1 @@ +export const UMB_USER_MANAGEMENT_MENU_ALIAS = 'Umb.Menu.UserManagement'; diff --git a/src/packages/user/section/menu/index.ts b/src/packages/user/section/menu/index.ts new file mode 100644 index 0000000000..4f07201dcf --- /dev/null +++ b/src/packages/user/section/menu/index.ts @@ -0,0 +1 @@ +export * from './constants.js'; diff --git a/src/packages/user/section/menu/manifests.ts b/src/packages/user/section/menu/manifests.ts new file mode 100644 index 0000000000..f5852aa534 --- /dev/null +++ b/src/packages/user/section/menu/manifests.ts @@ -0,0 +1,9 @@ +import { UMB_USER_MANAGEMENT_MENU_ALIAS } from './constants.js'; + +export const manifests = [ + { + type: 'menu', + alias: UMB_USER_MANAGEMENT_MENU_ALIAS, + name: 'User Management Menu', + }, +]; diff --git a/src/packages/user/user-section/paths.ts b/src/packages/user/section/paths.ts similarity index 100% rename from src/packages/user/user-section/paths.ts rename to src/packages/user/section/paths.ts diff --git a/src/packages/user/section/sidebar-app/index.ts b/src/packages/user/section/sidebar-app/index.ts new file mode 100644 index 0000000000..42f853e5be --- /dev/null +++ b/src/packages/user/section/sidebar-app/index.ts @@ -0,0 +1 @@ +export * from '../constants.js'; diff --git a/src/packages/user/section/sidebar-app/manifests.ts b/src/packages/user/section/sidebar-app/manifests.ts new file mode 100644 index 0000000000..f21d698bc2 --- /dev/null +++ b/src/packages/user/section/sidebar-app/manifests.ts @@ -0,0 +1,23 @@ +import { UMB_USER_MANAGEMENT_SECTION_ALIAS } from '../constants.js'; +import { UMB_USER_MANAGEMENT_MENU_ALIAS } from '../menu/index.js'; +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'sectionSidebarApp', + kind: 'menu', + alias: 'Umb.SectionSidebarApp.Menu.UserManagement', + name: 'User Management Menu Sidebar App', + weight: 100, + meta: { + label: '#treeHeaders_users', + menu: UMB_USER_MANAGEMENT_MENU_ALIAS, + }, + conditions: [ + { + alias: 'Umb.Condition.SectionAlias', + match: UMB_USER_MANAGEMENT_SECTION_ALIAS, + }, + ], + }, +]; diff --git a/src/packages/user/user-group/collection/action/manifests.ts b/src/packages/user/user-group/collection/action/manifests.ts index 1168e303e3..3f67cc84e1 100644 --- a/src/packages/user/user-group/collection/action/manifests.ts +++ b/src/packages/user/user-group/collection/action/manifests.ts @@ -1,3 +1,4 @@ +import { UMB_USER_GROUP_WORKSPACE_PATH } from '../../paths.js'; import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; @@ -9,7 +10,7 @@ export const createManifest: ManifestTypes = { weight: 200, meta: { label: '#general_create', - href: 'section/user-management/view/user-groups/user-group/create', + href: `${UMB_USER_GROUP_WORKSPACE_PATH}/create`, }, conditions: [ { diff --git a/src/packages/user/user-group/entity.ts b/src/packages/user/user-group/entity.ts index 40fc592fed..3978bfa6a5 100644 --- a/src/packages/user/user-group/entity.ts +++ b/src/packages/user/user-group/entity.ts @@ -1,3 +1,5 @@ export const UMB_USER_GROUP_ENTITY_TYPE = 'user-group'; +export const UMB_USER_GROUP_ROOT_ENTITY_TYPE = 'user-group-root'; export type UmbUserGroupEntityType = typeof UMB_USER_GROUP_ENTITY_TYPE; +export type UmbUserGroupRootEntityType = typeof UMB_USER_GROUP_ROOT_ENTITY_TYPE; diff --git a/src/packages/user/user-group/manifests.ts b/src/packages/user/user-group/manifests.ts index 4a03fbb339..7db75cbebf 100644 --- a/src/packages/user/user-group/manifests.ts +++ b/src/packages/user/user-group/manifests.ts @@ -1,18 +1,21 @@ import { manifests as collectionManifests } from './collection/manifests.js'; -import { manifests as repositoryManifests } from './repository/manifests.js'; -import { manifests as workspaceManifests } from './workspace/manifests.js'; -import { manifests as modalManifests } from './modals/manifests.js'; -import { manifests as sectionViewManifests } from './section-view/manifests.js'; import { manifests as entityActionManifests } from './entity-actions/manifests.js'; import { manifests as entityBulkActionManifests } from './entity-bulk-actions/manifests.js'; -import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; +import { manifests as menuItemManifests } from './menu-item/manifests.js'; +import { manifests as modalManifests } from './modals/manifests.js'; +import { manifests as repositoryManifests } from './repository/manifests.js'; +import { manifests as sectionViewManifests } from './workspace/user-group-root/manifests.js'; +import { manifests as workspaceManifests } from './workspace/manifests.js'; -export const manifests: Array = [ +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ ...collectionManifests, - ...repositoryManifests, - ...workspaceManifests, - ...modalManifests, - ...sectionViewManifests, ...entityActionManifests, ...entityBulkActionManifests, + ...menuItemManifests, + ...modalManifests, + ...repositoryManifests, + ...sectionViewManifests, + ...workspaceManifests, ]; diff --git a/src/packages/user/user-group/menu-item/manifests.ts b/src/packages/user/user-group/menu-item/manifests.ts new file mode 100644 index 0000000000..1c770acdae --- /dev/null +++ b/src/packages/user/user-group/menu-item/manifests.ts @@ -0,0 +1,18 @@ +import { UMB_USER_MANAGEMENT_MENU_ALIAS } from '../../section/menu/constants.js'; +import { UMB_USER_GROUP_ROOT_ENTITY_TYPE } from '../entity.js'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'menuItem', + alias: 'Umb.MenuItem.UserGroups', + name: 'User Groups Menu Item', + weight: 100, + meta: { + label: '#user_usergroups', + icon: 'icon-users', + entityType: UMB_USER_GROUP_ROOT_ENTITY_TYPE, + menus: [UMB_USER_MANAGEMENT_MENU_ALIAS], + }, + }, +]; diff --git a/src/packages/user/user-group/paths.ts b/src/packages/user/user-group/paths.ts index 6fc1f8cc7e..51aa649211 100644 --- a/src/packages/user/user-group/paths.ts +++ b/src/packages/user/user-group/paths.ts @@ -1,8 +1,13 @@ -import { UMB_USER_SECTION_PATHNAME } from '../user-section/paths.js'; -import { UMB_USER_GROUP_ENTITY_TYPE } from './entity.js'; +import { UMB_USER_SECTION_PATHNAME } from '../section/paths.js'; +import { UMB_USER_GROUP_ENTITY_TYPE, UMB_USER_GROUP_ROOT_ENTITY_TYPE } from './entity.js'; import { UMB_WORKSPACE_PATH_PATTERN } from '@umbraco-cms/backoffice/workspace'; export const UMB_USER_GROUP_WORKSPACE_PATH = UMB_WORKSPACE_PATH_PATTERN.generateAbsolute({ sectionName: UMB_USER_SECTION_PATHNAME, entityType: UMB_USER_GROUP_ENTITY_TYPE, }); + +export const UMB_USER_GROUP_ROOT_WORKSPACE_PATH = UMB_WORKSPACE_PATH_PATTERN.generateAbsolute({ + sectionName: UMB_USER_SECTION_PATHNAME, + entityType: UMB_USER_GROUP_ROOT_ENTITY_TYPE, +}); diff --git a/src/packages/user/user-group/section-view/manifests.ts b/src/packages/user/user-group/section-view/manifests.ts deleted file mode 100644 index 3780224244..0000000000 --- a/src/packages/user/user-group/section-view/manifests.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { UMB_USER_MANAGEMENT_SECTION_ALIAS } from '../../user-section/index.js'; -import type { ManifestSectionView, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; - -const sectionsViews: Array = [ - { - type: 'sectionView', - alias: 'Umb.SectionView.UserGroup', - name: 'User Group Section View', - js: () => import('./user-group-section-view.element.js'), - weight: 100, - meta: { - label: '#user_usergroups', - pathname: 'user-groups', - icon: 'icon-users', - }, - conditions: [ - { - alias: 'Umb.Condition.SectionAlias', - match: UMB_USER_MANAGEMENT_SECTION_ALIAS, - }, - ], - }, -]; - -export const manifests: Array = [...sectionsViews]; diff --git a/src/packages/user/user-group/section-view/user-group-section-view.element.ts b/src/packages/user/user-group/section-view/user-group-section-view.element.ts deleted file mode 100644 index 4611f0962d..0000000000 --- a/src/packages/user/user-group/section-view/user-group-section-view.element.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { UMB_USER_GROUP_COLLECTION_ALIAS } from '../collection/index.js'; -import { UMB_USER_GROUP_ENTITY_TYPE } from '../entity.js'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { css, html, customElement } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import type { UmbRoute } from '@umbraco-cms/backoffice/router'; -import { UmbCollectionElement } from '@umbraco-cms/backoffice/collection'; -import { UmbWorkspaceElement } from '@umbraco-cms/backoffice/workspace'; - -@customElement('umb-user-group-section-view') -export class UmbUserGroupSectionViewElement extends UmbLitElement { - #routes: UmbRoute[] = [ - { - path: 'collection', - component: () => { - const element = new UmbCollectionElement(); - element.setAttribute('alias', UMB_USER_GROUP_COLLECTION_ALIAS); - return element; - }, - }, - { - path: 'user-group', - component: () => { - const element = new UmbWorkspaceElement(); - element.setAttribute('entity-type', UMB_USER_GROUP_ENTITY_TYPE); - return element; - }, - }, - { - path: '', - redirectTo: 'collection', - }, - { - path: `**`, - component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement, - }, - ]; - - override render() { - return html``; - } - - static override styles = [ - UmbTextStyles, - css` - :host { - height: 100%; - } - - #router-slot { - height: calc(100% - var(--umb-header-layout-height)); - } - `, - ]; -} - -export default UmbUserGroupSectionViewElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-user-group-section-view': UmbUserGroupSectionViewElement; - } -} diff --git a/src/packages/user/user-group/workspace/actions/workspace-action-user-group-save.element.ts b/src/packages/user/user-group/workspace/actions/workspace-action-user-group-save.element.ts deleted file mode 100644 index 1c86ca5b08..0000000000 --- a/src/packages/user/user-group/workspace/actions/workspace-action-user-group-save.element.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { UMB_USER_WORKSPACE_CONTEXT } from '../../../user/workspace/user-workspace.context-token.js'; -import { html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; -import type { UUIButtonState } from '@umbraco-cms/backoffice/external/uui'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -// TODO: Revisit this component, it can be made via a kind with api instead. [NL] -// TODO: This seems like legacy code [NL] -@customElement('umb-workspace-action-user-group-save') -export class UmbWorkspaceActionUserGroupSaveElement extends UmbLitElement { - @state() - private _saveButtonState?: UUIButtonState; - - private _workspaceContext?: typeof UMB_USER_WORKSPACE_CONTEXT.TYPE; - - constructor() { - super(); - - this.consumeContext(UMB_USER_WORKSPACE_CONTEXT, (instance) => { - this._workspaceContext = instance; - }); - } - - private async _handleSave() { - if (!this._workspaceContext) return; - - this._saveButtonState = 'waiting'; - await this._workspaceContext - .requestSubmit() - .then(() => { - this._saveButtonState = 'success'; - }) - .catch(() => { - this._saveButtonState = 'failed'; - }); - } - - override render() { - return html``; - } -} - -export default UmbWorkspaceActionUserGroupSaveElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-workspace-action-user-group-save': UmbWorkspaceActionUserGroupSaveElement; - } -} diff --git a/src/packages/user/user-group/workspace/manifests.ts b/src/packages/user/user-group/workspace/manifests.ts index 4a593776bc..806ce0f556 100644 --- a/src/packages/user/user-group/workspace/manifests.ts +++ b/src/packages/user/user-group/workspace/manifests.ts @@ -1,42 +1,4 @@ -import type { - ManifestWorkspaces, - ManifestWorkspaceActions, - ManifestWorkspaceView, - ManifestTypes, -} from '@umbraco-cms/backoffice/extension-registry'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { manifests as userGroupManifests } from './user-group/manifests.js'; +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -const workspace: ManifestWorkspaces = { - type: 'workspace', - kind: 'routable', - alias: 'Umb.Workspace.UserGroup', - name: 'User Group Workspace', - api: () => import('./user-group-workspace.context.js'), - meta: { - entityType: 'user-group', - }, -}; - -const workspaceViews: Array = []; -const workspaceActions: Array = [ - { - type: 'workspaceAction', - kind: 'default', - alias: 'Umb.WorkspaceAction.UserGroup.Save', - name: 'Save User Group Workspace Action', - api: UmbSubmitWorkspaceAction, - meta: { - label: '#buttons_save', - look: 'primary', - color: 'positive', - }, - conditions: [ - { - alias: 'Umb.Condition.WorkspaceAlias', - match: workspace.alias, - }, - ], - }, -]; - -export const manifests: Array = [workspace, ...workspaceViews, ...workspaceActions]; +export const manifests: Array = [...userGroupManifests]; diff --git a/src/packages/user/user-group/workspace/user-group-root/manifests.ts b/src/packages/user/user-group/workspace/user-group-root/manifests.ts new file mode 100644 index 0000000000..ac7b088e93 --- /dev/null +++ b/src/packages/user/user-group/workspace/user-group-root/manifests.ts @@ -0,0 +1,14 @@ +import { UMB_USER_GROUP_ROOT_ENTITY_TYPE } from '../../entity.js'; +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'workspace', + alias: 'Umb.Workspace.UserGroupRoot', + name: 'User Group Root Workspace View', + element: () => import('./user-group-root-workspace.element.js'), + meta: { + entityType: UMB_USER_GROUP_ROOT_ENTITY_TYPE, + }, + }, +]; diff --git a/src/packages/user/user-group/workspace/user-group-root/user-group-root-workspace.element.ts b/src/packages/user/user-group/workspace/user-group-root/user-group-root-workspace.element.ts new file mode 100644 index 0000000000..0900cee472 --- /dev/null +++ b/src/packages/user/user-group/workspace/user-group-root/user-group-root-workspace.element.ts @@ -0,0 +1,21 @@ +import { UMB_USER_GROUP_COLLECTION_ALIAS } from '../../collection/index.js'; +import { html, customElement } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; + +const elementName = 'umb-user-group-root-workspace'; +@customElement(elementName) +export class UmbUserGroupRootWorkspaceElement extends UmbLitElement { + override render() { + return html` + ; + `; + } +} + +export { UmbUserGroupRootWorkspaceElement as element }; + +declare global { + interface HTMLElementTagNameMap { + [elementName]: UmbUserGroupRootWorkspaceElement; + } +} diff --git a/src/packages/user/user-group/workspace/components/user-group-entity-user-permission-list.element.ts b/src/packages/user/user-group/workspace/user-group/components/user-group-entity-user-permission-list.element.ts similarity index 100% rename from src/packages/user/user-group/workspace/components/user-group-entity-user-permission-list.element.ts rename to src/packages/user/user-group/workspace/user-group/components/user-group-entity-user-permission-list.element.ts diff --git a/src/packages/user/user-group/workspace/components/user-group-granular-permission-list.element.ts b/src/packages/user/user-group/workspace/user-group/components/user-group-granular-permission-list.element.ts similarity index 100% rename from src/packages/user/user-group/workspace/components/user-group-granular-permission-list.element.ts rename to src/packages/user/user-group/workspace/user-group/components/user-group-granular-permission-list.element.ts diff --git a/src/packages/user/user-group/workspace/user-group/constants.ts b/src/packages/user/user-group/workspace/user-group/constants.ts new file mode 100644 index 0000000000..6972100cb8 --- /dev/null +++ b/src/packages/user/user-group/workspace/user-group/constants.ts @@ -0,0 +1 @@ +export const UMB_USER_GROUP_WORKSPACE_ALIAS = 'Umb.Workspace.UserGroup'; diff --git a/src/packages/user/user-group/workspace/user-group/manifests.ts b/src/packages/user/user-group/workspace/user-group/manifests.ts new file mode 100644 index 0000000000..4a593776bc --- /dev/null +++ b/src/packages/user/user-group/workspace/user-group/manifests.ts @@ -0,0 +1,42 @@ +import type { + ManifestWorkspaces, + ManifestWorkspaceActions, + ManifestWorkspaceView, + ManifestTypes, +} from '@umbraco-cms/backoffice/extension-registry'; +import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; + +const workspace: ManifestWorkspaces = { + type: 'workspace', + kind: 'routable', + alias: 'Umb.Workspace.UserGroup', + name: 'User Group Workspace', + api: () => import('./user-group-workspace.context.js'), + meta: { + entityType: 'user-group', + }, +}; + +const workspaceViews: Array = []; +const workspaceActions: Array = [ + { + type: 'workspaceAction', + kind: 'default', + alias: 'Umb.WorkspaceAction.UserGroup.Save', + name: 'Save User Group Workspace Action', + api: UmbSubmitWorkspaceAction, + meta: { + label: '#buttons_save', + look: 'primary', + color: 'positive', + }, + conditions: [ + { + alias: 'Umb.Condition.WorkspaceAlias', + match: workspace.alias, + }, + ], + }, +]; + +export const manifests: Array = [workspace, ...workspaceViews, ...workspaceActions]; diff --git a/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts b/src/packages/user/user-group/workspace/user-group/user-group-workspace-editor.element.ts similarity index 97% rename from src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts rename to src/packages/user/user-group/workspace/user-group/user-group-workspace-editor.element.ts index 9374872d2a..01835e7c2a 100644 --- a/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts +++ b/src/packages/user/user-group/workspace/user-group/user-group-workspace-editor.element.ts @@ -1,5 +1,7 @@ -import type { UmbUserGroupDetailModel } from '../index.js'; +import type { UmbUserGroupDetailModel } from '../../index.js'; +import { UMB_USER_GROUP_ROOT_WORKSPACE_PATH } from '../../paths.js'; import { UMB_USER_GROUP_WORKSPACE_CONTEXT } from './user-group-workspace.context-token.js'; +import { UMB_USER_GROUP_WORKSPACE_ALIAS } from './constants.js'; import type { UUIBooleanInputEvent } from '@umbraco-cms/backoffice/external/uui'; import { css, html, nothing, customElement, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element'; @@ -170,9 +172,9 @@ export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement { return html` + back-path=${UMB_USER_GROUP_ROOT_WORKSPACE_PATH}> ${this.#renderHeader()} ${this.#renderMain()} `; diff --git a/src/packages/user/user-group/workspace/user-group-workspace.context-token.ts b/src/packages/user/user-group/workspace/user-group/user-group-workspace.context-token.ts similarity index 89% rename from src/packages/user/user-group/workspace/user-group-workspace.context-token.ts rename to src/packages/user/user-group/workspace/user-group/user-group-workspace.context-token.ts index a09ae6a716..3a11176569 100644 --- a/src/packages/user/user-group/workspace/user-group-workspace.context-token.ts +++ b/src/packages/user/user-group/workspace/user-group/user-group-workspace.context-token.ts @@ -1,4 +1,4 @@ -import { UMB_USER_GROUP_ENTITY_TYPE } from '../index.js'; +import { UMB_USER_GROUP_ENTITY_TYPE } from '../../index.js'; import type { UmbUserGroupWorkspaceContext } from './user-group-workspace.context.js'; import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; import type { UmbSubmittableWorkspaceContext } from '@umbraco-cms/backoffice/workspace'; diff --git a/src/packages/user/user-group/workspace/user-group-workspace.context.ts b/src/packages/user/user-group/workspace/user-group/user-group-workspace.context.ts similarity index 97% rename from src/packages/user/user-group/workspace/user-group-workspace.context.ts rename to src/packages/user/user-group/workspace/user-group/user-group-workspace.context.ts index c360e2057f..6f81961747 100644 --- a/src/packages/user/user-group/workspace/user-group-workspace.context.ts +++ b/src/packages/user/user-group/workspace/user-group/user-group-workspace.context.ts @@ -1,5 +1,5 @@ -import { UmbUserGroupDetailRepository } from '../repository/detail/index.js'; -import type { UmbUserGroupDetailModel } from '../types.js'; +import { UmbUserGroupDetailRepository } from '../../repository/detail/index.js'; +import type { UmbUserGroupDetailModel } from '../../types.js'; import { UmbUserGroupWorkspaceEditorElement } from './user-group-workspace-editor.element.js'; import type { UmbUserPermissionModel } from '@umbraco-cms/backoffice/user-permission'; import type { UmbRoutableWorkspaceContext, UmbSubmittableWorkspaceContext } from '@umbraco-cms/backoffice/workspace'; diff --git a/src/packages/user/user-section/manifests.ts b/src/packages/user/user-section/manifests.ts deleted file mode 100644 index 74bb597e28..0000000000 --- a/src/packages/user/user-section/manifests.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { UMB_USER_MANAGEMENT_SECTION_ALIAS } from './constants.js'; -import type { ManifestSection, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; - -const section: ManifestSection = { - type: 'section', - alias: UMB_USER_MANAGEMENT_SECTION_ALIAS, - name: 'User Management Section', - weight: 600, - meta: { - label: '#sections_users', - pathname: 'user-management', - }, - conditions: [ - { - alias: 'Umb.Condition.SectionUserPermission', - match: UMB_USER_MANAGEMENT_SECTION_ALIAS, - }, - ], -}; - -export const manifests: Array = [section]; diff --git a/src/packages/user/user/conditions/user-allow-action-base.condition.ts b/src/packages/user/user/conditions/user-allow-action-base.condition.ts index bdae21f4af..7dffc20550 100644 --- a/src/packages/user/user/conditions/user-allow-action-base.condition.ts +++ b/src/packages/user/user/conditions/user-allow-action-base.condition.ts @@ -1,5 +1,5 @@ import type { UmbUserStateEnum } from '../types.js'; -import { UMB_USER_WORKSPACE_CONTEXT } from '../workspace/user-workspace.context-token.js'; +import { UMB_USER_WORKSPACE_CONTEXT } from '../workspace/user/user-workspace.context-token.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { isCurrentUser } from '@umbraco-cms/backoffice/current-user'; import type { diff --git a/src/packages/user/user/entity-actions/create/create-user-entity-action.ts b/src/packages/user/user/entity-actions/create/create-user-entity-action.ts new file mode 100644 index 0000000000..a6da26da4f --- /dev/null +++ b/src/packages/user/user/entity-actions/create/create-user-entity-action.ts @@ -0,0 +1,21 @@ +import { UMB_USER_CREATE_OPTIONS_MODAL } from './modal/index.js'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; + +export class UmbCreateUserEntityAction extends UmbEntityActionBase { + override async execute() { + const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); + const modalContext = modalManager.open(this, UMB_USER_CREATE_OPTIONS_MODAL, { + data: { + parent: { + unique: this.args.unique, + entityType: this.args.entityType, + }, + }, + }); + + await modalContext.onSubmit(); + } +} + +export { UmbCreateUserEntityAction as api }; diff --git a/src/packages/user/user/entity-actions/create/manifests.ts b/src/packages/user/user/entity-actions/create/manifests.ts new file mode 100644 index 0000000000..7915152337 --- /dev/null +++ b/src/packages/user/user/entity-actions/create/manifests.ts @@ -0,0 +1,22 @@ +import { UMB_USER_ROOT_ENTITY_TYPE } from '../../entity.js'; + +import { manifests as modalManifests } from './modal/manifests.js'; + +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'entityAction', + kind: 'default', + alias: 'Umb.EntityAction.User.Create', + name: 'Create User Entity Action', + weight: 1200, + api: () => import('./create-user-entity-action.js'), + forEntityTypes: [UMB_USER_ROOT_ENTITY_TYPE], + meta: { + icon: 'icon-add', + label: '#actions_create', + }, + }, + ...modalManifests, +]; diff --git a/src/packages/user/user/entity-actions/create/modal/index.ts b/src/packages/user/user/entity-actions/create/modal/index.ts new file mode 100644 index 0000000000..778a1fe38d --- /dev/null +++ b/src/packages/user/user/entity-actions/create/modal/index.ts @@ -0,0 +1,8 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export const UMB_USER_CREATE_OPTIONS_MODAL = new UmbModalToken('Umb.Modal.User.CreateOptions', { + modal: { + type: 'sidebar', + size: 'small', + }, +}); diff --git a/src/packages/user/user/entity-actions/create/modal/manifests.ts b/src/packages/user/user/entity-actions/create/modal/manifests.ts new file mode 100644 index 0000000000..2c736c75fd --- /dev/null +++ b/src/packages/user/user/entity-actions/create/modal/manifests.ts @@ -0,0 +1,10 @@ +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'modal', + alias: 'Umb.Modal.User.CreateOptions', + name: 'User Create Options Modal', + element: () => import('./user-create-options-modal.element.js'), + }, +]; diff --git a/src/packages/user/user/entity-actions/create/modal/user-create-options-modal.element.ts b/src/packages/user/user/entity-actions/create/modal/user-create-options-modal.element.ts new file mode 100644 index 0000000000..74e8646990 --- /dev/null +++ b/src/packages/user/user/entity-actions/create/modal/user-create-options-modal.element.ts @@ -0,0 +1,106 @@ +import { UMB_CREATE_USER_MODAL } from '../../../modals/create/create-user-modal.token.js'; +import { UmbUserKind, type UmbUserKindType } from '../../../utils/index.js'; +import { html, customElement, map } from '@umbraco-cms/backoffice/external/lit'; +import { UMB_MODAL_MANAGER_CONTEXT, UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import { UMB_ENTITY_CONTEXT } from '@umbraco-cms/backoffice/entity'; +import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { UmbRequestReloadChildrenOfEntityEvent } from '@umbraco-cms/backoffice/entity-action'; + +interface UmbUserCreateOptionModel { + label: string; + description?: string; + icon: string; + kind: UmbUserKindType; +} + +const elementName = 'umb-user-create-options-modal'; +@customElement(elementName) +export class UmbUserCreateOptionsModalElement extends UmbModalBaseElement { + #options: Array = [ + { + label: this.localize.term('user_userKindDefault'), + icon: 'icon-user', + kind: UmbUserKind.DEFAULT, + }, + { + label: this.localize.term('user_userKindApi'), + icon: 'icon-unplug', + kind: UmbUserKind.API, + }, + ]; + + async #onClick(event: Event, kind: UmbUserKindType) { + event.stopPropagation(); + const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); + const entityContext = await this.getContext(UMB_ENTITY_CONTEXT); + + const unique = entityContext.getUnique(); + const entityType = entityContext.getEntityType(); + + if (unique === undefined) throw new Error('Missing unique'); + if (!entityType) throw new Error('Missing entityType'); + + const modalContext = modalManager.open(this, UMB_CREATE_USER_MODAL, { + data: { + user: { + kind, + }, + }, + }); + + modalContext + ?.onSubmit() + .then(() => { + this.#requestReloadChildrenOfEntity({ entityType, unique }); + }) + .catch(async () => { + // modal is closed after creation instead of navigating to the new user. + // We therefore need to reload the children of the entity + this.#requestReloadChildrenOfEntity({ entityType, unique }); + }); + } + + async #requestReloadChildrenOfEntity({ entityType, unique }: UmbEntityModel) { + const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); + const event = new UmbRequestReloadChildrenOfEntityEvent({ + entityType, + unique, + }); + + eventContext.dispatchEvent(event); + } + + override render() { + return html` + + + + ${map( + this.#options, + (item) => html` + this.#onClick(event, item.kind)}> + `, + )} + + + + + `; + } +} + +export { UmbUserCreateOptionsModalElement as element }; + +declare global { + interface HTMLElementTagNameMap { + [elementName]: UmbUserCreateOptionsModalElement; + } +} diff --git a/src/packages/user/user/entity-actions/manifests.ts b/src/packages/user/user/entity-actions/manifests.ts index b67955449e..f59da30aeb 100644 --- a/src/packages/user/user/entity-actions/manifests.ts +++ b/src/packages/user/user/entity-actions/manifests.ts @@ -1,6 +1,9 @@ import { UMB_USER_DETAIL_REPOSITORY_ALIAS, UMB_USER_ITEM_REPOSITORY_ALIAS } from '../repository/index.js'; import { UMB_USER_ENTITY_TYPE } from '../entity.js'; -import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +import { manifests as createManifests } from './create/manifests.js'; + +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; const entityActions: Array = [ { @@ -93,4 +96,4 @@ const entityActions: Array = [ }, ]; -export const manifests: Array = [...entityActions]; +export const manifests: Array = [...entityActions, ...createManifests]; diff --git a/src/packages/user/user/invite/entity-action/invite/invite-user-entity-action.ts b/src/packages/user/user/invite/entity-action/invite/invite-user-entity-action.ts new file mode 100644 index 0000000000..7d7f86ec79 --- /dev/null +++ b/src/packages/user/user/invite/entity-action/invite/invite-user-entity-action.ts @@ -0,0 +1,13 @@ +import { UMB_INVITE_USER_MODAL } from '../../index.js'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; + +export class UmbCreateUserEntityAction extends UmbEntityActionBase { + override async execute() { + const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); + const modalContext = modalManager.open(this, UMB_INVITE_USER_MODAL); + await modalContext?.onSubmit(); + } +} + +export { UmbCreateUserEntityAction as api }; diff --git a/src/packages/user/user/invite/entity-action/invite/manifests.ts b/src/packages/user/user/invite/entity-action/invite/manifests.ts new file mode 100644 index 0000000000..64ca8e8772 --- /dev/null +++ b/src/packages/user/user/invite/entity-action/invite/manifests.ts @@ -0,0 +1,19 @@ +import { UMB_USER_ROOT_ENTITY_TYPE } from '../../../entity.js'; + +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'entityAction', + kind: 'default', + alias: 'Umb.EntityAction.User.Invite', + name: 'Invite User Entity Action', + weight: 1000, + api: () => import('./invite-user-entity-action.js'), + forEntityTypes: [UMB_USER_ROOT_ENTITY_TYPE], + meta: { + icon: 'icon-paper-plane', + label: '#user_invite', + }, + }, +]; diff --git a/src/packages/user/user/invite/entity-action/manifests.ts b/src/packages/user/user/invite/entity-action/manifests.ts index af09b5ff79..0958868a9f 100644 --- a/src/packages/user/user/invite/entity-action/manifests.ts +++ b/src/packages/user/user/invite/entity-action/manifests.ts @@ -1,27 +1,9 @@ -import { UMB_USER_ENTITY_TYPE } from '../../entity.js'; +import { manifests as inviteManifests } from './invite/manifests.js'; import { manifests as resendInviteManifests } from './resend-invite/manifests.js'; -import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; -const entityActions: Array = [ - { - type: 'entityAction', - kind: 'default', - alias: 'Umb.EntityAction.User.ResendInvite', - name: 'Resend Invite User Entity Action', - weight: 500, - api: () => import('./resend-invite/resend-invite.action.js'), - forEntityTypes: [UMB_USER_ENTITY_TYPE], - meta: { - icon: 'icon-message', - label: '#actions_resendInvite', - }, - conditions: [ - { - alias: 'Umb.Condition.User.AllowResendInviteAction', - }, - ], - }, +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + ...inviteManifests, ...resendInviteManifests, ]; - -export const manifests: Array = [...entityActions]; diff --git a/src/packages/user/user/invite/entity-action/resend-invite/manifests.ts b/src/packages/user/user/invite/entity-action/resend-invite/manifests.ts index 87dac3af79..1525273137 100644 --- a/src/packages/user/user/invite/entity-action/resend-invite/manifests.ts +++ b/src/packages/user/user/invite/entity-action/resend-invite/manifests.ts @@ -1,6 +1,25 @@ +import { UMB_USER_ENTITY_TYPE } from '../../../entity.js'; import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; export const manifests: Array = [ + { + type: 'entityAction', + kind: 'default', + alias: 'Umb.EntityAction.User.ResendInvite', + name: 'Resend Invite User Entity Action', + weight: 500, + api: () => import('./resend-invite.action.js'), + forEntityTypes: [UMB_USER_ENTITY_TYPE], + meta: { + icon: 'icon-message', + label: '#actions_resendInvite', + }, + conditions: [ + { + alias: 'Umb.Condition.User.AllowResendInviteAction', + }, + ], + }, { type: 'condition', name: 'User Allow Resend Invite Action Condition', diff --git a/src/packages/user/user/invite/manifests.ts b/src/packages/user/user/invite/manifests.ts index 63b76f1ec9..3d56168a11 100644 --- a/src/packages/user/user/invite/manifests.ts +++ b/src/packages/user/user/invite/manifests.ts @@ -2,9 +2,9 @@ import { manifests as collectionActionManifests } from './collection-action/mani import { manifests as modalManifests } from './modal/manifests.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { manifests as entityActionManifests } from './entity-action/manifests.js'; -import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -export const manifests: Array = [ +export const manifests: Array = [ ...collectionActionManifests, ...modalManifests, ...repositoryManifests, diff --git a/src/packages/user/user/manifests.ts b/src/packages/user/user/manifests.ts index 3eae6c756b..b73a4378c2 100644 --- a/src/packages/user/user/manifests.ts +++ b/src/packages/user/user/manifests.ts @@ -7,8 +7,9 @@ import { manifests as inviteManifests } from './invite/manifests.js'; import { manifests as modalManifests } from './modals/manifests.js'; import { manifests as propertyEditorManifests } from './property-editor/manifests.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; -import { manifests as sectionViewManifests } from './section-view/manifests.js'; import { manifests as workspaceManifests } from './workspace/manifests.js'; +import { manifests as menuItemManifests } from './menu-item/manifests.js'; + import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; export const manifests: Array = [ @@ -21,6 +22,6 @@ export const manifests: Array = [ ...modalManifests, ...propertyEditorManifests, ...repositoryManifests, - ...sectionViewManifests, ...workspaceManifests, + ...menuItemManifests, ]; diff --git a/src/packages/user/user/menu-item/manifests.ts b/src/packages/user/user/menu-item/manifests.ts new file mode 100644 index 0000000000..c1980c58ef --- /dev/null +++ b/src/packages/user/user/menu-item/manifests.ts @@ -0,0 +1,18 @@ +import { UMB_USER_MANAGEMENT_MENU_ALIAS } from '../../section/menu/constants.js'; +import { UMB_USER_ROOT_ENTITY_TYPE } from '../entity.js'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'menuItem', + alias: 'Umb.MenuItem.Users', + name: 'Users Menu Item', + weight: 200, + meta: { + label: '#treeHeaders_users', + icon: 'icon-user', + entityType: UMB_USER_ROOT_ENTITY_TYPE, + menus: [UMB_USER_MANAGEMENT_MENU_ALIAS], + }, + }, +]; diff --git a/src/packages/user/user/paths.ts b/src/packages/user/user/paths.ts index e9040e7270..210af851fd 100644 --- a/src/packages/user/user/paths.ts +++ b/src/packages/user/user/paths.ts @@ -1,8 +1,13 @@ -import { UMB_USER_SECTION_PATHNAME } from '../user-section/paths.js'; -import { UMB_USER_ENTITY_TYPE } from './entity.js'; +import { UMB_USER_SECTION_PATHNAME } from '../section/paths.js'; +import { UMB_USER_ENTITY_TYPE, UMB_USER_ROOT_ENTITY_TYPE } from './entity.js'; import { UMB_WORKSPACE_PATH_PATTERN } from '@umbraco-cms/backoffice/workspace'; export const UMB_USER_WORKSPACE_PATH = UMB_WORKSPACE_PATH_PATTERN.generateAbsolute({ sectionName: UMB_USER_SECTION_PATHNAME, entityType: UMB_USER_ENTITY_TYPE, }); + +export const UMB_USER_ROOT_WORKSPACE_PATH = UMB_WORKSPACE_PATH_PATTERN.generateAbsolute({ + sectionName: UMB_USER_SECTION_PATHNAME, + entityType: UMB_USER_ROOT_ENTITY_TYPE, +}); diff --git a/src/packages/user/user/section-view/manifests.ts b/src/packages/user/user/section-view/manifests.ts deleted file mode 100644 index a9dbcd430b..0000000000 --- a/src/packages/user/user/section-view/manifests.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { UMB_USER_MANAGEMENT_SECTION_ALIAS } from '../../user-section/index.js'; -import type { ManifestSectionView, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; - -const sectionsViews: Array = [ - { - type: 'sectionView', - alias: 'Umb.SectionView.Users', - name: 'Users Section View', - js: () => import('./users-section-view.element.js'), - weight: 200, - meta: { - label: '#general_users', - pathname: 'users', - icon: 'icon-user', - }, - conditions: [ - { - alias: 'Umb.Condition.SectionAlias', - match: UMB_USER_MANAGEMENT_SECTION_ALIAS, - }, - ], - }, -]; - -export const manifests: Array = [...sectionsViews]; diff --git a/src/packages/user/user/section-view/users-section-view.element.ts b/src/packages/user/user/section-view/users-section-view.element.ts deleted file mode 100644 index 22f9d5069d..0000000000 --- a/src/packages/user/user/section-view/users-section-view.element.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { UMB_USER_COLLECTION_ALIAS } from '../collection/index.js'; -import { UMB_USER_ENTITY_TYPE, UMB_USER_ROOT_ENTITY_TYPE } from '../entity.js'; -import { css, html, customElement } from '@umbraco-cms/backoffice/external/lit'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import type { UmbRoute } from '@umbraco-cms/backoffice/router'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { UmbCollectionElement } from '@umbraco-cms/backoffice/collection'; -import { UmbWorkspaceElement } from '@umbraco-cms/backoffice/workspace'; -import { UmbEntityContext } from '@umbraco-cms/backoffice/entity'; - -@customElement('umb-section-view-users') -export class UmbSectionViewUsersElement extends UmbLitElement { - #routes: UmbRoute[] = [ - { - path: 'collection', - component: () => { - const element = new UmbCollectionElement(); - const entityContext = new UmbEntityContext(element); - entityContext.setEntityType(UMB_USER_ROOT_ENTITY_TYPE); - entityContext.setUnique(null); - element.setAttribute('alias', UMB_USER_COLLECTION_ALIAS); - return element; - }, - }, - { - path: 'user', - component: () => { - const element = new UmbWorkspaceElement(); - element.setAttribute('entity-type', UMB_USER_ENTITY_TYPE); - return element; - }, - }, - { - path: '', - redirectTo: 'collection', - }, - { - path: `**`, - component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement, - }, - ]; - - override render() { - return html` `; - } - - static override styles = [ - UmbTextStyles, - css` - :host { - height: 100%; - } - - #router-slot { - height: calc(100% - var(--umb-header-layout-height)); - } - `, - ]; -} - -export default UmbSectionViewUsersElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-section-view-users': UmbSectionViewUsersElement; - } -} diff --git a/src/packages/user/user/workspace/manifests.ts b/src/packages/user/user/workspace/manifests.ts index d2c5c90ec4..2208cee94d 100644 --- a/src/packages/user/user/workspace/manifests.ts +++ b/src/packages/user/user/workspace/manifests.ts @@ -1,42 +1,5 @@ -import { UMB_USER_ENTITY_TYPE } from '../entity.js'; -import { UMB_USER_WORKSPACE_ALIAS } from './constants.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; -import type { - ManifestWorkspaces, - ManifestWorkspaceActions, - ManifestTypes, -} from '@umbraco-cms/backoffice/extension-registry'; +import { manifests as userManifests } from './user/manifests.js'; +import { manifests as userRootManifests } from './user-root/manifests.js'; +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -const workspace: ManifestWorkspaces = { - type: 'workspace', - kind: 'routable', - alias: UMB_USER_WORKSPACE_ALIAS, - name: 'User Workspace', - api: () => import('./user-workspace.context.js'), - meta: { - entityType: UMB_USER_ENTITY_TYPE, - }, -}; - -const workspaceActions: Array = [ - { - type: 'workspaceAction', - kind: 'default', - alias: 'Umb.WorkspaceAction.User.Save', - name: 'Save User Workspace Action', - api: UmbSubmitWorkspaceAction, - meta: { - label: '#buttons_save', - look: 'primary', - color: 'positive', - }, - conditions: [ - { - alias: 'Umb.Condition.WorkspaceAlias', - match: workspace.alias, - }, - ], - }, -]; - -export const manifests: Array = [workspace, ...workspaceActions]; +export const manifests: Array = [...userManifests, ...userRootManifests]; diff --git a/src/packages/user/user/workspace/user-root/manifests.ts b/src/packages/user/user/workspace/user-root/manifests.ts new file mode 100644 index 0000000000..9cb07892d3 --- /dev/null +++ b/src/packages/user/user/workspace/user-root/manifests.ts @@ -0,0 +1,14 @@ +import { UMB_USER_ROOT_ENTITY_TYPE } from '../../entity.js'; +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'workspace', + alias: 'Umb.Workspace.UserRoot', + name: 'User Root Workspace View', + element: () => import('./user-root-workspace.element.js'), + meta: { + entityType: UMB_USER_ROOT_ENTITY_TYPE, + }, + }, +]; diff --git a/src/packages/user/user/workspace/user-root/user-root-workspace.element.ts b/src/packages/user/user/workspace/user-root/user-root-workspace.element.ts new file mode 100644 index 0000000000..335f7b9590 --- /dev/null +++ b/src/packages/user/user/workspace/user-root/user-root-workspace.element.ts @@ -0,0 +1,31 @@ +import { UMB_USER_COLLECTION_ALIAS } from '../../collection/index.js'; +import { UMB_USER_ROOT_ENTITY_TYPE } from '../../entity.js'; +import { UmbEntityContext } from '@umbraco-cms/backoffice/entity'; +import { html, customElement } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; + +const elementName = 'umb-user-root-workspace'; +@customElement(elementName) +export class UmbUserRootWorkspaceElement extends UmbLitElement { + constructor() { + super(); + // TODO: this.should happen automatically + const entityContext = new UmbEntityContext(this); + entityContext.setEntityType(UMB_USER_ROOT_ENTITY_TYPE); + entityContext.setUnique(null); + } + + override render() { + return html` + ; + `; + } +} + +export { UmbUserRootWorkspaceElement as element }; + +declare global { + interface HTMLElementTagNameMap { + [elementName]: UmbUserRootWorkspaceElement; + } +} diff --git a/src/packages/user/user/workspace/actions/user-workspace-action-save.element.ts b/src/packages/user/user/workspace/user/actions/user-workspace-action-save.element.ts similarity index 100% rename from src/packages/user/user/workspace/actions/user-workspace-action-save.element.ts rename to src/packages/user/user/workspace/user/actions/user-workspace-action-save.element.ts diff --git a/src/packages/user/user/workspace/components/user-workspace-access/user-workspace-access.element.ts b/src/packages/user/user/workspace/user/components/user-workspace-access/user-workspace-access.element.ts similarity index 97% rename from src/packages/user/user/workspace/components/user-workspace-access/user-workspace-access.element.ts rename to src/packages/user/user/workspace/user/components/user-workspace-access/user-workspace-access.element.ts index 7177e91909..86197319e5 100644 --- a/src/packages/user/user/workspace/components/user-workspace-access/user-workspace-access.element.ts +++ b/src/packages/user/user/workspace/user/components/user-workspace-access/user-workspace-access.element.ts @@ -1,5 +1,5 @@ import { UMB_USER_WORKSPACE_CONTEXT } from '../../user-workspace.context-token.js'; -import type { UmbUserStartNodesModel } from '../../../types.js'; +import type { UmbUserStartNodesModel } from '../../../../types.js'; import { html, customElement, state, css } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; diff --git a/src/packages/user/user/workspace/components/user-workspace-assign-access/user-workspace-assign-access.element.ts b/src/packages/user/user/workspace/user/components/user-workspace-assign-access/user-workspace-assign-access.element.ts similarity index 99% rename from src/packages/user/user/workspace/components/user-workspace-assign-access/user-workspace-assign-access.element.ts rename to src/packages/user/user/workspace/user/components/user-workspace-assign-access/user-workspace-assign-access.element.ts index 6a7a881039..d32bb6e0fd 100644 --- a/src/packages/user/user/workspace/components/user-workspace-assign-access/user-workspace-assign-access.element.ts +++ b/src/packages/user/user/workspace/user/components/user-workspace-assign-access/user-workspace-assign-access.element.ts @@ -1,5 +1,5 @@ import { UMB_USER_WORKSPACE_CONTEXT } from '../../user-workspace.context-token.js'; -import type { UmbUserDetailModel } from '../../../types.js'; +import type { UmbUserDetailModel } from '../../../../types.js'; import { html, customElement, state, nothing, css } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; diff --git a/src/packages/user/user/workspace/components/user-workspace-avatar/user-workspace-avatar.element.ts b/src/packages/user/user/workspace/user/components/user-workspace-avatar/user-workspace-avatar.element.ts similarity index 97% rename from src/packages/user/user/workspace/components/user-workspace-avatar/user-workspace-avatar.element.ts rename to src/packages/user/user/workspace/user/components/user-workspace-avatar/user-workspace-avatar.element.ts index b3c7317d12..9400230d7a 100644 --- a/src/packages/user/user/workspace/components/user-workspace-avatar/user-workspace-avatar.element.ts +++ b/src/packages/user/user/workspace/user/components/user-workspace-avatar/user-workspace-avatar.element.ts @@ -1,4 +1,4 @@ -import type { UmbUserDetailModel } from '../../../types.js'; +import type { UmbUserDetailModel } from '../../../../types.js'; import { UMB_USER_WORKSPACE_CONTEXT } from '../../user-workspace.context-token.js'; import { css, html, customElement, query, nothing, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; diff --git a/src/packages/user/user/workspace/components/user-workspace-client-credentials/user-workspace-client-credentials.element.ts b/src/packages/user/user/workspace/user/components/user-workspace-client-credentials/user-workspace-client-credentials.element.ts similarity index 93% rename from src/packages/user/user/workspace/components/user-workspace-client-credentials/user-workspace-client-credentials.element.ts rename to src/packages/user/user/workspace/user/components/user-workspace-client-credentials/user-workspace-client-credentials.element.ts index 512d97f2d6..7d77417056 100644 --- a/src/packages/user/user/workspace/components/user-workspace-client-credentials/user-workspace-client-credentials.element.ts +++ b/src/packages/user/user/workspace/user/components/user-workspace-client-credentials/user-workspace-client-credentials.element.ts @@ -2,10 +2,10 @@ import { UMB_USER_WORKSPACE_CONTEXT } from '../../user-workspace.context-token.j import type { UmbDeleteUserClientCredentialRequestArgs, UmbUserClientCredentialModel, -} from '../../../client-credential/index.js'; -import { UmbUserClientCredentialRepository } from '../../../client-credential/index.js'; -import { UMB_CREATE_USER_CLIENT_CREDENTIAL_MODAL } from '../../../client-credential/create/modal/create-user-client-credential-modal.token.js'; -import { UmbUserKind } from '../../../utils/index.js'; +} from '../../../../client-credential/index.js'; +import { UmbUserClientCredentialRepository } from '../../../../client-credential/index.js'; +import { UMB_CREATE_USER_CLIENT_CREDENTIAL_MODAL } from '../../../../client-credential/create/modal/create-user-client-credential-modal.token.js'; +import { UmbUserKind } from '../../../../utils/index.js'; import { html, customElement, state, css, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; diff --git a/src/packages/user/user/workspace/components/user-workspace-info/user-workspace-info.element.ts b/src/packages/user/user/workspace/user/components/user-workspace-info/user-workspace-info.element.ts similarity index 95% rename from src/packages/user/user/workspace/components/user-workspace-info/user-workspace-info.element.ts rename to src/packages/user/user/workspace/user/components/user-workspace-info/user-workspace-info.element.ts index 898bea5823..8f5d2437b0 100644 --- a/src/packages/user/user/workspace/components/user-workspace-info/user-workspace-info.element.ts +++ b/src/packages/user/user/workspace/user/components/user-workspace-info/user-workspace-info.element.ts @@ -1,8 +1,8 @@ -import type { UmbUserDisplayStatus } from '../../../utils.js'; -import { TimeFormatOptions, getDisplayStateFromUserStatus } from '../../../utils.js'; +import type { UmbUserDisplayStatus } from '../../../../utils.js'; +import { TimeFormatOptions, getDisplayStateFromUserStatus } from '../../../../utils.js'; import { UMB_USER_WORKSPACE_CONTEXT } from '../../user-workspace.context-token.js'; -import type { UmbUserDetailModel } from '../../../types.js'; -import { UmbUserKind } from '../../../utils/index.js'; +import type { UmbUserDetailModel } from '../../../../types.js'; +import { UmbUserKind } from '../../../../utils/index.js'; import { html, customElement, state, css, repeat, ifDefined, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; diff --git a/src/packages/user/user/workspace/components/user-workspace-profile-settings/user-workspace-profile-settings.element.ts b/src/packages/user/user/workspace/user/components/user-workspace-profile-settings/user-workspace-profile-settings.element.ts similarity index 97% rename from src/packages/user/user/workspace/components/user-workspace-profile-settings/user-workspace-profile-settings.element.ts rename to src/packages/user/user/workspace/user/components/user-workspace-profile-settings/user-workspace-profile-settings.element.ts index fd4e67c615..0d313eb130 100644 --- a/src/packages/user/user/workspace/components/user-workspace-profile-settings/user-workspace-profile-settings.element.ts +++ b/src/packages/user/user/workspace/user/components/user-workspace-profile-settings/user-workspace-profile-settings.element.ts @@ -1,11 +1,11 @@ import { UMB_USER_WORKSPACE_CONTEXT } from '../../user-workspace.context-token.js'; -import type { UmbUserDetailModel } from '../../../types.js'; +import type { UmbUserDetailModel } from '../../../../types.js'; +import { UmbUserKind } from '../../../../utils/index.js'; import { html, customElement, state, ifDefined, css, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import type { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import type { UmbUiCultureInputElement } from '@umbraco-cms/backoffice/localization'; -import { UmbUserKind } from '../../../utils/index.js'; @customElement('umb-user-workspace-profile-settings') export class UmbUserWorkspaceProfileSettingsElement extends UmbLitElement { diff --git a/src/packages/user/user/workspace/constants.ts b/src/packages/user/user/workspace/user/constants.ts similarity index 100% rename from src/packages/user/user/workspace/constants.ts rename to src/packages/user/user/workspace/user/constants.ts diff --git a/src/packages/user/user/workspace/user/manifests.ts b/src/packages/user/user/workspace/user/manifests.ts new file mode 100644 index 0000000000..3f4203dd88 --- /dev/null +++ b/src/packages/user/user/workspace/user/manifests.ts @@ -0,0 +1,42 @@ +import { UMB_USER_ENTITY_TYPE } from '../../entity.js'; +import { UMB_USER_WORKSPACE_ALIAS } from './constants.js'; +import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import type { + ManifestWorkspaces, + ManifestWorkspaceActions, + ManifestTypes, +} from '@umbraco-cms/backoffice/extension-registry'; + +const workspace: ManifestWorkspaces = { + type: 'workspace', + kind: 'routable', + alias: UMB_USER_WORKSPACE_ALIAS, + name: 'User Workspace', + api: () => import('./user-workspace.context.js'), + meta: { + entityType: UMB_USER_ENTITY_TYPE, + }, +}; + +const workspaceActions: Array = [ + { + type: 'workspaceAction', + kind: 'default', + alias: 'Umb.WorkspaceAction.User.Save', + name: 'Save User Workspace Action', + api: UmbSubmitWorkspaceAction, + meta: { + label: '#buttons_save', + look: 'primary', + color: 'positive', + }, + conditions: [ + { + alias: 'Umb.Condition.WorkspaceAlias', + match: workspace.alias, + }, + ], + }, +]; + +export const manifests: Array = [workspace, ...workspaceActions]; diff --git a/src/packages/user/user/workspace/user-workspace-editor.element.ts b/src/packages/user/user/workspace/user/user-workspace-editor.element.ts similarity index 92% rename from src/packages/user/user/workspace/user-workspace-editor.element.ts rename to src/packages/user/user/workspace/user/user-workspace-editor.element.ts index c4e11d2175..b65ebebf63 100644 --- a/src/packages/user/user/workspace/user-workspace-editor.element.ts +++ b/src/packages/user/user/workspace/user/user-workspace-editor.element.ts @@ -1,6 +1,8 @@ -import type { UmbUserDetailModel } from '../index.js'; +import type { UmbUserDetailModel } from '../../index.js'; +import { UMB_USER_ROOT_WORKSPACE_PATH } from '../../paths.js'; import type { UmbUserWorkspaceContext } from './user-workspace.context.js'; import { UMB_USER_WORKSPACE_CONTEXT } from './user-workspace.context-token.js'; +import { UMB_USER_WORKSPACE_ALIAS } from './constants.js'; import type { UUIInputElement } from '@umbraco-cms/backoffice/external/uui'; import { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; import { css, html, nothing, customElement, state } from '@umbraco-cms/backoffice/external/lit'; @@ -50,7 +52,10 @@ export class UmbUserWorkspaceEditorElement extends UmbLitElement { if (!this._user) return html`User not found`; return html` - + ${this.#renderHeader()}
${this.#renderLeftColumn()}
diff --git a/src/packages/user/user/workspace/user-workspace.context-token.ts b/src/packages/user/user/workspace/user/user-workspace.context-token.ts similarity index 89% rename from src/packages/user/user/workspace/user-workspace.context-token.ts rename to src/packages/user/user/workspace/user/user-workspace.context-token.ts index ac99021cc5..bac31a226c 100644 --- a/src/packages/user/user/workspace/user-workspace.context-token.ts +++ b/src/packages/user/user/workspace/user/user-workspace.context-token.ts @@ -1,4 +1,4 @@ -import { UMB_USER_ENTITY_TYPE } from '../entity.js'; +import { UMB_USER_ENTITY_TYPE } from '../../entity.js'; import type { UmbUserWorkspaceContext } from './user-workspace.context.js'; import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; import type { UmbSubmittableWorkspaceContext } from '@umbraco-cms/backoffice/workspace'; diff --git a/src/packages/user/user/workspace/user-workspace.context.ts b/src/packages/user/user/workspace/user/user-workspace.context.ts similarity index 94% rename from src/packages/user/user/workspace/user-workspace.context.ts rename to src/packages/user/user/workspace/user/user-workspace.context.ts index 69587e191d..18963318ec 100644 --- a/src/packages/user/user/workspace/user-workspace.context.ts +++ b/src/packages/user/user/workspace/user/user-workspace.context.ts @@ -1,8 +1,8 @@ -import type { UmbUserDetailModel, UmbUserStartNodesModel, UmbUserStateEnum } from '../types.js'; -import { UMB_USER_ENTITY_TYPE } from '../entity.js'; -import { UmbUserDetailRepository } from '../repository/index.js'; -import { UmbUserAvatarRepository } from '../repository/avatar/index.js'; -import { UmbUserConfigRepository } from '../repository/config/index.js'; +import type { UmbUserDetailModel, UmbUserStartNodesModel, UmbUserStateEnum } from '../../types.js'; +import { UMB_USER_ENTITY_TYPE } from '../../entity.js'; +import { UmbUserDetailRepository } from '../../repository/index.js'; +import { UmbUserAvatarRepository } from '../../repository/avatar/index.js'; +import { UmbUserConfigRepository } from '../../repository/config/index.js'; import { UMB_USER_WORKSPACE_ALIAS } from './constants.js'; import { UmbUserWorkspaceEditorElement } from './user-workspace-editor.element.js'; import type { UmbSubmittableWorkspaceContext } from '@umbraco-cms/backoffice/workspace'; diff --git a/src/packages/user/user/workspace/user-workspace.test.ts b/src/packages/user/user/workspace/user/user-workspace.test.ts similarity index 100% rename from src/packages/user/user/workspace/user-workspace.test.ts rename to src/packages/user/user/workspace/user/user-workspace.test.ts