From 1c40b8ba9363f99cae56c724fbaa3564d2a0b335 Mon Sep 17 00:00:00 2001
From: Benedek Farkas <benedek.farkas@lombiq.com>
Date: Tue, 10 Dec 2024 09:30:58 +0100
Subject: [PATCH] #8808: Fixing Container admin navigation (#8809)

* Fixing that Core.Containers "Show on admin menu" functionality shouldn't depend on the Orchard.Lists feature

* Moving menu.list.png admin menu icon from Orchard.Lists to Core.Containers as menu.container.png

to fix that Containers should have a default admin menu icon

* Fixing conflict between lists and container admin navicon by applying the unused menu.list-definition.png to lists

* Code styling and removing duplicate code
---
 src/Orchard.Web/Core/Containers/AdminMenu.cs  |  93 +++++++++++++++++
 .../Core/Containers/Styles/Web.config         |  12 +++
 .../Styles/images/menu.container.png}         | Bin
 .../Styles/menu.container-admin.css           |   7 ++
 src/Orchard.Web/Core/Orchard.Core.csproj      |   6 ++
 .../Modules/Orchard.Lists/AdminMenu.cs        |  97 ++----------------
 .../Orchard.Lists/Orchard.Lists.csproj        |   7 +-
 ...enu.list-definition.png => menu.lists.png} | Bin
 .../Orchard.Lists/Styles/menu.list-admin.css  |  22 ----
 .../Orchard.Lists/Styles/menu.lists-admin.css |   7 ++
 10 files changed, 135 insertions(+), 116 deletions(-)
 create mode 100644 src/Orchard.Web/Core/Containers/AdminMenu.cs
 create mode 100644 src/Orchard.Web/Core/Containers/Styles/Web.config
 rename src/Orchard.Web/{Modules/Orchard.Lists/Styles/images/menu.list.png => Core/Containers/Styles/images/menu.container.png} (100%)
 create mode 100644 src/Orchard.Web/Core/Containers/Styles/menu.container-admin.css
 rename src/Orchard.Web/Modules/Orchard.Lists/Styles/images/{menu.list-definition.png => menu.lists.png} (100%)
 delete mode 100644 src/Orchard.Web/Modules/Orchard.Lists/Styles/menu.list-admin.css
 create mode 100644 src/Orchard.Web/Modules/Orchard.Lists/Styles/menu.lists-admin.css

