Skip to content

Commit 2e2f1a4

Browse files
committed
Merge branch 'main' into cms/new-date-time-property-editors
2 parents 48bbf54 + 67fda89 commit 2e2f1a4

File tree

111 files changed

+1280
-867
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+1280
-867
lines changed

.lycheeignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
^https://github\.com/Shazwazza/Articulate/blob/.*/.*#L.*
99
^https://github\.com/umbraco/Umbraco-CMS/blob/.*
1010
^https://github\.com/.*/issues/[0-9]+#issuecomment-[0-9]+
11+
^https://github\.com/umbraco/.*/discussions/.*
1112

1213
# Anchor/fragment links causing false positives
1314
^https://apidocs\.umbraco\.com/.*/#.*
@@ -20,6 +21,7 @@
2021
^https://nginx\.org/.*/#.*
2122
^https://azure\.microsoft\.com/en-gb/services/media-services/.*
2223
^https://www\.tiny\.cloud/docs/.*
24+
^https://api\.cloud\.umbraco\.com/?$
2325

2426
# TinyMCE anchors
2527
^https://github\.com/tinymce/tinymce/issues/.*#.*
@@ -30,3 +32,6 @@
3032
# Timeout-prone Umbraco issue links
3133
^https://issues\.umbraco\.org/issue/.*
3234
^https://issues\.umbraco\.org/issues/.*
35+
36+
# Ignore specific troubleshooting anchor as Lychee is stripping special characters and replacing spaces with hyphens
37+
^file:///home/runner/work/UmbracoDocs/UmbracoDocs/umbraco-cloud/build-and-customize-your-solution/handle-deployments-and-environments/umbraco-cicd/troubleshooting.md#unable-to-determine-environment-by-its-environment-id

13/umbraco-workflow/workflow-section/approval-groups.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ This feature is useful where the approval group membership is a single user who
4444

4545
Offline approval requires a user to exist in the Backoffice and be assigned to a workflow group. They do not need to know how to use Umbraco or even know their login credentials.
4646

47+
{% hint style="info" %}
48+
Offline approval can not be used when the approval group has a group email set.
49+
{% endhint %}
50+
4751
## Roles
4852

