Skip to content
This repository was archived by the owner on Nov 6, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7566ce5
update constants
madsrasmussen Apr 6, 2024
f247d34
implement document user permission condition
madsrasmussen Apr 6, 2024
75ace44
Merge branch 'feature/entity-context' into feature/document-user-perm…
madsrasmussen Apr 8, 2024
2e0aa4a
Merge branch 'feature/entity-context' into feature/document-user-perm…
madsrasmussen Apr 8, 2024
5d87b47
Merge branch 'feature/entity-context' into feature/document-user-perm…
madsrasmussen Apr 9, 2024
ddd449f
Merge branch 'main' into feature/document-user-permission
madsrasmussen Apr 9, 2024
4af70f7
add conditions
madsrasmussen Apr 9, 2024
518504f
Update manifests.ts
madsrasmussen Apr 9, 2024
c92e270
implement allOf to allow multiple verbs for one permission condition
madsrasmussen Apr 9, 2024
72a611b
add user permissions to workspace actions
madsrasmussen Apr 9, 2024
1df8e9b
add public methods to enable and disable the action
madsrasmussen Apr 9, 2024
efdf111
programatically set the condition for save and publish so we can disa…
madsrasmussen Apr 9, 2024
5271afd
add save and preview button
madsrasmussen Apr 9, 2024
c266e96
export as api
madsrasmussen Apr 9, 2024
2c05412
disable save and publish button when not allowed
madsrasmussen Apr 9, 2024
0681b8d
use extension initializer
madsrasmussen Apr 9, 2024
1e8f101
add save action
madsrasmussen Apr 9, 2024
0ed1374
lazy load all document workspace actions
madsrasmussen Apr 9, 2024
3400a82
use fallback permissions correctly
madsrasmussen Apr 9, 2024
68bcdec
set entity context after load and create
madsrasmussen Apr 9, 2024
c9a0339
don't add to the permission list if the last modal is rejected
madsrasmussen Apr 10, 2024
043b97a
allow for both allOf and oneOf in the condition
madsrasmussen Apr 10, 2024
6766195
clean up
madsrasmussen Apr 10, 2024
8421656
add TODO
madsrasmussen Apr 10, 2024
bff10fd
Merge branch 'main' into feature/document-user-permission
madsrasmussen Apr 10, 2024
ce0664b
remove import
madsrasmussen Apr 10, 2024
df7f42c
Merge branch 'feature/document-user-permission' of https://github.com…
madsrasmussen Apr 10, 2024
bed0b6a
fix import
madsrasmussen Apr 10, 2024
1f27153
Merge branch 'main' into feature/document-user-permission
madsrasmussen Apr 10, 2024
854c1ec
Merge branch 'main' into feature/document-user-permission
madsrasmussen Apr 10, 2024
711020e
Merge branch 'main' into feature/document-user-permission
madsrasmussen Apr 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { UmbEntityContext } from '../../entity/entity.context.js';
import type { UmbEntityAction } from '@umbraco-cms/backoffice/entity-action';
import type { PropertyValueMap } from '@umbraco-cms/backoffice/external/lit';
import { html, nothing, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit';
Expand All @@ -6,7 +7,7 @@ import { UMB_SECTION_SIDEBAR_CONTEXT } from '@umbraco-cms/backoffice/section';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { ManifestEntityActionDefaultKind } from '@umbraco-cms/backoffice/extension-registry';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { createExtensionApi } from '@umbraco-cms/backoffice/extension-api';
import { UmbExtensionsManifestInitializer, createExtensionApi } from '@umbraco-cms/backoffice/extension-api';

@customElement('umb-entity-actions-bundle')
export class UmbEntityActionsBundleElement extends UmbLitElement {
Expand All @@ -30,6 +31,8 @@ export class UmbEntityActionsBundleElement extends UmbLitElement {

#sectionSidebarContext?: UmbSectionSidebarContext;

#entityContext = new UmbEntityContext(this);

constructor() {
super();

Expand All @@ -40,26 +43,35 @@ export class UmbEntityActionsBundleElement extends UmbLitElement {

protected updated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
if (_changedProperties.has('entityType') && _changedProperties.has('unique')) {
this.#entityContext.setEntityType(this.entityType);
this.#entityContext.setUnique(this.unique);
this.#observeEntityActions();
}
}

#observeEntityActions() {
this.observe(
umbExtensionsRegistry.byTypeAndFilter('entityAction', (ext) => ext.forEntityTypes.includes(this.entityType!)),
new UmbExtensionsManifestInitializer(
this,
umbExtensionsRegistry,
'entityAction',
(ext) => ext.forEntityTypes.includes(this.entityType!),
async (actions) => {
this._numberOfActions = actions.length;
this._firstActionManifest =
this._numberOfActions > 0 ? (actions[0] as ManifestEntityActionDefaultKind) : undefined;
if (!this._firstActionManifest) return;
this._firstActionApi = await createExtensionApi(this, this._firstActionManifest, [
{ unique: this.unique, entityType: this.entityType, meta: this._firstActionManifest.meta },
]);
this._numberOfActions > 0 ? (actions[0].manifest as ManifestEntityActionDefaultKind) : undefined;
this.#createFirstActionApi();
},
'umbEntityActionsObserver',
);
}

async #createFirstActionApi() {
if (!this._firstActionManifest) return;
this._firstActionApi = await createExtensionApi(this, this._firstActionManifest, [
{ unique: this.unique, entityType: this.entityType, meta: this._firstActionManifest.meta },
]);
}

#openContextMenu() {
if (!this.entityType) throw new Error('Entity type is not defined');
if (this.unique === undefined) throw new Error('Unique is not defined');
Expand All @@ -73,7 +85,7 @@ export class UmbEntityActionsBundleElement extends UmbLitElement {

render() {
if (this._numberOfActions === 0) return nothing;
return html`<uui-action-bar slot="actions"> ${this.#renderFirstAction()} ${this.#renderMore()} </uui-action-bar>`;
return html`<uui-action-bar slot="actions">${this.#renderMore()} ${this.#renderFirstAction()} </uui-action-bar>`;
}

#renderMore() {
Expand Down
10 changes: 5 additions & 5 deletions src/packages/core/extension-registry/conditions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,26 @@ import type { CollectionBulkActionPermissionConditionConfig } from '../../collec
import type { UmbSectionUserPermissionConditionConfig } from '../../section/conditions/index.js';
import type { SectionAliasConditionConfig } from './section-alias.condition.js';
import type { SwitchConditionConfig } from './switch.condition.js';
import type { UserPermissionConditionConfig } from '@umbraco-cms/backoffice/user-permission';
import type { BlockWorkspaceHasSettingsConditionConfig } from '@umbraco-cms/backoffice/block';
import type {
WorkspaceAliasConditionConfig,
WorkspaceEntityTypeConditionConfig,
} from '@umbraco-cms/backoffice/workspace';
import type { UmbConditionConfigBase } from '@umbraco-cms/backoffice/extension-api';
import type { UmbDocumentUserPermissionConditionConfig } from '@umbraco-cms/backoffice/document';

/* TODO: in theory should't the core package import from other packages.
Are there any other way we can do this?
Niels: Sadly I don't see any other solutions currently. But are very open for ideas :-) now that I think about it maybe there is some ability to extend a global type, similar to the 'declare global' trick we use on Elements.
*/
export type ConditionTypes =
| BlockWorkspaceHasSettingsConditionConfig
| CollectionAliasConditionConfig
| CollectionBulkActionPermissionConditionConfig
| SectionAliasConditionConfig
| WorkspaceAliasConditionConfig
| BlockWorkspaceHasSettingsConditionConfig
| WorkspaceEntityTypeConditionConfig
| SwitchConditionConfig
| UserPermissionConditionConfig
| UmbDocumentUserPermissionConditionConfig
| UmbSectionUserPermissionConditionConfig
| WorkspaceAliasConditionConfig
| WorkspaceEntityTypeConditionConfig
| UmbConditionConfigBase;
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ export class UmbReloadTreeItemChildrenEntityAction extends UmbEntityActionBase<M
);
}
}
export default UmbReloadTreeItemChildrenEntityAction;

export { UmbReloadTreeItemChildrenEntityAction as api };
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ export class UmbSubmitWorkspaceAction extends UmbWorkspaceActionBase<UmbSubmitta
(unique) => {
// We can't save if we don't have a unique
if (unique === undefined) {
this._isDisabled.setValue(true);
} else {
this._isDisabled.setValue(false);
this.disable();
}
},
'saveWorkspaceActionUniqueObserver',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,20 @@ export abstract class UmbWorkspaceActionBase<ArgsMetaType = never>
public execute(): Promise<void> {
return Promise.resolve();
}

/**
* Disables the action.
* @memberof UmbWorkspaceActionBase
*/
public disable(): void {
this._isDisabled.setValue(true);
}

/**
* Enables the action.
* @memberof UmbWorkspaceActionBase
*/
public enable(): void {
this._isDisabled.setValue(false);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { UMB_DOCUMENT_ENTITY_TYPE, UMB_DOCUMENT_ROOT_ENTITY_TYPE } from '../../entity.js';
import { UMB_USER_PERMISSION_DOCUMENT_CREATE } from '../../user-permissions/index.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';

const entityActions: Array<ManifestTypes> = [
Expand All @@ -14,6 +15,12 @@ const entityActions: Array<ManifestTypes> = [
icon: 'icon-add',
label: '#actions_create',
},
conditions: [
{
alias: 'Umb.Condition.UserPermission.Document',
allOf: [UMB_USER_PERMISSION_DOCUMENT_CREATE],
},
],
},
];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js';
import { UMB_USER_PERMISSION_DOCUMENT_CULTURE_AND_HOSTNAMES } from '../../user-permissions/index.js';
import { UmbDocumentCultureAndHostnamesEntityAction } from './culture-and-hostnames.action.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';

Expand All @@ -15,6 +16,12 @@ const entityActions: Array<ManifestTypes> = [
icon: 'icon-home',
label: '#actions_assigndomain',
},
conditions: [
{
alias: 'Umb.Condition.UserPermission.Document',
allOf: [UMB_USER_PERMISSION_DOCUMENT_CULTURE_AND_HOSTNAMES],
},
],
},
];