diff --git a/src/Orchard.Web/Core/Containers/AdminMenu.cs b/src/Orchard.Web/Core/Containers/AdminMenu.cs
new file mode 100644
index 000000000..cc5fd9b52
--- /dev/null
+++ b/src/Orchard.Web/Core/Containers/AdminMenu.cs
@@ -0,0 +1,93 @@
+using System.Linq;
+using Orchard.ContentManagement;
+using Orchard.Core.Containers.Models;
+using Orchard.Core.Containers.Services;
+using Orchard.Localization;
+using Orchard.Security;
+using Orchard.UI.Navigation;
+using Orchard.Utility.Extensions;
+
+namespace Orchard.Core.Containers {
+    public class AdminMenu : INavigationProvider {
+        private readonly IContainerService _containerService;
+        private readonly IContentManager _contentManager;
+        private readonly IAuthorizationService _authorizationService;
+        private readonly IWorkContextAccessor _workContextAccessor;
+
+        public AdminMenu(
+            IContainerService containerService,
+            IContentManager contentManager,
+            IAuthorizationService authorizationService,
+            IWorkContextAccessor workContextAccessor) {
+            _containerService = containerService;
+            _contentManager = contentManager;
+            _authorizationService = authorizationService;
+            _workContextAccessor = workContextAccessor;
+        }
+
+        public Localizer T { get; set; }
+        public string MenuName { get { return "admin"; } }
+
+        public void GetNavigation(NavigationBuilder builder) {
+            builder.AddImageSet("container");
+
+            var containers = _containerService
+                .GetContainersQuery(VersionOptions.Latest)
+                .Where<ContainerPartRecord>(x => x.ShowOnAdminMenu)
+                .List()
+                .Where(content => _authorizationService.TryCheckAccess(
+                    Contents.Permissions.EditContent,
+                    _workContextAccessor.GetContext().CurrentUser,
+                    content))
+                .ToList();
+
+            foreach (var container in containers) {
+                var closureContainer = container;
+
+                if (!string.IsNullOrWhiteSpace(container.AdminMenuImageSet)) {
+                    builder.AddImageSet(container.AdminMenuImageSet.Trim());
+                }
+
+                builder.Add(T(container.AdminMenuText), container.AdminMenuPosition, item => {
+                    var containedItems = _containerService.GetContentItems(closureContainer.Id, VersionOptions.Latest).ToList();
+                    var actualContainer = closureContainer;
+                    var position = 0;
+
+                    // If the list has just a single item that happens to be a container itself,
+                    // we will treat that one as the actual container to provide a nice & quick way to manage that list.
+                    if (containedItems.Count == 1) {
+                        var containedItem = containedItems.First().As<ContainerPart>();
+
+                        if (containedItem != null) {
+                            actualContainer = containedItem;
+                            foreach (var itemContentType in containedItem.ItemContentTypes) {
+                                var closureItemContentType = itemContentType;
+                                item.Add(T("New {0}", itemContentType.DisplayName), string.Format("1.{0}", position++), subItem => subItem
+                                    .Action("Create", "Admin", new {
+                                        id = closureItemContentType.Name,
+                                        containerid = containedItem.Id,
+                                        area = "Contents"
+                                    }));
+                            }
+                        }
+                    }
+
+                    item.Action(_contentManager.GetItemMetadata(actualContainer).AdminRouteValues)
+                        .AddClass("section-container")
+                        .AddClass(closureContainer.AdminMenuText.HtmlClassify())
+                        .LinkToFirstChild(false);
+
+                    foreach (var itemContentType in closureContainer.ItemContentTypes) {
+                        var closureItemContentType = itemContentType;
+                        item.Add(T("New {0}", itemContentType.DisplayName), string.Format("1.{0}", position++), subItem => subItem
+                            .Action("Create", "Admin", new {
+                                id = closureItemContentType.Name,
+                                containerid = container.Id,
+                                area = "Contents"
+                            }));
+                    }
+                });
+            }
+        }
+    }
+}
diff --git a/src/Orchard.Web/Core/Containers/Styles/Web.config b/src/Orchard.Web/Core/Containers/Styles/Web.config
new file mode 100644
index 000000000..93eab9a73
--- /dev/null
+++ b/src/Orchard.Web/Core/Containers/Styles/Web.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+    <system.webServer>
+        <staticContent>
+            <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
+        </staticContent>
+        <handlers accessPolicy="Script,Read">
+            <!-- For any request to a file exists on disk, return it via native http module. AccessPolicy="Script" above is to allow for a managed 404 page. -->
+            <add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
+        </handlers>
+    </system.webServer>
+</configuration>
diff --git a/src/Orchard.Web/Modules/Orchard.Lists/Styles/images/menu.list.png b/src/Orchard.Web/Core/Containers/Styles/images/menu.container.png
similarity index 100%
rename from src/Orchard.Web/Modules/Orchard.Lists/Styles/images/menu.list.png
rename to src/Orchard.Web/Core/Containers/Styles/images/menu.container.png
diff --git a/src/Orchard.Web/Core/Containers/Styles/menu.container-admin.css b/src/Orchard.Web/Core/Containers/Styles/menu.container-admin.css
new file mode 100644
index 000000000..a795a07ce
--- /dev/null
+++ b/src/Orchard.Web/Core/Containers/Styles/menu.container-admin.css
@@ -0,0 +1,7 @@
+.menu-admin > .section-container > h3 > a {
+    background-image: url(images/menu.container.png) !important;
+}
+
+.menu-admin > .section-container > h3 > a:hover {
+    background-position: 0 -30px !important;
+}
diff --git a/src/Orchard.Web/Core/Orchard.Core.csproj b/src/Orchard.Web/Core/Orchard.Core.csproj
index 67072601b..1dc161b15 100644
--- a/src/Orchard.Web/Core/Orchard.Core.csproj
+++ b/src/Orchard.Web/Core/Orchard.Core.csproj
@@ -119,6 +119,7 @@
     <Compile Include="Common\ViewModels\DateTimeEditor.cs" />
     <Compile Include="Common\ViewModels\TextFieldDriverViewModel.cs" />
     <Compile Include="Common\ViewModels\TextFieldSettingsEventsViewModel.cs" />
+    <Compile Include="Containers\AdminMenu.cs" />
     <Compile Include="Containers\Controllers\ItemController.cs" />
     <Compile Include="Containers\Drivers\ContainablePartDriver.cs" />
     <Compile Include="Containers\Drivers\ContainerPartDriver.cs" />
@@ -318,6 +319,8 @@
     <Content Include="Common\Views\Parts.Common.Metadata.cshtml" />
     <Content Include="Common\Views\CommonMetadataLastModified.cshtml" />
     <Content Include="Containers\Module.txt" />
