umbraco-granular-user-permissions

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Umbraco Granular User Permissions

Umbraco细粒度用户权限

What is it?

什么是细粒度用户权限?

Granular User Permissions allow you to create custom permission controls for specific entity types in Umbraco. Unlike general entity permissions that apply to all instances, granular permissions can be configured per-entity, allowing fine-grained access control. This is commonly used for document permissions where different users can have different permissions on different content nodes.
细粒度用户权限允许你在Umbraco中为特定实体类型创建自定义权限控制。与适用于所有实例的通用实体权限不同,细粒度权限可以针对每个实体单独配置,实现精细化的访问控制。这通常用于文档权限管理,不同用户可对不同内容节点拥有不同权限。

Documentation

文档参考

Reference Example

参考示例

The Umbraco source includes a working example:
Location:
/Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/user-permission/
This example demonstrates granular user permission implementation. Study this for production patterns.
Umbraco源码中包含一个可用示例:
位置
/Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/user-permission/
该示例展示了细粒度用户权限的实现方式,可参考其中的生产环境实践模式。

Related Foundation Skills

相关基础技能

  • Conditions: When controlling permission visibility
    • Reference skill:
      umbraco-conditions
  • Context API: When accessing user or workspace context
    • Reference skill:
      umbraco-context-api
  • 条件判断:控制权限可见性时会用到
    • 参考技能:
      umbraco-conditions
  • 上下文API:访问用户或工作区上下文时会用到
    • 参考技能:
      umbraco-context-api

Workflow

工作流程

  1. Fetch docs - Use WebFetch on the URLs above
  2. Ask questions - What entity type? What permissions? What schema type?
  3. Generate files - Create manifest + element based on latest docs
  4. Explain - Show what was created and how to test
  1. 获取文档 - 使用WebFetch获取上述URL中的文档
  2. 明确需求 - 确定目标实体类型?需要哪些权限?采用什么架构类型?
  3. 生成文件 - 根据最新文档创建清单文件(manifest)和元素组件
  4. 说明解释 - 展示创建的内容以及测试方法

Minimal Examples

最简示例

Manifest (manifests.ts)

清单文件(manifests.ts)

typescript
import type { ManifestGranularUserPermission } from '@umbraco-cms/backoffice/user-permission';

export const manifests: Array<ManifestGranularUserPermission> = [
  {
    type: 'userGranularPermission',
    alias: 'My.GranularPermission.Custom',
    name: 'Custom Granular Permission',
    weight: 100,
    forEntityTypes: ['my-entity-type'],
    element: () => import('./my-granular-permission.element.js'),
    meta: {
      schemaType: 'MyPermissionPresentationModel',
      label: 'Custom Permissions',
      description: 'Configure custom permissions for this entity',
    },
  },
];
typescript
import type { ManifestGranularUserPermission } from '@umbraco-cms/backoffice/user-permission';

export const manifests: Array<ManifestGranularUserPermission> = [
  {
    type: 'userGranularPermission',
    alias: 'My.GranularPermission.Custom',
    name: 'Custom Granular Permission',
    weight: 100,
    forEntityTypes: ['my-entity-type'],
    element: () => import('./my-granular-permission.element.js'),
    meta: {
      schemaType: 'MyPermissionPresentationModel',
      label: 'Custom Permissions',
      description: 'Configure custom permissions for this entity',
    },
  },
];

Element Implementation (my-granular-permission.element.ts)

元素组件实现(my-granular-permission.element.ts)

typescript
import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';

@customElement('my-granular-permission')
export class MyGranularPermissionElement extends UmbLitElement {
  @property({ attribute: false })
  value: unknown;

  @state()
  private _permissions: string[] = [];

  override render() {
    return html`
      <uui-box headline="Custom Permissions">
        <uui-checkbox
          label="Can Edit"
          @change=${(e: Event) => this.#onPermissionChange('edit', (e.target as HTMLInputElement).checked)}
        ></uui-checkbox>
        <uui-checkbox
          label="Can Delete"
          @change=${(e: Event) => this.#onPermissionChange('delete', (e.target as HTMLInputElement).checked)}
        ></uui-checkbox>
      </uui-box>
    `;
  }

  #onPermissionChange(permission: string, enabled: boolean) {
    if (enabled) {
      this._permissions = [...this._permissions, permission];
    } else {
      this._permissions = this._permissions.filter(p => p !== permission);
    }
    this.dispatchEvent(new CustomEvent('change', { detail: { permissions: this._permissions } }));
  }
}

export default MyGranularPermissionElement;
typescript
import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';

@customElement('my-granular-permission')
export class MyGranularPermissionElement extends UmbLitElement {
  @property({ attribute: false })
  value: unknown;

  @state()
  private _permissions: string[] = [];

  override render() {
    return html`
      <uui-box headline="Custom Permissions">
        <uui-checkbox
          label="Can Edit"
          @change=${(e: Event) => this.#onPermissionChange('edit', (e.target as HTMLInputElement).checked)}
        ></uui-checkbox>
        <uui-checkbox
          label="Can Delete"
          @change=${(e: Event) => this.#onPermissionChange('delete', (e.target as HTMLInputElement).checked)}
        ></uui-checkbox>
      </uui-box>
    `;
  }

  #onPermissionChange(permission: string, enabled: boolean) {
    if (enabled) {
      this._permissions = [...this._permissions, permission];
    } else {
      this._permissions = this._permissions.filter(p => p !== permission);
    }
    this.dispatchEvent(new CustomEvent('change', { detail: { permissions: this._permissions } }));
  }
}

export default MyGranularPermissionElement;

Interface Reference

接口参考

typescript
interface ManifestGranularUserPermission extends ManifestElement {
  type: 'userGranularPermission';
  forEntityTypes?: Array<string>;
  meta: MetaGranularUserPermission;
}

interface MetaGranularUserPermission {
  schemaType: string;      // API schema type for serialization
  label?: string;          // Display label (can use localization key)
  labelKey?: string;       // Localization key for label
  description?: string;    // Description text
  descriptionKey?: string; // Localization key for description
}
typescript
interface ManifestGranularUserPermission extends ManifestElement {
  type: 'userGranularPermission';
  forEntityTypes?: Array<string>;
  meta: MetaGranularUserPermission;
}

interface MetaGranularUserPermission {
  schemaType: string;      // 用于序列化的API架构类型
  label?: string;          // 显示标签(可使用本地化键)
  labelKey?: string;       // 标签的本地化键
  description?: string;    // 描述文本
  descriptionKey?: string; // 描述的本地化键
}

Common Entity Types

常见实体类型

  • document
    - Content nodes
  • media
    - Media items
  • member
    - Members
That's it! Always fetch fresh docs, keep examples minimal, generate complete working code.
  • document
    - 内容节点
  • media
    - 媒体项
  • member
    - 会员
就是这样!请务必获取最新文档,保持示例简洁,生成完整可运行的代码。