Expand Down
58 changes: 58 additions & 0 deletions src/packages/documents/documents/entity-actions/manifests.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import { UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS, UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS } from '../repository/index.js';
import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js';
import { UMB_DOCUMENT_PICKER_MODAL } from '../modals/index.js';
import {
UMB_USER_PERMISSION_DOCUMENT_CREATE_BLUEPRINT,
UMB_USER_PERMISSION_DOCUMENT_DELETE,
UMB_USER_PERMISSION_DOCUMENT_DUPLICATE,
UMB_USER_PERMISSION_DOCUMENT_MOVE,
UMB_USER_PERMISSION_DOCUMENT_NOTIFICATIONS,
UMB_USER_PERMISSION_DOCUMENT_PERMISSIONS,
UMB_USER_PERMISSION_DOCUMENT_PUBLISH,
UMB_USER_PERMISSION_DOCUMENT_UNPUBLISH,
} from '../user-permissions/constants.js';
import { manifests as createManifests } from './create/manifests.js';
import { manifests as publicAccessManifests } from './public-access/manifests.js';
import { manifests as cultureAndHostnamesManifests } from './culture-and-hostnames/manifests.js';
Expand All @@ -18,6 +28,12 @@ const entityActions: Array<ManifestEntityAction> = [
itemRepositoryAlias: UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS,
detailRepositoryAlias: UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS,
},
conditions: [
{
alias: 'Umb.Condition.UserPermission.Document',
allOf: [UMB_USER_PERMISSION_DOCUMENT_DELETE],
},
],
},
{
type: 'entityAction',
Expand All @@ -31,6 +47,12 @@ const entityActions: Array<ManifestEntityAction> = [
icon: 'icon-blueprint',
label: '#actions_createblueprint',
},
conditions: [
{
alias: 'Umb.Condition.UserPermission.Document',
allOf: [UMB_USER_PERMISSION_DOCUMENT_CREATE_BLUEPRINT],
},
],
},
{
type: 'entityAction',
Expand All @@ -44,6 +66,12 @@ const entityActions: Array<ManifestEntityAction> = [
itemRepositoryAlias: UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS,
pickerModelAlias: UMB_DOCUMENT_PICKER_MODAL,
},
conditions: [
{
alias: 'Umb.Condition.UserPermission.Document',
allOf: [UMB_USER_PERMISSION_DOCUMENT_MOVE],
},
],
},
{
type: 'entityAction',
Expand All @@ -57,6 +85,12 @@ const entityActions: Array<ManifestEntityAction> = [
itemRepositoryAlias: UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS,
pickerModal: UMB_DOCUMENT_PICKER_MODAL,
},
conditions: [
{
alias: 'Umb.Condition.UserPermission.Document',
allOf: [UMB_USER_PERMISSION_DOCUMENT_DUPLICATE],
},
],
},
{
type: 'entityAction',
Expand All @@ -70,6 +104,12 @@ const entityActions: Array<ManifestEntityAction> = [
icon: 'icon-globe',
label: '#actions_publish',
},
conditions: [
{
alias: 'Umb.Condition.UserPermission.Document',
allOf: [UMB_USER_PERMISSION_DOCUMENT_PUBLISH],
},
],
},
{
type: 'entityAction',
Expand All @@ -83,6 +123,12 @@ const entityActions: Array<ManifestEntityAction> = [
icon: 'icon-globe',
label: '#actions_unpublish',
},
conditions: [
{
alias: 'Umb.Condition.UserPermission.Document',
allOf: [UMB_USER_PERMISSION_DOCUMENT_UNPUBLISH],
},
],
},
{
type: 'entityAction',
Expand All @@ -96,6 +142,12 @@ const entityActions: Array<ManifestEntityAction> = [
icon: 'icon-name-badge',
label: '#actions_setPermissions',
},
conditions: [
{
alias: 'Umb.Condition.UserPermission.Document',
allOf: [UMB_USER_PERMISSION_DOCUMENT_PERMISSIONS],
},
],
},
{
type: 'entityAction',
Expand All @@ -109,6 +161,12 @@ const entityActions: Array<ManifestEntityAction> = [
icon: 'icon-megaphone',
label: '#actions_notify',
},
conditions: [
{
alias: 'Umb.Condition.UserPermission.Document',
allOf: [UMB_USER_PERMISSION_DOCUMENT_NOTIFICATIONS],
},
],
},
];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js';
import { UMB_USER_PERMISSION_DOCUMENT_PUBLIC_ACCESS } from '../../user-permissions/index.js';
import { UmbDocumentPublicAccessEntityAction } from './public-access.action.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';