4953
The **Roles** tab provides an overview of the current workflow roles for the Group:
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
description: Ask the user for confirmation
3+
---
4+
5+
# Confirm Dialog
6+
7+
This example shows how to open a confirm dialog. The `UMB_CONFIRM_MODAL` is a token that represents the confirm dialog. The `open` method takes the token and an object with the data for the confirm dialog. The `onSubmit` method returns a promise that resolves when the user confirms the dialog and rejects when the user cancels the dialog.
8+
9+
The confirm modal itself is built-in and does not need to be registered in the extension registry.
10+
11+
The modal token describes the options that you can pass to the modal. The confirm modal token has the following properties:
12+
13+
* `headline` - The headline of the modal.
14+
* `content` - The content of the modal, which can be a TemplateResult or a string.
15+
* `color` - (Optional) The color of the modal. This can be `positive` or `danger`.
16+
* `confirmLabel` - (Optional) The label of the confirm button.
17+
18+
## Basic Usage
19+
20+
{% code title="my-element.ts" %}
21+
```typescript
22+
import { html, LitElement, customElement } from "@umbraco-cms/backoffice/external/lit";
23+
import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
24+
import { UMB_MODAL_MANAGER_CONTEXT, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal';
25+
26+
@customElement('my-element')
27+
export class MyElement extends UmbElementMixin(LitElement) {
28+
29+
30+
async #onRequestDisable() {
31+
const context = await this.getContext(UMB_MODAL_MANAGER_CONTEXT)
32+
33+
const modal = context?.open(
34+
this, UMB_CONFIRM_MODAL,
35+
{
36+
data: {
37+
headline: `#actions_disable`,
38+
content: `#defaultdialogs_confirmdisable`,
39+
color: "danger",
40+
confirmLabel: "Disable",
41+
}
42+
}
43+
);
44+
45+
modal?.onSubmit()
46+
.then(() => {
47+
console.log("User has approved");
48+
})
49+
.catch(() => {
50+
console.log("User has rejected");
51+
});
52+
}
53+
54+
render() {
55+
return html`<uui-button
56+
look="primary"
57+
color="danger"
58+
@click=${this.#onRequestDisable}
59+
label=${this.localize.term("actions_disable")}></uui-button>`;
60+
}
61+
}
62+
```
63+
{% endcode %}

15/umbraco-cms/SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,10 @@
217217
* [Property Editor Schema](customizing/property-editors/composition/property-editor-schema.md)
218218
* [Property Editor UI](customizing/property-editors/composition/property-editor-ui.md)
219219
* [Property Value Converters](customizing/property-editors/property-value-converters.md)
220+
* [Property Value Converter Example](customizing/property-editors/full-examples-value-converters.md)
220221
* [Property Actions](customizing/property-editors/property-actions.md)
221222
* [Integrate Property Editors](customizing/property-editors/integrate-property-editors.md)
222223
* [Tracking References](customizing/property-editors/tracking.md)
223-
* [Content Picker Value Converter Example](customizing/property-editors/full-examples-value-converters.md)
224224
* [Property Dataset](customizing/property-editors/property-dataset.md)
225225
* [Workspaces](customizing/workspaces.md)
226226
* [Umbraco Package](customizing/umbraco-package.md)
Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Content Picker Value Converter Example
1+
# Property Value Converter full example
2+
This page includes an example of a complete Property Value Converter. The example is that of a Property Value Converter for a Content Picker, where the user picks a node from the Umbraco tree.
23

3-
{% include "../../.gitbook/includes/obsolete-warning-snapshot-publishedcache.md" %}
44

55
{% code title="ContentPickerPropertyConverter.cs" %}
66

@@ -12,44 +12,56 @@ using Umbraco.Cms.Core.PublishedCache;
1212

1313
namespace UmbracoDocs.Samples;
1414

15-
public class ContentPickerPropertyConverter : IPropertyValueConverter
15+
// Injecting the IPublishedContentCache for fetching content from the Umbraco cache
16+
public class ContentPickerPropertyConverter(IPublishedContentCache publishedContentCache) : IPropertyValueConverter
1617
{
17-
private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
18-
19-
// Injecting the PublishedSnapshotAccessor for fetching content
20-
public ContentPickerPropertyConverter(IPublishedSnapshotAccessor publishedSnapshotAccessor)
21-
=> _publishedSnapshotAccessor = publishedSnapshotAccessor;
22-
18+
// Make sure the Property Value Converter only applies to the Content Picker property editor
2319
public bool IsConverter(IPublishedPropertyType propertyType)
24-
=> propertyType.EditorAlias.Equals("Umbraco.ContentPicker");
20+
=> propertyType.EditorAlias.Equals(Constants.PropertyEditors.Aliases.ContentPicker);
2521

22+
23+
// We consider the value to be a value only when we have the actual IPublishedContent object,
24+
// meaning that there is a valid picked content item.
2625
public bool? IsValue(object? value, PropertyValueLevel level)
2726
{
2827
return level switch
2928
{
30-
PropertyValueLevel.Source => value is string stringValue && string.IsNullOrWhiteSpace(stringValue) is false,
31-
_ => throw new NotSupportedException($"Invalid level: {level}.")
29+
PropertyValueLevel.Source => null,
30+
PropertyValueLevel.Inter => null,
31+
PropertyValueLevel.Object => value is IPublishedContent,
32+
_ => throw new ArgumentOutOfRangeException(nameof(level), level, $"Invalid level: {level}.")
3233
};
3334
}
3435

36+
// The type returned by this converter is IPublishedContent
37+
// And the Models Builder will take care of returning the actual generated type
3538
public Type GetPropertyValueType(IPublishedPropertyType propertyType)
3639
=> typeof(IPublishedContent);
3740

41+
// Because we have a reference to another content item, we need to use the Elements cache level,
42+
// to make sure that changes to the referenced item are detected and the cache invalidated accordingly.
3843
public PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
3944
=> PropertyCacheLevel.Elements;
4045

41-
public object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview)
42-
// parse the source string to a GuidUdi intermediate value
43-
=> source is string stringValue && UdiParser.TryParse(stringValue, out GuidUdi? guidUdi)
44-
? guidUdi
45-
: null;
46+
// Converts the source value (string) to an intermediate value (GuidUdi)
47+
public object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType,
48+
object? source, bool preview)
49+
{
50+
if (source is not string { Length: > 0 } stringValue)
51+
return null;
52+
53+
return UdiParser.TryParse(stringValue, out GuidUdi? guidUdi) ? guidUdi : null;
54+
}
4655

47-
public object? ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview)
48-
// inter is expected to be a GuidUdi at this point (see ConvertSourceToIntermediate)
56+
// Converts the intermediate value (GuidUdi) to the actual object value (IPublishedContent)
57+
public object? ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType,
58+
PropertyCacheLevel referenceCacheLevel, object? inter, bool preview)
4959
=> inter is GuidUdi guidUdi
50-
? _publishedSnapshotAccessor.GetRequiredPublishedSnapshot().Content?.GetById(guidUdi.Guid)
60+
? publishedContentCache.GetById(guidUdi.Guid)
5161
: null;
5262
}
63+
64+
5365
```
5466

5567
{% endcode %}

0 commit comments

Comments
 (0)