Skip to content

Commit

Permalink
Tab support for admin / content edit (OrchardCMS#3626)
Browse files Browse the repository at this point in the history
  • Loading branch information
deanmarcussen authored and sethcleaver committed Aug 12, 2019
1 parent 4272e54 commit 6f5c6b9
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@using OrchardCore.Mvc.Utilities;
@{
var tabs = ((IEnumerable<dynamic>)Model.Tabs).ToArray();
string contentItemId = Model.ContentItem != null ? (string)Model.ContentItem.ContentItemId : "";
}
@if (tabs.Any())
{
var tabIndex = 0;
<ul class="nav nav-tabs flex-column flex-md-row" role="tablist">
@foreach (var tab in tabs)
{
var tabText = tab.ToString();
var defaultTabId = $"tab-{contentItemId}-{tabText}".HtmlClassify();
var tabId = tab is string ? defaultTabId : (string)(tab.TabName ?? defaultTabId);
var tabCssClasses = tabIndex == 0 ? "nav-item nav-link active" : "nav-item nav-link";
var itemCssClasses = tabIndex == tabs.Length -1 ? "nav-item" : "nav-item pr-md-2";
<li class="@itemCssClasses">
<a class="@tabCssClasses" href="#@tabId" data-toggle="tab" role="tab" aria-controls="@tabId" aria-selected="false">@tabText</a>
</li>
tabIndex++;
}
</ul>
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
@*@using OrchardCore.Shapes*@
@*@{
var tabs = (IEnumerable<string>)CoreShapes.HarvestAndSortTabs(Model.Content);
Display.LocalNavigation(Tabs: tabs);
}*@
@using OrchardCore.DisplayManagement.Zones
@{
var tabs = (IEnumerable<string>)ZoneShapes.HarvestAndSortTabs(Model.Parts);
}

<style asp-src="~/OrchardCore.Contents/Styles/Contents.min.css" debug-src="~/OrchardCore.Contents/Styles/Contents.css"></style>

Expand All @@ -17,6 +16,10 @@
}
</div>
<div class="edit-item-parts">
@if (tabs.Any())
{
@await DisplayAsync(await New.LocalNavigation(ContentItem: Model.ContentItem, Tabs: tabs))
}
@if (Model.Parts != null)
{
@await DisplayAsync(Model.Parts)
Expand All @@ -38,13 +41,13 @@
</div>
</div>
</div>
@if (Model.Sidebar != null)
{
<div class="edit-sidebar-handler"></div>
<div class="edit-sidebar group">
@await DisplayAsync(Model.Sidebar)
</div>
}
@if (Model.Sidebar != null)
{
<div class="edit-sidebar-handler"></div>
<div class="edit-sidebar group">
@await DisplayAsync(Model.Sidebar)
</div>
}
</div>

@if (!String.IsNullOrWhiteSpace(Context.Request.Query["returnUrl"]))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@await DisplayAsync(await New.AdminTabs(ContentItem: Model.ContentItem, Tabs: Model.Tabs))


60 changes: 60 additions & 0 deletions src/OrchardCore.Themes/TheAdmin/Assets/scss/TheAdmin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,66 @@ ul.pager li {
ul.pager li a {
@extend .page-link;
}
// Tabs
// ------------------------------
//
.tab-pane {
border-left: $nav-tabs-border-width solid $nav-tabs-border-color;
border-right: $nav-tabs-border-width solid $nav-tabs-border-color;
border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
border-top: $nav-tabs-border-width solid $nav-tabs-border-color;
border-bottom-left-radius: $nav-tabs-border-radius;
border-bottom-right-radius: $nav-tabs-border-radius;
border-top-right-radius: $nav-tabs-border-radius;
margin-bottom: map-get($map: $spacers, $key: 3);
padding-left: map-get($map: $spacers, $key: 3);
padding-right: map-get($map: $spacers, $key: 3);
padding-top: map-get($map: $spacers, $key: 3);
}

.nav-tabs {
border-bottom: none;
margin-top: 1px;
margin-bottom: -1px;
.nav-link {
border: none;
color: $white;
background-color: $gray-600;
@include transition($btn-transition);
&:hover{
background-color: darken($gray-600, 7.5%)
}
&.active {
border-left: $nav-tabs-border-width solid $nav-tabs-border-color;
border-right: $nav-tabs-border-width solid $nav-tabs-border-color;
border-top: $nav-tabs-border-width solid $nav-tabs-border-color;
cursor: initial;
color: $gray-900;
background-color: $white;
&:hover {
background-color: $white;
}
}
}
.nav-item{
margin-bottom: 0px;
}
}

@include media-breakpoint-down(sm) {
.nav-tabs {
.nav-item:not(.nav-link) {
padding-bottom: map-get($map: $spacers, $key: 1);
}
.nav-link {
border-bottom-left-radius: $nav-tabs-border-radius;
border-bottom-right-radius: $nav-tabs-border-radius;
&.active {
border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
}
}
}
}
// Sortable
// ------------------------------
.ui-sortable-handle {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
font-family: Consolas, monospace;
height: auto;
color: black;
border: 1px solid #eee;
border: 1px solid $gray-300;
font-size: $font-size-base;
text-align: left;
direction: ltr;
Expand Down
70 changes: 69 additions & 1 deletion src/OrchardCore.Themes/TheAdmin/wwwroot/Styles/TheAdmin.css
Original file line number Diff line number Diff line change
Expand Up @@ -8780,7 +8780,7 @@ a.text-dark:hover, a.text-dark:focus {
font-family: Consolas, monospace;
height: auto;
color: black;
border: 1px solid #eee;
border: 1px solid #dee2e6;
font-size: 1rem;
text-align: left;
direction: ltr; }
Expand Down Expand Up @@ -10079,6 +10079,74 @@ select[multiple] {
[dir] ul.pager {
margin-top: 1rem; }

[dir] .tab-pane {
border-bottom: 1px solid #dee2e6;
border-top: 1px solid #dee2e6;
margin-bottom: 1rem;
padding-top: 1rem; }

[dir=ltr] .tab-pane {
border-left: 1px solid #dee2e6;
border-right: 1px solid #dee2e6;
border-bottom-left-radius: 0.25rem;
border-bottom-right-radius: 0.25rem;
border-top-right-radius: 0.25rem;
padding-left: 1rem;
padding-right: 1rem; }

[dir=rtl] .tab-pane {
border-right: 1px solid #dee2e6;
border-left: 1px solid #dee2e6;
border-bottom-right-radius: 0.25rem;
border-bottom-left-radius: 0.25rem;
border-top-left-radius: 0.25rem;
padding-right: 1rem;
padding-left: 1rem; }

[dir] .nav-tabs {
border-bottom: none;
margin-top: 1px;
margin-bottom: -1px; }
.nav-tabs .nav-link {
color: white;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; }
[dir] .nav-tabs .nav-link {
border: none;
background-color: #6c757d; }
@media (prefers-reduced-motion: reduce) {
.nav-tabs .nav-link {
transition: none; } }
[dir] .nav-tabs .nav-link:hover {
background-color: #5a6268; }
.nav-tabs .nav-link.active {
color: #212529; }
[dir] .nav-tabs .nav-link.active {
border-top: 1px solid #dee2e6;
cursor: initial;
background-color: white; }
[dir=ltr] .nav-tabs .nav-link.active {
border-left: 1px solid #dee2e6;
border-right: 1px solid #dee2e6; }
[dir=rtl] .nav-tabs .nav-link.active {
border-right: 1px solid #dee2e6;
border-left: 1px solid #dee2e6; }
[dir] .nav-tabs .nav-link.active:hover {
background-color: white; }
[dir] .nav-tabs .nav-item {
margin-bottom: 0px; }

@media (max-width: 767.98px) {
[dir] .nav-tabs .nav-item:not(.nav-link) {
padding-bottom: 0.25rem; }
[dir=ltr] .nav-tabs .nav-link {
border-bottom-left-radius: 0.25rem;
border-bottom-right-radius: 0.25rem; }
[dir=rtl] .nav-tabs .nav-link {
border-bottom-right-radius: 0.25rem;
border-bottom-left-radius: 0.25rem; }
[dir] .nav-tabs .nav-link.active {
border-bottom: 1px solid #dee2e6; } }

[dir] .ui-sortable-handle {
cursor: move; }

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,14 @@ public async Task BuildEditorAsync(ContentItem contentItem, BuildEditorContext c
return;

dynamic contentShape = context.Shape;
dynamic partsShape = await context.ShapeFactory.CreateAsync("Zone", Arguments.Empty);
contentShape.Zones["Parts"] = partsShape;
dynamic partsShape = await context.ShapeFactory.CreateAsync("ContentZone",
Arguments.From(new
{
ContentItem = contentItem
}));

contentShape.Zones["Parts"] = partsShape;

foreach (var displayDriver in _displayDrivers)
{
try
Expand Down
47 changes: 41 additions & 6 deletions src/OrchardCore/OrchardCore.DisplayManagement/Zones/ZoneShapes.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
Expand Down Expand Up @@ -35,25 +35,33 @@ public async Task<IHtmlContent> ContentZone(dynamic DisplayAsync, dynamic Shape)

if (tabbed.Count > 1)
{
var tabIndex = 0;
var tabId = Shape.ContentItem != null ? (string)Shape.ContentItem.ContentItemId : "";
var tabContentBuilder = new TagBuilder("div");
tabContentBuilder.AddCssClass("tab-content");
foreach (var tab in tabbed)
{
var tabName = String.IsNullOrWhiteSpace(tab.Key) ? "Content" : tab.Key;
var tabBuilder = new TagBuilder("div");
tabBuilder.Attributes["id"] = "tab-" + tabName.HtmlClassify();
tabBuilder.Attributes["data-tab"] = tabName;
var tabItemBuilder = new TagBuilder("div");
tabItemBuilder.Attributes["id"] = $"tab-{tabId}-{tabName}".HtmlClassify();
var tabItemClasses = tabIndex == 0 ? "tab-pane fade show active" : "tab-pane fade";
tabItemBuilder.AddCssClass(tabItemClasses);
foreach (var item in tab)
{
tabBuilder.InnerHtml.AppendHtml(await DisplayAsync(item));
tabItemBuilder.InnerHtml.AppendHtml(await DisplayAsync(item));
}
htmlContents.Add(tabBuilder);
tabContentBuilder.InnerHtml.AppendHtml(tabItemBuilder);
tabIndex++;
}
htmlContents.Add(tabContentBuilder);
}
else if (tabbed.Count > 0)
{
foreach (var item in tabbed[0])
{
htmlContents.Add(await DisplayAsync(item));
}

}

var htmlContentBuilder = new HtmlContentBuilder();
Expand All @@ -64,5 +72,32 @@ public async Task<IHtmlContent> ContentZone(dynamic DisplayAsync, dynamic Shape)

return htmlContentBuilder;
}

public static IEnumerable<string> HarvestAndSortTabs(IEnumerable<dynamic> shapes)
{
var tabs = new List<string>();

foreach (var shape in shapes)
{
var tab = (string)shape.Metadata.Tab;

if (String.IsNullOrEmpty(tab))
continue;

if (!tabs.Contains(tab))
tabs.Add(tab);
}

// If we have any tabs, make sure we have at least the Content tab and that it is the first one,
// since that's where we will put anything else not part of a tab.
if (tabs.Any())
{
tabs.Remove("Content");
tabs.Insert(0, "Content");
}

return tabs;
}

}
}

0 comments on commit 6f5c6b9

Please sign in to comment.