diff --git a/src/FluentCMS.Admin/Components/Forms/FieldWidget.razor b/src/FluentCMS.Admin/Components/Forms/FieldWidget.razor index 74d2db178..3747582e8 100644 --- a/src/FluentCMS.Admin/Components/Forms/FieldWidget.razor +++ b/src/FluentCMS.Admin/Components/Forms/FieldWidget.razor @@ -26,11 +26,11 @@ break; case "richText": - + break; case "list": case "json": - + break; case "number": @@ -48,7 +48,15 @@ break; default: - + @* A single-line input drops line breaks, so a text that has them is shown where they survive the post. *@ + @if (Value?.IndexOfAny(['\n', '\r']) >= 0) + { + + } + else + { + + } break; } @@ -72,6 +80,9 @@ private bool Wide => Field.Type is "richText" or "list" or "json"; + // HTML drops one line break right after a textarea's start tag, so a value that starts with one gets another to lose. + private string? TextareaValue => Value is ['\n', ..] or ['\r', ..] ? "\n" + Value : Value; + private int? MaxLength => Field.Settings.ValueKind == System.Text.Json.JsonValueKind.Object && Field.Settings.TryGetProperty("maxLength", out var max) && max.TryGetInt32(out var length) diff --git a/src/FluentCMS.Admin/Components/Forms/PickerField.razor b/src/FluentCMS.Admin/Components/Forms/PickerField.razor index 1acd12c78..333be49fc 100644 --- a/src/FluentCMS.Admin/Components/Forms/PickerField.razor +++ b/src/FluentCMS.Admin/Components/Forms/PickerField.razor @@ -41,7 +41,7 @@ @oninput="SearchAsync" @onkeydown="OnKeyDown" placeholder="@(Kind == MediaKind ? L["Search by file name or folder"] : L["Search by name"])" - aria-controls="@ListId" + aria-controls="@(_hits.Count > 0 ? ListId : null)" aria-autocomplete="list" data-ui="rove-input" data-field="@Field" /> diff --git a/src/FluentCMS.Admin/Components/Pages/EntryEditor.razor b/src/FluentCMS.Admin/Components/Pages/EntryEditor.razor index 80c089855..7411f9cec 100644 --- a/src/FluentCMS.Admin/Components/Pages/EntryEditor.razor +++ b/src/FluentCMS.Admin/Components/Pages/EntryEditor.razor @@ -34,9 +34,41 @@ {
@L["An entity type: every field is a fact with its source, owner and validity."]
} + @if (_entry is { State: EntryState.Reverted, PublishedVersion: null } revertedCreate) + { ++ @L["The form shows version {0}, whose creation was reverted. Nothing of this entry is published; saving proposes it again.", revertedCreate.LatestVersion] +
+ } + @if (_entry is { PublishedVersion: { } published } entry && entry.LatestVersion != published && entry.State != EntryState.InReview) + { ++ @if (FromPublished) + { + @L["The form shows the published version {0}. The latest draft, version {1}, is not published; saving proposes this version's values with your changes.", published, entry.LatestVersion] + @L["Show the latest draft"] + } + else if (entry.State == EntryState.Reverted) + { + @L["The form shows the reverted draft, version {0}. Version {1} is published.", entry.LatestVersion, published] + @L["Start from the published version"] + } + else + { + @L["The form shows the latest draft, version {0}, which is not published; a rejected change can leave such a draft. Version {1} is published.", entry.LatestVersion, published] + @L["Start from the published version"] + } +
+ }