@umbraco-cms/backoffice 17.4.0-rc → 17.4.0-rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/custom-elements.json +1 -1
  2. package/dist-cms/apps/app/app.element.js +120 -7
  3. package/dist-cms/apps/backoffice/backoffice.context.js +1 -9
  4. package/dist-cms/apps/backoffice/backoffice.element.d.ts +0 -2
  5. package/dist-cms/apps/backoffice/backoffice.element.js +0 -58
  6. package/dist-cms/apps/backoffice/components/backoffice-main.element.d.ts +2 -2
  7. package/dist-cms/apps/backoffice/components/backoffice-main.element.js +16 -3
  8. package/dist-cms/libs/extension-api/controller/base-extension-initializer.controller.d.ts +1 -1
  9. package/dist-cms/libs/extension-api/controller/base-extension-initializer.controller.js +61 -19
  10. package/dist-cms/libs/extension-api/controller/extension-api-initializer.controller.d.ts +1 -1
  11. package/dist-cms/libs/extension-api/controller/extension-api-initializer.controller.js +10 -3
  12. package/dist-cms/libs/extension-api/controller/extension-element-and-api-initializer.controller.d.ts +1 -1
  13. package/dist-cms/libs/extension-api/controller/extension-element-and-api-initializer.controller.js +12 -3
  14. package/dist-cms/libs/extension-api/controller/extension-element-initializer.controller.d.ts +1 -1
  15. package/dist-cms/libs/extension-api/controller/extension-element-initializer.controller.js +11 -3
  16. package/dist-cms/libs/extension-api/controller/extension-manifest-initializer.controller.d.ts +1 -1
  17. package/dist-cms/libs/extension-api/controller/extension-manifest-initializer.controller.js +1 -1
  18. package/dist-cms/libs/extension-api/initializers/extension-initializer-base.d.ts +2 -2
  19. package/dist-cms/libs/extension-api/initializers/extension-initializer-base.js +7 -3
  20. package/dist-cms/libs/extension-api/registry/extension.registry.js +22 -2
  21. package/dist-cms/packages/block/block/conditions/block-workspace-is-readonly.condition.js +4 -2
  22. package/dist-cms/packages/block/block/context/block-entry.context.js +1 -4
  23. package/dist-cms/packages/block/block/workspace/block-element-manager.js +2 -2
  24. package/dist-cms/packages/block/block/workspace/block-workspace-editor.element.d.ts +1 -0
  25. package/dist-cms/packages/block/block/workspace/block-workspace-editor.element.js +31 -9
  26. package/dist-cms/packages/block/block/workspace/block-workspace-language-access.controller.d.ts +16 -0
  27. package/dist-cms/packages/block/block/workspace/block-workspace-language-access.controller.js +126 -0
  28. package/dist-cms/packages/block/block/workspace/block-workspace.context.js +23 -19
  29. package/dist-cms/packages/block/block/workspace/manifests.js +3 -0
  30. package/dist-cms/packages/block/block-custom-view/types.d.ts +1 -0
  31. package/dist-cms/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.js +4 -5
  32. package/dist-cms/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.js +2 -5
  33. package/dist-cms/packages/block/block-list/components/block-list-entry/block-list-entry.element.js +11 -6
  34. package/dist-cms/packages/block/block-rte/components/block-rte-entry/block-rte-entry.element.js +4 -5
  35. package/dist-cms/packages/block/block-single/components/block-single-entry/block-single-entry.element.js +4 -5
  36. package/dist-cms/packages/code-editor/umbraco-package.d.ts +1 -0
  37. package/dist-cms/packages/code-editor/umbraco-package.js +1 -0
  38. package/dist-cms/packages/content/content/global-components/content-workspace-property.element.js +1 -1
  39. package/dist-cms/packages/core/components/body-layout/body-layout.element.js +3 -1
  40. package/dist-cms/packages/core/extension-registry/conditions/condition-base.controller.js +3 -2
  41. package/dist-cms/packages/core/extension-registry/conditions/delay.condition.js +5 -1
  42. package/dist-cms/packages/core/extension-registry/conditions/switch.condition.d.ts +0 -2
  43. package/dist-cms/packages/core/extension-registry/conditions/switch.condition.js +13 -7
  44. package/dist-cms/packages/core/property/property-guard-manager/property-guard.manager.d.ts +1 -1
  45. package/dist-cms/packages/core/property/property-guard-manager/property-guard.manager.js +6 -3
  46. package/dist-cms/packages/core/property/property-guard-manager/variant-property-guard.manager.d.ts +1 -1
  47. package/dist-cms/packages/core/property/property-guard-manager/variant-property-guard.manager.js +7 -3
  48. package/dist-cms/packages/core/recycle-bin/conditions/is-trashed/entity-is-trashed.condition.js +2 -1
  49. package/dist-cms/packages/core/repository/data-mapper/mapping/data-mapping-resolver.js +1 -0
  50. package/dist-cms/packages/core/utils/guard-manager/guard.manager.base.d.ts +4 -2
  51. package/dist-cms/packages/core/utils/guard-manager/guard.manager.base.js +10 -5
  52. package/dist-cms/packages/core/utils/guard-manager/readonly-guard.manager.js +9 -5
  53. package/dist-cms/packages/core/utils/guard-manager/readonly-variant-guard.manager.d.ts +12 -2
  54. package/dist-cms/packages/core/utils/guard-manager/readonly-variant-guard.manager.js +26 -11
  55. package/dist-cms/packages/core/variant/variant-id.class.d.ts +4 -0
  56. package/dist-cms/packages/core/variant/variant-id.class.js +5 -1
  57. package/dist-cms/packages/core/workspace/components/workspace-action/common/submit/submit.action.d.ts +2 -2
  58. package/dist-cms/packages/core/workspace/components/workspace-action/common/submit/submit.action.js +8 -2
  59. package/dist-cms/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.js +7 -10
  60. package/dist-cms/packages/core/workspace/namable/name-write-guard.manager.js +5 -2
  61. package/dist-cms/packages/core/workspace/workspace.element.d.ts +0 -2
  62. package/dist-cms/packages/core/workspace/workspace.element.js +1 -4
  63. package/dist-cms/packages/documents/document-types/property-type/manifests.js +2 -1
  64. package/dist-cms/packages/documents/documents/reference/repository/manifests.js +2 -1
  65. package/dist-cms/packages/documents/documents/user-permissions/document-property-value/conditions/document-property-value-user-permission.condition.js +2 -0
  66. package/dist-cms/packages/documents/documents/user-permissions/document-property-value/data/manifests.js +4 -2
  67. package/dist-cms/packages/documents/documents/user-permissions/document-property-value/workspace-context/document-block-property-value-user-permission.workspace-context.js +3 -5
  68. package/dist-cms/packages/documents/documents/workspace/actions/save.action.js +2 -0
  69. package/dist-cms/packages/documents/documents/workspace/document-workspace.context.js +6 -1
  70. package/dist-cms/packages/documents/umbraco-package.d.ts +1 -6
  71. package/dist-cms/packages/documents/umbraco-package.js +2 -8
  72. package/dist-cms/packages/media/media/reference/repository/manifests.js +2 -1
  73. package/dist-cms/packages/media/media-types/property-type/manifests.js +2 -1
  74. package/dist-cms/packages/members/member/reference/repository/manifests.js +2 -1
  75. package/dist-cms/packages/members/member-type/property-type/manifests.js +2 -1
  76. package/dist-cms/packages/rte/components/rte-base.element.d.ts +2 -1
  77. package/dist-cms/packages/rte/components/rte-base.element.js +19 -6
  78. package/dist-cms/packages/ufm/umbraco-package.d.ts +1 -0
  79. package/dist-cms/packages/ufm/umbraco-package.js +1 -0
  80. package/dist-cms/packages/user/current-user/current-user.context.d.ts +3 -1
  81. package/dist-cms/packages/user/current-user/current-user.context.js +11 -17
  82. package/dist-cms/tsconfig.build.tsbuildinfo +1 -1
  83. package/package.json +1 -1
  84. package/vscode-html-custom-data.json +3 -3