Expand All @@ -15,6 +16,12 @@ const entityActions: Array<ManifestTypes> = [
icon: 'icon-lock',
label: '#actions_protect',
},
conditions: [
{
alias: 'Umb.Condition.UserPermission.Document',
allOf: [UMB_USER_PERMISSION_DOCUMENT_PUBLIC_ACCESS],
},
],
},
];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { UMB_DOCUMENT_ENTITY_TYPE, UMB_DOCUMENT_ROOT_ENTITY_TYPE } from '../../entity.js';
import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS } from '../../repository/index.js';
import { UMB_DOCUMENT_TREE_REPOSITORY_ALIAS } from '../../tree/index.js';
import { UMB_USER_PERMISSION_DOCUMENT_SORT } from '../../user-permissions/index.js';
import { UMB_SORT_CHILDREN_OF_DOCUMENT_REPOSITORY_ALIAS } from './repository/constants.js';
import { manifests as repositoryManifests } from './repository/manifests.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
Expand All @@ -18,5 +19,11 @@ export const manifests: Array<ManifestTypes> = [
sortChildrenOfRepositoryAlias: UMB_SORT_CHILDREN_OF_DOCUMENT_REPOSITORY_ALIAS,
treeRepositoryAlias: UMB_DOCUMENT_TREE_REPOSITORY_ALIAS,
},
conditions: [
{
alias: 'Umb.Condition.UserPermission.Document',
allOf: [UMB_USER_PERMISSION_DOCUMENT_SORT],
},
],
},
];
1 change: 1 addition & 0 deletions src/packages/documents/documents/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { UmbVariantModel, UmbVariantOptionModel, UmbVariantPublishModel } f
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
import { DocumentVariantStateModel as UmbDocumentVariantState } from '@umbraco-cms/backoffice/external/backend-api';
export { UmbDocumentVariantState };
export type { UmbDocumentUserPermissionConditionConfig } from './user-permissions/document-user-permission.condition.js';

