Skip to content

Commit f28a6c9

Browse files
committed
Merge branch 'release/4.6.0' into master
This is primarily a maintenance update focused on a number of under-the-hood improvements, such as adoption of C# 9.0, as well as some minor bug fixes related to the user interface, such as ensuring nested topics can be rolled back. Normally, this would be considered a patch (i.e., 4.5.1) since it contains no new features. We're sticking with 4.6.0, however, to align it with the corresponding release of OnTopic 4.6.0. Bug Fixes - Reset content type in `ContentTypeListViewComponent` when modal window is triggered (b6868cf) - Display `PermittedContentTypes` from parent topic on left rail when creating a new topic (9beeb8a) - Hide `DisableDelete` warning when creating new topics of protected content types (5ddbd26) - Allow rollback to previous versions of nested topics within large-window modals (780e7ed) - Ensure versions in version history don't wrap even when using long date/times (0072c55) Improvements - Updated code to use C# 9.0 pattern matching and implicitly typed initializers (4962a85) - Updated to latest versions of internal packages, including OnTopic 4.6.0 (dee88f0) - Updated to latest version of Code Analysis and fixed most issues introduced with C# 9.0 (11331ea)
2 parents 22b5f4f + dee88f0 commit f28a6c9

50 files changed

Lines changed: 395 additions & 216 deletions

File tree

Some content is hidden

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

OnTopic.Editor.AspNetCore.Host/OnTopic.Editor.AspNetCore.Host.csproj

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,21 @@
22

33
<PropertyGroup>
44
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<LangVersion>9.0</LangVersion>
56
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
67
<UserSecretsId>aff0d52c-eab2-4c07-88b2-5af34649f874</UserSecretsId>
78
</PropertyGroup>
89

910
<ItemGroup>
10-
<PackageReference Include="OnTopic" Version="4.5.0" />
11-
<PackageReference Include="OnTopic.ViewModels" Version="4.5.0" />
12-
<PackageReference Include="OnTopic.AspNetCore.Mvc" Version="4.5.0" />
13-
<PackageReference Include="OnTopic.Data.Caching" Version="4.5.0" />
14-
<PackageReference Include="OnTopic.Data.Sql" Version="4.5.0" />
11+
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.1">
12+
<PrivateAssets>all</PrivateAssets>
13+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
14+
</PackageReference>
15+
<PackageReference Include="OnTopic" Version="4.6.0" />
16+
<PackageReference Include="OnTopic.ViewModels" Version="4.6.0" />
17+
<PackageReference Include="OnTopic.AspNetCore.Mvc" Version="4.6.0" />
18+
<PackageReference Include="OnTopic.Data.Caching" Version="4.6.0" />
19+
<PackageReference Include="OnTopic.Data.Sql" Version="4.6.0" />
1520
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.8" />
1621
</ItemGroup>
1722