@@ -29,7 +29,7 @@ let UmbContentWorkspacePropertyElement = class UmbContentWorkspacePropertyElemen
29
29
  });
30
30
  // The Content Workspace Context is used to retrieve the property type we like to observe.
31
31
  // This gives us the configuration from the property type as part of the data type.
32
- this.consumeContext(UMB_CONTENT_WORKSPACE_CONTEXT, async (workspaceContext) => {
32
+ this.consumeContext(UMB_CONTENT_WORKSPACE_CONTEXT, (workspaceContext) => {
33
33
  this._workspaceContext = workspaceContext;
34
34
  this.#observePropertyType();
35
35
  });
@@ -68,7 +68,9 @@ let UmbBodyLayoutElement = class UmbBodyLayoutElement extends LitElement {
68
68
  this._navigationSlotHasChildren
69
69
  ? ''
70
70
  : 'none'}">
71
- ${this.headline ? html `<h3 id="headline" title=${this.headline}>${this.headline}</h3>` : nothing}
71
+ ${this.headline
72
+ ? html `<h3 id="headline" title=${this.headline} data-mark="layout-headline">${this.headline}</h3>`
73
+ : nothing}
72
74
 
73
75
  <slot
74
76
  id="header-slot"
@@ -8,7 +8,7 @@ export class UmbConditionBase extends UmbControllerBase {
8
8
  if (value === this.#permitted)
9
9
  return;
10
10
  this.#permitted = value;
11
- this.#onChange(value);
11
+ this.#onChange?.(value);
12
12
  }
13
13
  #onChange;
14
14
  constructor(host, args) {
@@ -17,8 +17,9 @@ export class UmbConditionBase extends UmbControllerBase {
17
17
  this.#onChange = args.onChange;
18
18
  }
19
19
  destroy() {
20
+ // Clear `#onChange` before `super.destroy()`. [NL]
21
+ this.#onChange = undefined;
20
22
  super.destroy();
21
23
  this.config = undefined;
22
- this.#onChange = undefined;
23
24
  }
24
25
  }
@@ -3,9 +3,13 @@ export class UmbDelayCondition extends UmbConditionBase {
3
3
  #timer;
4
4
  constructor(host, args) {
5
5
  super(host, args);
6
+ const offset = parseInt(this.config.offset);
7
+ if (isNaN(offset) || offset <= 0) {
8
+ throw new Error(`Offset must be a positive number (offset: ${this.config.offset})`);
9
+ }
6
10
  this.#timer = setTimeout(() => {
7
11
  this.permitted = true;
8
- }, parseInt(this.config.offset));
12
+ }, offset);
9
13
  }