export interface UmbDocumentDetailModel {
documentType: {
Expand Down
31 changes: 15 additions & 16 deletions src/packages/documents/documents/user-permissions/constants.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
export const UMB_USER_PERMISSION_DOCUMENT_CREATE = 'Umb.UserPermission.Document.Create';
export const UMB_USER_PERMISSION_DOCUMENT_READ = 'Umb.UserPermission.Document.Read';
export const UMB_USER_PERMISSION_DOCUMENT_UPDATE = 'Umb.UserPermission.Document.Update';
export const UMB_USER_PERMISSION_DOCUMENT_DELETE = 'Umb.UserPermission.Document.Delete';
export const UMB_USER_PERMISSION_DOCUMENT_CREATE_BLUEPRINT = 'Umb.UserPermission.Document.CreateBlueprint';
export const UMB_USER_PERMISSION_DOCUMENT_NOTIFICATIONS = 'Umb.UserPermission.Document.Notifications';
export const UMB_USER_PERMISSION_DOCUMENT_PUBLISH = 'Umb.UserPermission.Document.Publish';
export const UMB_USER_PERMISSION_DOCUMENT_PERMISSIONS = 'Umb.UserPermission.Document.Permissions';
export const UMB_USER_PERMISSION_DOCUMENT_SEND_FOR_APPROVAL = 'Umb.UserPermission.Document.SendForApproval';
export const UMB_USER_PERMISSION_DOCUMENT_UNPUBLISH = 'Umb.UserPermission.Document.Unpublish';
export const UMB_USER_PERMISSION_DOCUMENT_DUPLICATE = 'Umb.UserPermission.Document.Duplicate';
export const UMB_USER_PERMISSION_DOCUMENT_MOVE = 'Umb.UserPermission.Document.Move';
export const UMB_USER_PERMISSION_DOCUMENT_SORT = 'Umb.UserPermission.Document.Sort';
export const UMB_USER_PERMISSION_DOCUMENT_CULTURE_AND_HOSTNAMES = 'Umb.UserPermission.Document.CultureAndHostnames';
export const UMB_USER_PERMISSION_DOCUMENT_PUBLIC_ACCESS = 'Umb.UserPermission.Document.PublicAccess';
export const UMB_USER_PERMISSION_DOCUMENT_ROLLBACK = 'Umb.UserPermission.Document.Rollback';
export const UMB_USER_PERMISSION_DOCUMENT_CREATE = 'Umb.Document.Create';
export const UMB_USER_PERMISSION_DOCUMENT_READ = 'Umb.Document.Read';
export const UMB_USER_PERMISSION_DOCUMENT_UPDATE = 'Umb.Document.Update';
export const UMB_USER_PERMISSION_DOCUMENT_DELETE = 'Umb.Document.Delete';
export const UMB_USER_PERMISSION_DOCUMENT_CREATE_BLUEPRINT = 'Umb.Document.CreateBlueprint';
export const UMB_USER_PERMISSION_DOCUMENT_NOTIFICATIONS = 'Umb.Document.Notifications';
export const UMB_USER_PERMISSION_DOCUMENT_PUBLISH = 'Umb.Document.Publish';
export const UMB_USER_PERMISSION_DOCUMENT_PERMISSIONS = 'Umb.Document.Permissions';
export const UMB_USER_PERMISSION_DOCUMENT_UNPUBLISH = 'Umb.Document.Unpublish';
export const UMB_USER_PERMISSION_DOCUMENT_DUPLICATE = 'Umb.Document.Duplicate';
export const UMB_USER_PERMISSION_DOCUMENT_MOVE = 'Umb.Document.Move';
export const UMB_USER_PERMISSION_DOCUMENT_SORT = 'Umb.Document.Sort';
export const UMB_USER_PERMISSION_DOCUMENT_CULTURE_AND_HOSTNAMES = 'Umb.Document.CultureAndHostnames';
export const UMB_USER_PERMISSION_DOCUMENT_PUBLIC_ACCESS = 'Umb.Document.PublicAccess';
export const UMB_USER_PERMISSION_DOCUMENT_ROLLBACK = 'Umb.Document.Rollback';
Loading