OnTopic.Editor.AspNetCore.Host/SampleActivator.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ public SampleActivator(string connectionString, IWebHostEnvironment webHostEnvir
8888
/// <returns>A concrete instance of an <see cref="IController"/>.</returns>
8989
public object Create(ControllerContext context) {
9090

91+
/*------------------------------------------------------------------------------------------------------------------------
92+
| Validate parameters
93+
\-----------------------------------------------------------------------------------------------------------------------*/
94+
Contract.Requires(context, nameof(context));
95+
9196
/*------------------------------------------------------------------------------------------------------------------------
9297
| Determine controller type
9398
\-----------------------------------------------------------------------------------------------------------------------*/
@@ -111,6 +116,11 @@ public object Create(ControllerContext context) {
111116
/// <returns>A concrete instance of an <see cref="IController"/>.</returns>
112117
public object Create(ViewComponentContext context) {
113118

119+
/*------------------------------------------------------------------------------------------------------------------------
120+
| Validate parameters
121+
\-----------------------------------------------------------------------------------------------------------------------*/
122+
Contract.Requires(context, nameof(context));
123+
114124
/*------------------------------------------------------------------------------------------------------------------------
115125
| Determine view component type
116126
\-----------------------------------------------------------------------------------------------------------------------*/

OnTopic.Editor.AspNetCore/Areas/Editor/Views/Editor/Components/ContentTypeList/Default.cshtml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@model ContentTypeListViewModel
22

3-
@if (Model.TopicList.Count == 1) {
3+
@if (Model.TopicList.Count is 1) {
44
<!-- New topics are not permitted in this context -->
55
}
66

@@ -20,7 +20,9 @@ else if (Model.TopicList.Count > 2) {
2020
var option = $('option:selected', this);
2121
@if (Model.EnableModal?? false) {
2222
<text>
23-
initEditorModal('@Model.AttributeKey', option.text(), option.val(), @Model.OnModalClose); return false;
23+
initEditorModal('@Model.AttributeKey', option.text(), option.val(), @Model.OnModalClose);
24+
$(this).prop('selectedIndex', 0);
25+
return false;
2426
</text>
2527
}
2628
else {
@@ -37,7 +39,7 @@ else if (Model.TopicList.Count > 2) {
3739

3840
else {
3941
<div class="ChildTopic">
40-
@if (Model.EnableModal == true) {
42+
@if (Model.EnableModal is true) {
4143
<a onclick="initEditorModal('@Model.AttributeKey', '@Model.TopicList.LastOrDefault().Text', '@Model.TopicList.LastOrDefault().Value', @Model.OnModalClose); return false;" class="btn btn-info btn-sm">
4244
<span class="fa fa-plus"></span>
4345
@Model.TopicList.LastOrDefault().Text

OnTopic.Editor.AspNetCore/Areas/Editor/Views/Editor/Edit.cshtml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<div id="FormArea" class="row form area">
2121

2222
<div class="col-md-12">
23-
@if (Model.ContentTypeDescriptor.DisableDelete) {
23+
@if (Model.ContentTypeDescriptor.DisableDelete && !Model.IsNew) {
2424
<div class="alert alert-warning" role="alert">
2525
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
2626
<strong>Warning:</strong> This topic is part of the OnTopic internal organizational structure and is not intended to be modified. Deletion of this Topic has been disabled.
@@ -31,7 +31,7 @@
3131
@Model.ContentTypeDescriptor.Description
3232
</div>
3333
}
34-
@if (Model.Topic.DerivedTopic != null) {
34+
@if (Model.Topic.DerivedTopic is not null) {
3535
<div class="alert alert-primary" role="alert">
3636
<strong>Note:</strong> This topic derives from <a href="@Url.Action("Edit", new { path = Model.Topic.DerivedTopic.WebPath })">@Model.Topic.DerivedTopic.Title</a>. Any values not explicitly defined here will be inherited from that topic.
3737
</div>
@@ -46,7 +46,7 @@
4646

4747
var displayGroupId = displayGroupName.Replace(" ", String.Empty);
4848

49-
<div id="Group_@displayGroupId" class="tab-pane fade@(index == 0 ? " show active" : "")" role="tabpanel" aria-labelledby="Tab_@displayGroupId">
49+
<div id="Group_@displayGroupId" class="tab-pane fade@(index is 0 ? " show active" : "")" role="tabpanel" aria-labelledby="Tab_@displayGroupId">
5050
<section id="Section_@displayGroupId">
5151

5252
@foreach (var attribute in Model.ContentTypeDescriptor.GetAttributeDescriptors(displayGroupName)) {
@@ -105,7 +105,7 @@
105105
}
106106
});
107107

108-
@if (Model.Topic.DerivedTopic != null) {
108+
@if (Model.Topic.DerivedTopic is not null) {
109109
<text>
110110
/**
111111
* Disable required fields if derived topic, as missing values will be inherited

OnTopic.Editor.AspNetCore/Areas/Editor/Views/Shared/_Toolbar.cshtml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111

1212
@if (Model.Topic.VersionHistory.Count > 1) {
1313
<!-- Versions -->
14-
<div id="VersionsDropdown" class="dropdown d-none d-lg-inline-block" style="display:inline-block;">
14+
<div id="VersionsDropdown" class="dropdown d-none d-md-inline-block" style="display:inline-block;">
1515
<button class="btn btn-sm btn-ancillary dropdown-toggle" type="button" id="VersionsButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
1616
<span class="fa fa-history"></span>
1717
Versions
1818
<span class="caret"></span>
1919
</button>
20-
<ul class="dropdown-menu" role="menu" aria-labelledby="VersionsButton" style="left: 3px; top: 98%;">
20+
<ul class="dropdown-menu" role="menu" aria-labelledby="VersionsButton">
2121
@foreach (DateTime version in Model.Topic.VersionHistory) {
2222
<li role="presentation" class="small">
2323
<a tabindex="-1" role="menuitem" href="@Url.Action("SetVersion", "Editor", new { path=Model.Topic.WebPath, version=version.ToString("MM/dd/yyyy hh:mm:ss.fff tt"), isModal=Model.IsModal })">@version.ToString()</a>
@@ -64,7 +64,7 @@
6464
var displayGroupName = displayGroups[i];
6565
var displayGroupId = displayGroups[i].Replace(" ", String.Empty);
6666
<li class="nav-item">
67-
<a id="Tab_@displayGroupId" class="nav-link @(i == 0 ? "active" : "")" href="#Group_@displayGroupId" data-toggle="tab" role="tab" aria-controls="#Group_@displayGroupId" aria-expanded="@(i == 0 ? "true" : "false")">@displayGroupName</a>
67+
<a id="Tab_@displayGroupId" class="nav-link @(i is 0 ? "active" : "")" href="#Group_@displayGroupId" data-toggle="tab" role="tab" aria-controls="#Group_@displayGroupId" aria-expanded="@(i is 0 ? "true" : "false")">@displayGroupName</a>
6868
</li>
6969
}
7070
</ul>

OnTopic.Editor.AspNetCore/Components/ContentTypeListViewComponent.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using OnTopic.Editor.AspNetCore.Models;
1313
using OnTopic.Editor.Models;
1414
using OnTopic.Editor.Models.Metadata;
15+
using OnTopic.Internal.Diagnostics;
1516
using OnTopic.Repositories;
1617

1718
namespace OnTopic.Editor.AspNetCore.Components {
@@ -58,6 +59,11 @@ public IViewComponentResult Invoke(
5859
string onModalClose = null
5960
) {
6061

62+
/*------------------------------------------------------------------------------------------------------------------------
63+
| Validate parameters
64+
\-----------------------------------------------------------------------------------------------------------------------*/
65+
Contract.Requires(currentTopic, nameof(currentTopic));
66+
6167
/*------------------------------------------------------------------------------------------------------------------------
6268
| Establish view model
6369
\-----------------------------------------------------------------------------------------------------------------------*/
@@ -72,7 +78,7 @@ public IViewComponentResult Invoke(
7278
| Set label
7379
\-----------------------------------------------------------------------------------------------------------------------*/
7480
viewModel.TopicList.Add(
75-
new SelectListItem {
81+
new() {
7682
Value = null,
7783
Text = "Add a child topic…"
7884
}
@@ -83,7 +89,7 @@ public IViewComponentResult Invoke(
8389
\-----------------------------------------------------------------------------------------------------------------------*/
8490
foreach (var contentType in values.OrderBy(c => c.Title)) {
8591
viewModel.TopicList.Add(
86-
new SelectListItem {
92+
new() {
8793
Value = getValue(contentType.Key),
8894
Text = contentType.Title
8995
}
@@ -94,13 +100,14 @@ public IViewComponentResult Invoke(
94100
| Get content type
95101
>-------------------------------------------------------------------------------------------------------------------------
96102
| If the database is uninitialized, the content type won't be found. In that case, return an empty view, which will
97-
| effectively hide the component.
103+
| effectively hide the component. If the topic cannot be found, assume it is a new topic and attempt to load the parent
104+
| for context.
98105
\-----------------------------------------------------------------------------------------------------------------------*/
99106
var contentTypes = _topicRepository.GetContentTypeDescriptors();
100-
var actualTopic = _topicRepository.Load(currentTopic.Id);
107+
var actualTopic = _topicRepository.Load(currentTopic.Id)?? _topicRepository.Load(currentTopic.Parent.Id);
101108
var actualContentType = contentTypes.GetTopic(currentTopic.ContentType);
102109

103-
if (actualContentType == null) {
110+
if (actualContentType is null || actualTopic is null) {
104111
return View(viewModel);
105112
}
106113

@@ -118,7 +125,7 @@ public IViewComponentResult Invoke(
118125
.Relationships
119126
.GetTopics("ContentTypes")
120127
.Select(c =>
121-
new SelectListItem {
128+
new SelectListItem() {
122129
Value = getValue(c.Key),
123130
Text = c.Title
124131
}
@@ -136,7 +143,7 @@ public IViewComponentResult Invoke(
136143
| content types explicitly annotated as "implicitly permitted", and which are not marked as hidden are displayed. This
137144
| typically include the Page content type, and popular derivatives of it, such as Content List.
138145
\-----------------------------------------------------------------------------------------------------------------------*/
139-
if (viewModel.TopicList.Count.Equals(1) && !actualContentType.DisableChildTopics) {
146+
if (viewModel.TopicList.Count is 1 && !actualContentType.DisableChildTopics) {
140147
viewModel.TopicList.AddRange(
141148
contentTypes
142149
.Where(c => actualContentType.Equals("Container") || c.Attributes.GetBoolean("ImplicitlyPermitted", false))

OnTopic.Editor.AspNetCore/Components/DateTimeViewComponent.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using OnTopic.Editor.Models;
88
using OnTopic.Editor.Models.Components.ViewModels;
99
using OnTopic.Editor.Models.Metadata;
10+
using OnTopic.Internal.Diagnostics;
1011

1112
namespace OnTopic.Editor.AspNetCore.Components {
1213

@@ -39,6 +40,12 @@ public IViewComponentResult Invoke(
3940
string htmlFieldPrefix
4041
) {
4142

43+
/*------------------------------------------------------------------------------------------------------------------------
44+
| Validate parameters
45+
\-----------------------------------------------------------------------------------------------------------------------*/
46+
Contract.Requires(currentTopic, nameof(currentTopic));
47+
Contract.Requires(attribute, nameof(attribute));
48+
4249
/*------------------------------------------------------------------------------------------------------------------------
4350
| Set HTML prefix
4451
\-----------------------------------------------------------------------------------------------------------------------*/

OnTopic.Editor.AspNetCore/Components/FileListViewComponent.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using OnTopic.Editor.AspNetCore.Models;
1313
using OnTopic.Editor.Models;
1414
using OnTopic.Editor.Models.Metadata;
15+
using OnTopic.Internal.Diagnostics;
1516

1617
#nullable enable
1718

@@ -52,6 +53,12 @@ public IViewComponentResult Invoke(
5253
string htmlFieldPrefix
5354
) {
5455

56+
/*------------------------------------------------------------------------------------------------------------------------
57+
| Validate parameters
58+
\-----------------------------------------------------------------------------------------------------------------------*/
59+
Contract.Requires(currentTopic, nameof(currentTopic));
60+
Contract.Requires(attribute, nameof(attribute));
61+
5562
/*------------------------------------------------------------------------------------------------------------------------
5663
| Set HTML prefix
5764
\-----------------------------------------------------------------------------------------------------------------------*/
@@ -73,7 +80,7 @@ string htmlFieldPrefix
7380
/*------------------------------------------------------------------------------------------------------------------------
7481
| Set model values
7582
\-----------------------------------------------------------------------------------------------------------------------*/
76-
model.Files = GetFiles(model.InheritedValue, attribute, model.AbsolutePath);
83+
model.Files.AddRange(GetFiles(model.InheritedValue, attribute, model.AbsolutePath));
7784
model.AbsolutePath = _webHostEnvironment.ContentRootPath + attribute.Path;
7885

7986
/*------------------------------------------------------------------------------------------------------------------------
@@ -95,6 +102,11 @@ public static List<SelectListItem> GetFiles(
95102
string absolutePath
96103
) {
97104

105+
/*------------------------------------------------------------------------------------------------------------------------
106+
| Validate parameters
107+
\-----------------------------------------------------------------------------------------------------------------------*/
108+
Contract.Requires(attribute, nameof(attribute));
109+
98110
/*------------------------------------------------------------------------------------------------------------------------
99111
| INSTANTIATE OBJECTS
100112
\-----------------------------------------------------------------------------------------------------------------------*/
@@ -111,14 +123,14 @@ string absolutePath
111123
/*------------------------------------------------------------------------------------------------------------------------
112124
| Filter file list based on extension
113125
\-----------------------------------------------------------------------------------------------------------------------*/
114-
if (attribute.Extension != null) {
126+
if (attribute.Extension is not null) {
115127
searchPattern = searchPattern + "." + attribute.Extension;
116128
}
117129

118130
/*------------------------------------------------------------------------------------------------------------------------
119131
| Filter file list based on filter criteria
120132
\-----------------------------------------------------------------------------------------------------------------------*/
121-
if (attribute.Filter != null) {
133+
if (attribute.Filter is not null) {
122134
searchPattern = attribute.Filter + searchPattern;
123135
}
124136

@@ -128,12 +140,12 @@ string absolutePath
128140
var foundFiles = Directory.GetFiles(absolutePath, searchPattern, searchOption);
129141

130142
if (!String.IsNullOrEmpty(inheritedValue)) {
131-
files.Add(new SelectListItem("", inheritedValue));
143+
files.Add(new("", inheritedValue));
132144
}
133145
foreach (var foundFile in foundFiles) {
134146
var fileName = foundFile.Replace(absolutePath, "");
135147
var fileNameKey = fileName.Replace("." + attribute.Extension, "");
136-
files.Add(new SelectListItem(fileNameKey, fileName));
148+
files.Add(new(fileNameKey, fileName));
137149
}
138150

139151
/*------------------------------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)