10
14
  destroy() {
11
15
  clearTimeout(this.#timer);
@@ -4,8 +4,6 @@ import type { ManifestCondition, UmbConditionConfigBase, UmbConditionControllerA
4
4
  export declare class UmbSwitchCondition extends UmbConditionBase<SwitchConditionConfig> implements UmbExtensionCondition {
5
5
  #private;
6
6
  constructor(host: UmbControllerHost, args: UmbConditionControllerArguments<SwitchConditionConfig>);
7
- startApprove(): void;
8
- startDisapprove(): void;
9
7
  destroy(): void;
10
8
  }
11
9
  export declare const manifest: ManifestCondition;
@@ -1,23 +1,29 @@
1
1
  import { UmbConditionBase } from './condition-base.controller.js';
2
2
  export class UmbSwitchCondition extends UmbConditionBase {
3
3
  #timer;
4
+ #frequency;
4
5
  constructor(host, args) {
5
6
  super(host, args);
6
- this.startApprove();
7
+ const frequency = parseInt(this.config.frequency);
8
+ if (isNaN(frequency) || frequency <= 0) {
9
+ throw new Error(`Frequency must be a positive number (frequency: ${this.config.frequency})`);
10
+ }
11
+ this.#frequency = frequency;
12
+ this.#startApprove();
7
13
  }
8
- startApprove() {
14
+ #startApprove() {
9
15
  clearTimeout(this.#timer);
10
16
  this.#timer = setTimeout(() => {
11
17
  this.permitted = true;
12
- this.startDisapprove();
13
- }, parseInt(this.config.frequency));
18
+ this.#startDisapprove();
19
+ }, this.#frequency);
14
20
  }
15
- startDisapprove() {
21
+ #startDisapprove() {
16
22
  clearTimeout(this.#timer);
17
23
  this.#timer = setTimeout(() => {
18
24
  this.permitted = false;
19
- this.startApprove();
20
- }, parseInt(this.config.frequency));
25
+ this.#startApprove();
26
+ }, this.#frequency);
21
27
  }