+    <Content Include="Containers\Styles\images\menu.container.png" />
+    <Content Include="Containers\Styles\menu.container-admin.css" />
     <Content Include="Shapes\Scripts\admin-localnavigation.js" />
     <Content Include="Contents\Styles\images\menu.content.png" />
     <Content Include="Contents\Styles\menu.content-admin.css" />
@@ -610,6 +613,9 @@
     <Content Include="Navigation\Views\Admin\Edit.cshtml" />
   </ItemGroup>
   <ItemGroup>
+    <Content Include="Containers\Styles\Web.config">
+      <SubType>Designer</SubType>
+    </Content>
     <None Include="packages.config" />
     <Content Include="Title\Views\DefinitionTemplates\TitlePartSettings.cshtml" />
   </ItemGroup>
diff --git a/src/Orchard.Web/Modules/Orchard.Lists/AdminMenu.cs b/src/Orchard.Web/Modules/Orchard.Lists/AdminMenu.cs
index fbb99bd8d..eb2ad4627 100644
--- a/src/Orchard.Web/Modules/Orchard.Lists/AdminMenu.cs
+++ b/src/Orchard.Web/Modules/Orchard.Lists/AdminMenu.cs
@@ -1,98 +1,15 @@
-using System;
-using System.Linq;
-using Orchard.ContentManagement;
-using Orchard.Core.Containers.Models;
-using Orchard.Core.Containers.Services;
-using Orchard.Localization;
-using Orchard.Security;
+using Orchard.Localization;
 using Orchard.UI.Navigation;
-using Orchard.Utility.Extensions;
 
 namespace Orchard.Lists {
     public class AdminMenu : INavigationProvider {
-        private readonly IContainerService _containerService;
-        private readonly IContentManager _contentManager;
-        private readonly IAuthorizationService _authorizationService;
-        private readonly IWorkContextAccessor _workContextAccessor;
-
-        public AdminMenu(
-            IContainerService containerService, 
-            IContentManager contentManager,
-            IAuthorizationService authorizationService, 
-            IWorkContextAccessor workContextAccessor
-            ) {
-            _containerService = containerService;
-            _contentManager = contentManager;
-            _authorizationService = authorizationService;
-            _workContextAccessor = workContextAccessor;
-        }
-
         public Localizer T { get; set; }
         public string MenuName { get { return "admin"; } }
 
-        public void GetNavigation(NavigationBuilder builder) {
-            builder.AddImageSet("list");
-
-            CreateListManagementMenuItem(builder);
-            CreateListMenuItems(builder);
-        }
-
-        private void CreateListManagementMenuItem(NavigationBuilder builder) {
-            builder.Add(T("Lists"), "11", item => item
-                .Action("Index", "Admin", new {area = "Orchard.Lists"}).Permission(Permissions.ManageLists)
-            );
-        }
-
-        private void CreateListMenuItems(NavigationBuilder builder) {
-            var containers = _containerService
-                .GetContainersQuery(VersionOptions.Latest)
-                .Where<ContainerPartRecord>(x => x.ShowOnAdminMenu)
-                .List()
-                .Where(x => _authorizationService.TryCheckAccess(Orchard.Core.Contents.Permissions.EditContent, _workContextAccessor.GetContext().CurrentUser, x))
-                .ToList();
-
-            foreach (var container in containers) {
-                var closureContainer = container;
-
-                if (!String.IsNullOrWhiteSpace(container.AdminMenuImageSet)) {
-                    builder.AddImageSet(container.AdminMenuImageSet.Trim());                    
-                }
-
-                builder.Add(T(container.AdminMenuText), container.AdminMenuPosition, item => {
-                    var containedItems = _containerService.GetContentItems(closureContainer.Id, VersionOptions.Latest).ToList();
-                    var actualContainer = closureContainer;
-                    var position = 0;
-
-                    // If the list has just a single item that happens to be a container itself,
-                    // we will treat that one as the actual container to provide a nice & quick way to manage that list.
-                    if (containedItems.Count == 1) {
-                        var containedItem = containedItems.First().As<ContainerPart>();
-
-                        if (containedItem != null) {
-                            actualContainer = containedItem;
-                            foreach (var itemContentType in containedItem.ItemContentTypes) {
-                                var closureItemContentType = itemContentType;
-                                item.Add(T("New {0}", itemContentType.DisplayName), String.Format("1.{0}", position++), subItem => subItem
-                                    .Action("Create", "Admin", new { id = closureItemContentType.Name, containerid = containedItem.Id, area = "Contents" }));
-                            }
-                        }
-                    }
-
-                    var containerMetadata = _contentManager.GetItemMetadata(actualContainer);
-                    item.Action(containerMetadata.AdminRouteValues);
-
-                    item.Action(containerMetadata.AdminRouteValues);
-                    item.AddClass("nav-list");
-                    item.AddClass(closureContainer.AdminMenuText.HtmlClassify());
-                    item.LinkToFirstChild(false);
-                    
-                    foreach (var itemContentType in closureContainer.ItemContentTypes) {
-                        var closureItemContentType = itemContentType;
-                        item.Add(T("New {0}", itemContentType.DisplayName), String.Format("1.{0}", position++), subItem => subItem
-                            .Action("Create", "Admin", new { id = closureItemContentType.Name, containerid = container.Id, area = "Contents" }));
-                    }
-                });
-            }
-        }
+        public void GetNavigation(NavigationBuilder builder) =>
+            builder
+                .AddImageSet("lists")
+                .Add(T("Lists"), "11", item => item
+                .Action("Index", "Admin", new { area = "Orchard.Lists" }).Permission(Permissions.ManageLists));
     }
-}
\ No newline at end of file
+}
diff --git a/src/Orchard.Web/Modules/Orchard.Lists/Orchard.Lists.csproj b/src/Orchard.Web/Modules/Orchard.Lists/Orchard.Lists.csproj
index 2826072e4..f8b3eb32f 100644
--- a/src/Orchard.Web/Modules/Orchard.Lists/Orchard.Lists.csproj
+++ b/src/Orchard.Web/Modules/Orchard.Lists/Orchard.Lists.csproj
@@ -115,6 +115,7 @@
     <Content Include="Styles\images\icons.png" />
     <Content Include="Styles\images\view.default.png" />
     <Content Include="Styles\images\view.condensed.png" />