22
28
  destroy() {
23
29
  clearTimeout(this.#timer);
@@ -1,4 +1,4 @@
1
- import type { Observable } from '../../../../libs/observable-api/index.js';
1
+ import { type Observable } from '../../../../libs/observable-api/index.js';
2
2
  import type { UmbReferenceByUnique } from '../../models/index.js';
3
3
  import { UmbGuardManagerBase, type UmbGuardRule } from '../../utils/index.js';
4
4
  export interface UmbPropertyGuardRule extends UmbGuardRule {
@@ -1,3 +1,4 @@
1
+ import { mergeObservables } from '../../../../libs/observable-api/index.js';
1
2
  import { UmbGuardManagerBase } from '../../utils/index.js';
2
3
  /**
3
4
  *
@@ -21,7 +22,9 @@ export class UmbPropertyGuardManager extends UmbGuardManagerBase {
21
22
  * @memberof UmbPropertyGuardManager
22
23
  */
23
24
  isPermittedForProperty(propertyType) {
24
- return this._rules.asObservablePart((rules) => this.#resolvePermission(rules, propertyType));
25
+ return mergeObservables([this.rules, this._fallback], ([states, fallback]) => {
26
+ return this.#resolvePermission(states, propertyType) ?? fallback;
27
+ });
25
28
  }
26
29
  /**
27
30
  * Checks if the property is permitted for the given property type
@@ -30,7 +33,7 @@ export class UmbPropertyGuardManager extends UmbGuardManagerBase {
30
33
  * @memberof UmbPropertyGuardManager
31
34
  */
32
35
  getIsPermittedForProperty(propertyType) {
33
- return this.#resolvePermission(this.getRules(), propertyType);
36
+ return this.#resolvePermission(this.getRules(), propertyType) ?? this._getFallback();
34
37
  }
35
38
  #resolvePermission(rules, propertyType) {
36
39
  if (rules.filter((x) => x.permitted === false).some((rule) => findRule(rule, propertyType))) {
@@ -39,6 +42,6 @@ export class UmbPropertyGuardManager extends UmbGuardManagerBase {
39
42
  if (rules.filter((x) => x.permitted === true).some((rule) => findRule(rule, propertyType))) {
40
43
  return true;
41
44
  }
42
- return this._fallback;
45
+ return undefined;
43
46
  }
44
47
  }
@@ -1,6 +1,6 @@
1
1
  import type { UmbPropertyGuardRule } from './property-guard.manager.js';
2
2
  import type { UmbVariantId } from '../../variant/index.js';
3
- import type { Observable } from '../../../../libs/observable-api/index.js';
3
+ import { type Observable } from '../../../../libs/observable-api/index.js';
4
4
  import type { UmbReferenceByUnique } from '../../models/index.js';
5
5
  import { UmbGuardManagerBase } from '../../utils/index.js';
6
6
  export interface UmbVariantPropertyGuardRule extends UmbPropertyGuardRule {
@@ -1,3 +1,4 @@
1
+ import { mergeObservables } from '../../../../libs/observable-api/index.js';
1
2
  import { UmbGuardManagerBase } from '../../utils/index.js';
2
3
  /**
3
4
  *
@@ -28,7 +29,9 @@ export class UmbVariantPropertyGuardManager extends UmbGuardManagerBase {
28
29
  * @memberof UmbVariantPropertyGuardManager
29
30
  */
30
31
  isPermittedForVariantAndProperty(propertyVariantId, propertyType, datasetVariantId) {
31
- return this._rules.asObservablePart((rules) => this.#resolvePermission(rules, propertyVariantId, propertyType, datasetVariantId));
32
+ return mergeObservables([this.rules, this._fallback], ([rules, fallback]) => {
33
+ return this.#resolvePermission(rules, propertyVariantId, propertyType, datasetVariantId) ?? fallback;
34
+ });
32
35
  }
33
36
  /**
34
37
  * Checks if the variant and propertyType is permitted.
@@ -39,7 +42,8 @@ export class UmbVariantPropertyGuardManager extends UmbGuardManagerBase {
39
42
  * @memberof UmbVariantPropertyGuardManager
40
43
  */
41
44
  getIsPermittedForVariantAndProperty(propertyVariantId, propertyType, datasetVariantId) {
42
- return this.#resolvePermission(this._rules.getValue(), propertyVariantId, propertyType, datasetVariantId);
45
+ return (this.#resolvePermission(this._rules.getValue(), propertyVariantId, propertyType, datasetVariantId) ??
46
+ this._getFallback());
43
47
  }
44
48
  #resolvePermission(rules, propertyVariantId, propertyType, datasetVariantId) {
45
49
  if (rules
@@ -52,6 +56,6 @@ export class UmbVariantPropertyGuardManager extends UmbGuardManagerBase {
52
56
  .some((rule) => findRule(rule, propertyVariantId, propertyType, datasetVariantId))) {
53
57
  return true;
54
58
  }
55
- return this._fallback;
59
+ return undefined;
56
60
  }
57
61
  }
@@ -1,12 +1,13 @@
1
1
  import { UMB_IS_TRASHED_ENTITY_CONTEXT } from '../../constants.js';
2
2
  import { UmbConditionBase } from '../../../extension-registry/index.js';
3
+ const s = Symbol();
3
4
  export class UmbEntityIsTrashedCondition extends UmbConditionBase {
4
5
  constructor(host, args) {
5
6
  super(host, args);
6
7
  this.consumeContext(UMB_IS_TRASHED_ENTITY_CONTEXT, (context) => {
7
8
  this.observe(context?.isTrashed, (isTrashed) => {
8
9
  this.permitted = isTrashed === true;
9
- });
10
+ }, s);
10
11
  });
11
12
  }
12
13
  }
@@ -35,6 +35,7 @@ export class UmbDataSourceDataMappingResolver extends UmbControllerBase {
35
35
  return undefined;
36
36
  }
37
37
  // Pick the manifest with the highest priority
38
+ // TODO: We can remove this sorting, it is implemented in the extension registry.
38
39
  // TODO: This should have been handled in the extension registry, but until then we do it here: [NL]
39
40
  return supportedManifests.sort((a, b) => (b.weight || 0) - (a.weight || 0))[0];
40
41
  }
@@ -11,17 +11,19 @@ export interface UmbGuardRule extends UmbGuardIncomingRuleBase {
11
11
  permitted: boolean;
12
12
  }
13
13
  export declare abstract class UmbGuardManagerBase<RuleType extends UmbGuardRule = UmbGuardRule, IncomingRuleType extends UmbGuardIncomingRuleBase = UmbPartialSome<RuleType, 'unique' | 'permitted'>> extends UmbControllerBase {
14
+ #private;
14
15
  protected readonly _rules: UmbArrayState<RuleType, unknown>;
15
16
  readonly rules: import("rxjs").Observable<RuleType[]>;
16
17
  readonly hasRules: import("rxjs").Observable<boolean>;
17
- protected _fallback: boolean;
18
+ protected _fallback: import("rxjs").Observable<boolean>;
19
+ protected _getFallback(): boolean;
18
20
  fallbackToNotPermitted(): void;
19
21
  fallbackToPermitted(): void;
20
22
  /**
21
23
  * Add a new rule
22
24
  * @param {RuleType} rule
23
25
  */
24
- addRule(rule: IncomingRuleType): string | symbol | undefined;
26
+ addRule(rule: IncomingRuleType): RuleType['unique'];
25
27
  /**
26
28
  * Add multiple rules
27
29
  * @param {RuleType[]} rules
@@ -1,5 +1,5 @@
1
1
  import { UmbControllerBase } from '../../../../libs/class-api/index.js';
2
- import { UmbArrayState } from '../../../../libs/observable-api/index.js';
2
+ import { UmbArrayState, UmbBooleanState } from '../../../../libs/observable-api/index.js';
3
3
  export class UmbGuardManagerBase extends UmbControllerBase {
4
4
  constructor() {
5
5
  super(...arguments);
@@ -7,13 +7,18 @@ export class UmbGuardManagerBase extends UmbControllerBase {
7
7
  this._rules = new UmbArrayState([], (x) => x.unique);
8
8
  this.rules = this._rules.asObservable();
9
9
  this.hasRules = this._rules.asObservablePart((x) => x.length > 0);
10
- this._fallback = false;
10
+ this.#fallback = new UmbBooleanState(false);
11
+ this._fallback = this.#fallback.asObservable();
12
+ }
13
+ #fallback;
14
+ _getFallback() {
15
+ return this.#fallback.getValue();
11
16
  }
12
17
  fallbackToNotPermitted() {
13
- this._fallback = false;
18
+ this.#fallback.setValue(false);
14
19
  }
15
20
  fallbackToPermitted() {
16
- this._fallback = true;
21
+ this.#fallback.setValue(true);
17
22
  }
18
23
  /**
19
24
  * Add a new rule
@@ -26,7 +31,7 @@ export class UmbGuardManagerBase extends UmbControllerBase {
26
31
  newRule.permitted = true;
27
32
  }
28
33
  this._rules.appendOne(newRule);
29
- return rule.unique;
34
+ return newRule.unique;
30
35
  }
31
36
  /**
32
37
  * Add multiple rules
@@ -1,14 +1,18 @@
1
+ import { mergeObservables } from '../../../../libs/observable-api/index.js';
1
2
  import { UmbGuardManagerBase } from './guard.manager.base.js';
2
3
  // TODO: Check the need for this one.
3
4
  export class UmbReadOnlyGuardManager extends UmbGuardManagerBase {
4
5
  constructor() {
5
6
  super(...arguments);
6
- this.permitted = this._rules.asObservablePart((rules) => {
7
- return this.#resolvePermission(rules);
8
- });
7
+ this.permitted = mergeObservables([
8
+ this._rules.asObservablePart((rules) => {
9
+ return this.#resolvePermission(rules);
10
+ }),
11
+ this._fallback,
12
+ ], ([permitted, fallback]) => permitted ?? fallback);
9
13
  }
10
14
  getPermitted() {
11
- return this.#resolvePermission(this.getRules());
15
+ return this.#resolvePermission(this.getRules()) ?? this._getFallback();
12
16
  }
13
17
  #resolvePermission(rules) {
14
18
  if (rules.filter((x) => x.permitted === false).length > 0) {
@@ -17,6 +21,6 @@ export class UmbReadOnlyGuardManager extends UmbGuardManagerBase {
17
21
  if (rules.filter((x) => x.permitted === true).length > 0) {
18
22
  return true;
19
23
  }
20
- return this._fallback;
24
+ return undefined;
21
25
  }
22
26
  }
@@ -22,10 +22,20 @@ export declare class UmbReadOnlyVariantGuardManager extends UmbReadOnlyGuardMana
22
22
  isPermittedForVariant(variantId: UmbVariantId): Observable<boolean>;
23
23
  /**
24
24
  * @param {Observable<UmbVariantId | undefined>} variantId
25
- * @returns {Observable<boolean>} - Observable that emits true if the variantId is permitted to read, false otherwise
25
+ * @returns {Observable<boolean | undefined>} - Observable that emits true if the variantId is permitted to read, false otherwise
26
+ * @memberof UmbReadOnlyVariantGuardManager
27
+ */
28
+ isPermittedForObservableVariant(variantId: Observable<UmbVariantId | undefined>): Observable<boolean | undefined>;
29
+ /**
30
+ * Observe the permission for multiple given variantIds
31
+ * @param {Observable<UmbVariantId[]>} variantIds - Observable emitting the variantIds to evaluate
32
+ * @returns {Observable<{ variantId: UmbVariantId; permitted: boolean }[]>} - Observable that emits an array of objects with a permitted boolean and the variantId
26
33
  * @memberof UmbReadOnlyVariantGuardManager
27
34
  */
28
- isPermittedForObservableVariant(variantId: Observable<UmbVariantId | undefined>): Observable<boolean>;
35
+ isPermittedForObservableVariants(variantIds: Observable<UmbVariantId[]>): Observable<{
36
+ variantId: UmbVariantId;
37
+ permitted: boolean;
38
+ }[]>;
29
39
  /**
30
40
  * Check if the given variantId is permitted to read
31
41
  * @param {UmbVariantId} variantId
@@ -8,7 +8,6 @@ import { mergeObservables } from '../../../../libs/observable-api/index.js';
8
8
  function findRule(rule, variantId) {
9
9
  return rule.variantId?.compare(variantId) || rule.variantId === undefined;
10
10
  }
11
- // TODO: Check the need for this one.
12
11
  /**
13
12
  * Read only guard manager for variant rules.
14
13
  * @export
@@ -23,22 +22,38 @@ export class UmbReadOnlyVariantGuardManager extends UmbReadOnlyGuardManager {
23
22
  * @memberof UmbReadOnlyVariantGuardManager
24
23
  */
25
24
  isPermittedForVariant(variantId) {
26
- return this._rules.asObservablePart((states) => {
27
- return this.#resolvePermission(states, variantId);
28
- });
25
+ return mergeObservables([
26
+ this._rules.asObservablePart((rules) => {
27
+ return this.#resolvePermission(rules, variantId);
28
+ }),
29
+ this._fallback,
30
+ ], ([permitted, fallback]) => permitted ?? fallback);
29
31
  }
30
32
  /**
31
33
  * @param {Observable<UmbVariantId | undefined>} variantId
32
- * @returns {Observable<boolean>} - Observable that emits true if the variantId is permitted to read, false otherwise
34
+ * @returns {Observable<boolean | undefined>} - Observable that emits true if the variantId is permitted to read, false otherwise
33
35
  * @memberof UmbReadOnlyVariantGuardManager
34
36
  */
35
37
  isPermittedForObservableVariant(variantId) {
36
- return mergeObservables([this.rules, variantId], ([states, variantId]) => {
38
+ return mergeObservables([this.rules, variantId, this._fallback], ([rules, variantId, fallback]) => {
37
39
  if (!variantId) {
38
- // Or should we know about the fallback state here? [NL]
39
- return false;
40
+ return undefined;
41
+ }
42
+ return this.#resolvePermission(rules, variantId) ?? fallback;
43
+ });
44
+ }
45
+ /**
46
+ * Observe the permission for multiple given variantIds
47
+ * @param {Observable<UmbVariantId[]>} variantIds - Observable emitting the variantIds to evaluate
48
+ * @returns {Observable<{ variantId: UmbVariantId; permitted: boolean }[]>} - Observable that emits an array of objects with a permitted boolean and the variantId
49
+ * @memberof UmbReadOnlyVariantGuardManager
50
+ */
51
+ isPermittedForObservableVariants(variantIds) {
52
+ return mergeObservables([this.rules, variantIds, this._fallback], ([rules, variantIds, fallback]) => {
53
+ if (!variantIds || variantIds.length === 0) {
54
+ return [];
40
55
  }
41
- return this.#resolvePermission(states, variantId);
56
+ return variantIds.map((id) => ({ variantId: id, permitted: this.#resolvePermission(rules, id) ?? fallback }));
42
57
  });
43
58
  }
44
59
  /**
@@ -48,7 +63,7 @@ export class UmbReadOnlyVariantGuardManager extends UmbReadOnlyGuardManager {
48
63
  * @memberof UmbReadOnlyVariantGuardManager
49
64
  */
50
65
  getIsPermittedForVariant(variantId) {
51
- return this.#resolvePermission(this.getRules(), variantId);
66
+ return this.#resolvePermission(this.getRules(), variantId) ?? this._getFallback();
52
67
  }
53
68
  #resolvePermission(rules, variantId) {
54
69
  if (rules.filter((x) => x.permitted === false).some((rule) => findRule(rule, variantId))) {
@@ -57,6 +72,6 @@ export class UmbReadOnlyVariantGuardManager extends UmbReadOnlyGuardManager {
57
72
  if (rules.filter((x) => x.permitted === true).some((rule) => findRule(rule, variantId))) {
58
73
  return true;
59
74
  }
60
- return this._fallback;
75
+ return undefined;
61
76
  }
62
77
  }
@@ -5,6 +5,10 @@ export declare const UMB_INVARIANT_CULTURE = "invariant";
5
5
  * The identifier is not specific for ContentType Variants, but is used for many type of identification of a culture and a segment. One case is any property of a ContentType can be resolved into a VariantId depending on their structural settings such as Vary by Culture and Vary by Segmentation.
6
6
  */
7
7
  export declare class UmbVariantId {
8
+ /**
9
+ * A frozen instance of the UmbVariantId class representing the invariant variant, meaning it has no culture and no segment.
10
+ */
11
+ static readonly INVARIANT: Readonly<UmbVariantId>;
8
12
  static Create(variantData: UmbObjectWithVariantProperties): UmbVariantId;
9
13
  static CreateFromPartial(variantData: Partial<UmbObjectWithVariantProperties>): UmbVariantId;
10
14
  static CreateInvariant(): UmbVariantId;
@@ -4,6 +4,10 @@ export const UMB_INVARIANT_CULTURE = 'invariant';
4
4
  * The identifier is not specific for ContentType Variants, but is used for many type of identification of a culture and a segment. One case is any property of a ContentType can be resolved into a VariantId depending on their structural settings such as Vary by Culture and Vary by Segmentation.
5
5
  */
6
6
  export class UmbVariantId {
7
+ /**
8
+ * A frozen instance of the UmbVariantId class representing the invariant variant, meaning it has no culture and no segment.
9
+ */
10
+ static { this.INVARIANT = Object.freeze(new UmbVariantId(null, null)); }
7
11
  static Create(variantData) {
8
12
  return Object.freeze(new UmbVariantId(variantData.culture, variantData.segment));
9
13
  }
@@ -11,7 +15,7 @@ export class UmbVariantId {
11
15
  return Object.freeze(new UmbVariantId(variantData.culture, variantData.segment));
12
16
  }
13
17
  static CreateInvariant() {
14
- return Object.freeze(new UmbVariantId(null, null));
18
+ return UmbVariantId.INVARIANT;
15
19
  }
16
20
  static FromString(str) {
17
21
  const firstUnderscoreIndex = str.indexOf('_');
@@ -5,9 +5,9 @@ import type { UmbSubmitWorkspaceActionArgs } from './types.js';
5
5
  import type { UmbControllerHost } from '../../../../../../../libs/controller-api/index.js';
6
6
  export declare class UmbSubmitWorkspaceAction<ArgsMetaType extends MetaWorkspaceAction = MetaWorkspaceAction, WorkspaceContextType extends UmbSubmittableWorkspaceContext = UmbSubmittableWorkspaceContext> extends UmbWorkspaceActionBase<ArgsMetaType> {
7
7
  #private;
8
- protected _retrieveWorkspaceContext: Promise<unknown>;
8
+ protected _retrieveWorkspaceContext?: Promise<unknown>;
9
9
  protected _workspaceContext?: WorkspaceContextType;
10
10
  constructor(host: UmbControllerHost, args: UmbSubmitWorkspaceActionArgs<ArgsMetaType>);
11
11
  protected _gotWorkspaceContext(): void;
12
- execute(): Promise<void>;
12
+ execute(): Promise<void | undefined>;
13
13
  }
@@ -8,10 +8,16 @@ export class UmbSubmitWorkspaceAction extends UmbWorkspaceActionBase {
8
8
  this._workspaceContext = context;
9
9
  this.#observeUnique();
10
10
  this._gotWorkspaceContext();
11
- }).asPromise();
11
+ })
12
+ .asPromise()
13
+ .catch(() => {
14
+ return undefined;
15
+ });
12
16
  }
13
17
  #observeUnique() {
14
18
  this.observe(this._workspaceContext?.unique, (unique) => {
19
+ if (!this._workspaceContext)
20
+ return;
15
21
  // We can't save if we don't have a unique
16
22
  if (unique === undefined) {
17
23
  this.disable();
@@ -27,6 +33,6 @@ export class UmbSubmitWorkspaceAction extends UmbWorkspaceActionBase {
27
33
  }
28
34
  async execute() {
29
35
  await this._retrieveWorkspaceContext;
30
- return await this._workspaceContext.requestSubmit();
36
+ return await this._workspaceContext?.requestSubmit();
31
37
  }
32
38
  }
@@ -13,7 +13,7 @@ import { UmbDataPathVariantQuery, umbBindToValidation } from '../../../validatio
13
13
  import { UMB_PROPERTY_DATASET_CONTEXT, isNameablePropertyDatasetContext } from '../../../property/index.js';
14
14
  import { UUIInputEvent } from '../../../../../external/uui/index.js';
15
15
  import { UMB_HINT_CONTEXT } from '../../../hint/index.js';
16
- import { observeMultiple } from '../../../../../libs/observable-api/index.js';
16
+ import { createObservablePart, observeMultiple } from '../../../../../libs/observable-api/index.js';
17
17
  let UmbWorkspaceSplitViewVariantSelectorElement = class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement {
18
18
  #splitViewContext;
19
19
  #datasetContext;
@@ -46,8 +46,8 @@ let UmbWorkspaceSplitViewVariantSelectorElement = class UmbWorkspaceSplitViewVar
46
46
  const workspaceContext = this.#splitViewContext?.getWorkspaceContext();
47
47
  this.#observeVariants(workspaceContext);
48
48
  this.#observeActiveVariants(workspaceContext);
49
+ this.#observeReadOnlyCultures(workspaceContext);
49
50
  this.#observeCurrentVariant();
50
- this.#observeReadOnlyGuardRules(workspaceContext);
51
51
  this.observe(workspaceContext?.variesBySegment, (value) => (this._variesBySegment = value ?? false), 'umbObserveVariesBySegment');
52
52
  this.observe(workspaceContext?.variesByCulture, (value) => (this._variesByCulture = value ?? false), 'umbObserveVariesByCulture');
53
53
  });
@@ -79,7 +79,6 @@ let UmbWorkspaceSplitViewVariantSelectorElement = class UmbWorkspaceSplitViewVar
79
79
  this.observe(workspaceContext?.variantOptions, (variantOptions) => {
80
80
  this._variantOptions = (variantOptions ?? []).sort(this._variantSorter);
81
81
  this._cultureVariantOptions = this._variantOptions.filter((variant) => variant.segment === null);
82
- this.#setReadOnlyCultures(workspaceContext);
83
82
  }, '_observeVariantOptions');
84
83
  if (workspaceContext) {
85
84
  this.observe(observeMultiple([
@@ -122,9 +121,6 @@ let UmbWorkspaceSplitViewVariantSelectorElement = class UmbWorkspaceSplitViewVar
122
121
  this._activeVariant = option;
123
122
  }, 'umbObserveActiveVariant');
124
123
  }
125
- #observeReadOnlyGuardRules(workspaceContext) {
126
- this.observe(workspaceContext?.readOnlyGuard.rules, () => this.#setReadOnlyCultures(workspaceContext), 'umbObserveReadOnlyGuardRules');
127
- }
128
124
  #handleInput(event) {
129
125
  if (event instanceof UUIInputEvent) {
130
126
  const target = event.composedPath()[0];
@@ -158,14 +154,15 @@ let UmbWorkspaceSplitViewVariantSelectorElement = class UmbWorkspaceSplitViewVar
158
154
  }
159
155
  return this._variantOptions.length > 1;
160
156
  }
161
- #setReadOnlyCultures(workspaceContext) {
157
+ #observeReadOnlyCultures(workspaceContext) {
162
158
  if (workspaceContext) {
163
- this._readOnlyCultures = this._variantOptions
164
- .filter((variant) => workspaceContext.readOnlyGuard.getIsPermittedForVariant(UmbVariantId.Create(variant)))
165
- .map((variant) => variant.culture);
159
+ this.observe(workspaceContext.readOnlyGuard.isPermittedForObservableVariants(createObservablePart(workspaceContext.variantOptions, (options) => options.map((option) => UmbVariantId.Create(option)))), (permitted) => {
160
+ this._readOnlyCultures = permitted.filter((p) => p.permitted === true).map((p) => p.variantId.culture);
161
+ }, '_observeReadOnlyCultures');
166
162
  }
167
163
  else {
168
164
  this._readOnlyCultures = [];
165
+ this.removeUmbControllerByAlias('_observeReadOnlyCultures');
169
166
  }
170
167
  }
171
168
  #onPopoverToggle(event) {
@@ -1,7 +1,10 @@
1
+ import { mergeObservables } from '../../../../libs/observable-api/index.js';
1
2
  import { UmbGuardManagerBase } from '../../utils/index.js';
2
3
  export class UmbNameWriteGuardManager extends UmbGuardManagerBase {
3
4
  isPermittedForName() {
4
- return this._rules.asObservablePart((rules) => this.#resolvePermission(rules));
5
+ return mergeObservables([this.rules, this._fallback], ([rules, fallback]) => {
6
+ return this.#resolvePermission(rules) ?? fallback;
7
+ });
5
8
  }
6
9
  #resolvePermission(rules) {
7
10
  if (rules.some((rule) => rule.permitted === false)) {
@@ -10,6 +13,6 @@ export class UmbNameWriteGuardManager extends UmbGuardManagerBase {
10
13
  if (rules.some((rule) => rule.permitted === true)) {
11
14
  return true;
12
15
  }
13
- return this._fallback;
16
+ return undefined;
14
17
  }
15
18
  }
@@ -1,11 +1,9 @@
1
- import { type PropertyValueMap } from '../../../external/lit/index.js';
2
1
  import { UmbLitElement } from '../lit-element/index.js';
3
2
  export declare class UmbWorkspaceElement extends UmbLitElement {
4
3
  #private;
5
4
  private _component?;
6
5
  get entityType(): string | undefined;
7
6
  set entityType(value: string);
8
- protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
9
7
  render(): HTMLElement | import("lit-html").TemplateResult<1>;
10
8
  }
11
9
  export { UmbWorkspaceElement as element };
@@ -24,14 +24,11 @@ let UmbWorkspaceElement = class UmbWorkspaceElement extends UmbLitElement {
24
24
  this.#entityType = value;
25
25
  this.#createController(value);
26
26
  }
27
- firstUpdated(_changedProperties) {
28
- super.firstUpdated(_changedProperties);
29
- this.setAttribute(UMB_MARK_ATTRIBUTE_NAME, 'workspace');
30
- }
31
27
  #createController(entityType) {
32
28
  if (this.#extensionsController) {
33
29
  this.#extensionsController.destroy();
34
30
  }
31
+ this.setAttribute(UMB_MARK_ATTRIBUTE_NAME, 'workspace:' + entityType);
35
32
  this.#extensionsController = new UmbExtensionsElementAndApiInitializer(this, umbExtensionsRegistry, 'workspace', apiArgsCreator, (manifest) => manifest.meta.entityType === entityType, (extensionControllers) => {
36
33
  this._component = extensionControllers[0]?.component;
37
34
  const api = extensionControllers[0]?.api;
@@ -1,11 +1,12 @@
1
1
  import { UMB_DOCUMENT_TYPE_PROPERTY_TYPE_ENTITY_TYPE } from './entity.js';
2
+ import { UmbDocumentTypePropertyTypeReferenceResponseManagementApiDataMapping } from './document-type-property-type-reference-response.management-api.mapping.js';
2
3
  import { UMB_MANAGEMENT_API_DATA_SOURCE_ALIAS } from '../../../core/repository/index.js';
3
4
  export const manifests = [
4
5
  {
5
6
  type: 'dataSourceDataMapping',
6
7
  alias: 'Umb.DataSourceDataMapping.ManagementApi.DocumentTypePropertyTypeReferenceResponse',
7
8
  name: 'Document Type Property Type Reference Response Management Api Data Mapping',
8
- api: () => import('./document-type-property-type-reference-response.management-api.mapping.js'),
9
+ api: UmbDocumentTypePropertyTypeReferenceResponseManagementApiDataMapping,
9
10
  forDataSource: UMB_MANAGEMENT_API_DATA_SOURCE_ALIAS,
10
11
  forDataModel: 'DocumentTypePropertyTypeReferenceResponseModel',
11
12
  },
@@ -1,4 +1,5 @@
1
1
  import { UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS } from './constants.js';
2
+ import { UmbDocumentReferenceResponseManagementApiDataMapping } from './document-reference-response.management-api.mapping.js';
2
3
  import { UMB_MANAGEMENT_API_DATA_SOURCE_ALIAS } from '../../../../core/repository/index.js';
3
4
  export const manifests = [
4
5
  {
@@ -11,7 +12,7 @@ export const manifests = [
11
12
  type: 'dataSourceDataMapping',
12
13
  alias: 'Umb.DataSourceDataMapping.ManagementApi.DocumentReferenceResponse',
13
14
  name: 'Document Reference Response Management Api Data Mapping',
14
- api: () => import('./document-reference-response.management-api.mapping.js'),
15
+ api: UmbDocumentReferenceResponseManagementApiDataMapping,
15
16
  forDataSource: UMB_MANAGEMENT_API_DATA_SOURCE_ALIAS,
16
17
  forDataModel: 'DocumentReferenceResponseModel',
17
18
  },
@@ -8,6 +8,8 @@ export class UmbDocumentPropertyValueUserPermissionCondition extends UmbConditio
8
8
  super(host, args);
9
9
  this.consumeContext(UMB_CURRENT_USER_CONTEXT, (context) => {
10
10
  this.observe(context?.currentUser, (currentUser) => {
11
+ if (!currentUser)
12
+ return;
11
13
  this.#documentPropertyValuePermissions =
12
14
  currentUser?.permissions?.filter(isDocumentPropertyValueUserPermission) || [];
13
15
  this.#fallbackPermissions = currentUser?.fallbackPermissions || [];