+    <Content Include="Styles\menu.lists-admin.css" />
     <Content Include="Styles\nprogress.css" />
     <Content Include="Scripts\nprogress.js" />
     <Content Include="Scripts\orchard-lists-admin.js" />
@@ -143,16 +144,14 @@
     <Content Include="Scripts\orchard-lists-admin.min.js">
       <DependentUpon>orchard-lists-admin.js</DependentUpon>
     </Content>
-    <Content Include="Styles\images\menu.list-definition.png" />
+    <Content Include="Styles\images\menu.lists.png" />
     <Content Include="Styles\images\move.gif" />
     <Content Include="Styles\images\offline.gif" />
     <Content Include="Styles\images\online.gif" />
     <Content Include="Styles\list-admin.css" />
-    <Content Include="Styles\images\menu.list.png" />
     <Content Include="Styles\list-admin.min.css">
       <DependentUpon>list-admin.css</DependentUpon>
     </Content>
-    <Content Include="Styles\menu.list-admin.css" />
   </ItemGroup>
   <ItemGroup>
     <Content Include="Web.config">
@@ -272,4 +271,4 @@
       </FlavorProperties>
     </VisualStudio>
   </ProjectExtensions>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.Lists/Styles/images/menu.list-definition.png b/src/Orchard.Web/Modules/Orchard.Lists/Styles/images/menu.lists.png
similarity index 100%
rename from src/Orchard.Web/Modules/Orchard.Lists/Styles/images/menu.list-definition.png
rename to src/Orchard.Web/Modules/Orchard.Lists/Styles/images/menu.lists.png
diff --git a/src/Orchard.Web/Modules/Orchard.Lists/Styles/menu.list-admin.css b/src/Orchard.Web/Modules/Orchard.Lists/Styles/menu.list-admin.css
deleted file mode 100644
index 9d43ff049..000000000
--- a/src/Orchard.Web/Modules/Orchard.Lists/Styles/menu.list-admin.css
+++ /dev/null
@@ -1,22 +0,0 @@
-.navicon-list,
-.navicon-lists,
-.section-new .subnavicon-list,
-.nav-list > h3 > a,
-.nav-list-definition > h3 > a {
-    background-image:url(images/menu.list.png) !important;
-}
-
-.navicon-list:hover,
-.navicon-lists:hover,
-.nav-list > h3 > a:hover,
-.nav-list-definition > h3 > a:hover {
-    background-position:0 -30px !important;
-}
-
-.navicon-lists {
-    background-image:url(images/menu.list.png) !important;
-}
-
-.navicon-lists:hover {
-    background-position:0 -30px !important;
-}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.Lists/Styles/menu.lists-admin.css b/src/Orchard.Web/Modules/Orchard.Lists/Styles/menu.lists-admin.css
new file mode 100644
index 000000000..2199b6ee8
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.Lists/Styles/menu.lists-admin.css
@@ -0,0 +1,7 @@
+.navicon-lists {
+    background-image: url(images/menu.lists.png) !important;
+}
+
+.navicon-lists:hover {
+    background-position: 0 -30px !important;
+}