Gets sln building, removes old legacy settings, removes ascx dashboard support

This commit is contained in:
Shannon
2018-12-03 16:14:49 +11:00
parent 953f37f2db
commit 162b90194d
25 changed files with 172 additions and 457 deletions

View File

@@ -3,7 +3,7 @@
<section alias="StartupSettingsDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing"> <section alias="StartupSettingsDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Remove" /> <tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
<tab caption="Welcome" xdt:Locator="Match(caption)" xdt:Transform="InsertIfMissing"> <tab caption="Welcome" xdt:Locator="Match(caption)" xdt:Transform="InsertIfMissing">
<control showOnce="true" addPanel="true" panelCaption="" xdt:Transform="InsertIfMissing"> <control panelCaption="" xdt:Transform="InsertIfMissing">
views/dashboard/settings/settingsdashboardintro.html views/dashboard/settings/settingsdashboardintro.html
</control> </control>
</tab> </tab>
@@ -14,7 +14,7 @@
<area>forms</area> <area>forms</area>
</areas> </areas>
<tab caption="Install Umbraco Forms"> <tab caption="Install Umbraco Forms">
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/forms/formsdashboardintro.html views/dashboard/forms/formsdashboardintro.html
</control> </control>
</tab> </tab>
@@ -28,7 +28,7 @@
<section alias="StartupDeveloperDashboardSection"> <section alias="StartupDeveloperDashboardSection">
<tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Replace"> <tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Replace">
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/developer/developerdashboardvideos.html views/dashboard/developer/developerdashboardvideos.html
</control> </control>
</tab> </tab>
@@ -47,7 +47,7 @@
<tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Remove" /> <tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
<tab caption="Content" xdt:Locator="Match(caption)" xdt:Transform="InsertIfMissing" /> <tab caption="Content" xdt:Locator="Match(caption)" xdt:Transform="InsertIfMissing" />
<tab caption="Content" xdt:Locator="Match(caption)" xdt:Transform="Replace"> <tab caption="Content" xdt:Locator="Match(caption)" xdt:Transform="Replace">
<control showOnce="false" addPanel="false" panelCaption=""> <control panelCaption="">
views/dashboard/media/mediafolderbrowser.html views/dashboard/media/mediafolderbrowser.html
</control> </control>
</tab> </tab>
@@ -56,7 +56,7 @@
<section alias="StartupMemberDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing"> <section alias="StartupMemberDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Remove" /> <tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
<tab caption="Get Started" xdt:Transform="Insert"> <tab caption="Get Started" xdt:Transform="Insert">
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/members/membersdashboardvideos.html views/dashboard/members/membersdashboardvideos.html
</control> </control>
</tab> </tab>
@@ -92,4 +92,4 @@
</control> </control>
</tab> </tab>
</section> </section>
</dashBoard> </dashBoard>

View File

@@ -8,25 +8,6 @@ namespace Umbraco.Core.Configuration.Dashboard
internal class ControlElement : RawXmlConfigurationElement, IDashboardControl internal class ControlElement : RawXmlConfigurationElement, IDashboardControl
{ {
public bool ShowOnce
{
get
{
return RawXml.Attribute("showOnce") == null
? false
: bool.Parse(RawXml.Attribute("showOnce").Value);
}
}
public bool AddPanel
{
get
{
return RawXml.Attribute("addPanel") == null
? true
: bool.Parse(RawXml.Attribute("addPanel").Value);
}
}
public string PanelCaption public string PanelCaption
{ {
@@ -37,7 +18,6 @@ namespace Umbraco.Core.Configuration.Dashboard
: RawXml.Attribute("panelCaption").Value; : RawXml.Attribute("panelCaption").Value;
} }
} }
public AccessElement Access public AccessElement Access
{ {
get get
@@ -66,9 +46,6 @@ namespace Umbraco.Core.Configuration.Dashboard
} }
IAccess IDashboardControl.AccessRights IAccess IDashboardControl.AccessRights => Access;
{
get { return Access; }
}
} }
} }

View File

@@ -2,10 +2,6 @@
{ {
public interface IDashboardControl public interface IDashboardControl
{ {
bool ShowOnce { get; }
bool AddPanel { get; }
string PanelCaption { get; } string PanelCaption { get; }
string ControlPath { get; } string ControlPath { get; }

View File

@@ -1,204 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Umbraco.Core.Cache;
using Umbraco.Core.IO;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Manifest
{
/// <summary>
/// This reads in the manifests and stores some definitions in memory so we can look them on the server side
/// </summary>
internal class ManifestBuilder
{
private readonly IRuntimeCacheProvider _runtimeCache;
private readonly ManifestParser _parser;
public ManifestBuilder(IRuntimeCacheProvider cache, ManifestParser parser)
{
_runtimeCache = cache;
_parser = parser;
}
public const string GridEditorsKey = "gridEditors";
public const string PropertyEditorsKey = "propertyEditors";
public const string ParameterEditorsKey = "parameterEditors";
public const string DashboardsKey = "dashboards";
/// <summary>
/// Returns all grid editors found in the manfifests
/// </summary>
internal IEnumerable<GridEditor> GridEditors
{
get
{
return _runtimeCache.GetCacheItem<IEnumerable<GridEditor>>(
typeof (ManifestBuilder) + GridEditorsKey,
() =>
{
var editors = new List<GridEditor>();
foreach (var manifest in _parser.GetManifests())
{
if (manifest.GridEditors != null)
{
editors.AddRange(ManifestParser.GetGridEditors(manifest.GridEditors));
}
}
return editors;
}, new TimeSpan(0, 10, 0));
}
}
/// <summary>
/// Returns all property editors found in the manfifests
/// </summary>
internal IEnumerable<PropertyEditor> PropertyEditors
{
get
{
return _runtimeCache.GetCacheItem<IEnumerable<PropertyEditor>>(
typeof(ManifestBuilder) + PropertyEditorsKey,
() =>
{
var editors = new List<PropertyEditor>();
foreach (var manifest in _parser.GetManifests())
{
if (manifest.PropertyEditors != null)
{
editors.AddRange(ManifestParser.GetPropertyEditors(manifest.PropertyEditors));
}
}
return editors;
}, new TimeSpan(0, 10, 0));
}
}
/// <summary>
/// Returns all parameter editors found in the manfifests and all property editors that are flagged to be parameter editors
/// </summary>
internal IEnumerable<ParameterEditor> ParameterEditors
{
get
{
return _runtimeCache.GetCacheItem<IEnumerable<ParameterEditor>>(
typeof (ManifestBuilder) + ParameterEditorsKey,
() =>
{
var editors = new List<ParameterEditor>();
foreach (var manifest in _parser.GetManifests())
{
if (manifest.ParameterEditors != null)
{
editors.AddRange(ManifestParser.GetParameterEditors(manifest.ParameterEditors));
}
}
return editors;
}, new TimeSpan(0, 10, 0));
}
}
/// <summary>
/// Returns all dashboards found in the manfifests
/// </summary>
internal IDictionary<string, Section> Dashboards
{
get
{
//TODO: Need to integrate the security with the manifest dashboards
return _runtimeCache.GetCacheItem<IDictionary<string, Section>>(
typeof(ManifestBuilder) + DashboardsKey,
() =>
{
var dashboards = new Dictionary<string, Section>();
foreach (var manifest in _parser.GetManifests())
{
if (manifest.Dashboards != null)
{
var converted = manifest.Dashboards.ToDictionary(x => x.Key, x => x.Value.ToObject<Section>());
foreach (var item in converted)
{
Section existing;
if (dashboards.TryGetValue(item.Key, out existing))
{
foreach (var area in item.Value.Areas)
{
if (existing.Areas.Contains(area, StringComparer.InvariantCultureIgnoreCase) == false)
existing.Areas.Add(area);
}
//merge
foreach (var tab in item.Value.Tabs)
{
Tab existingTab;
if (existing.Tabs.TryGetValue(tab.Key, out existingTab))
{
//merge
foreach (var control in tab.Value.Controls)
{
existingTab.Controls.Add(control);
}
}
else
{
existing.Tabs[tab.Key] = tab.Value;
}
}
;
}
else
{
dashboards[item.Key] = item.Value;
}
}
}
}
return dashboards;
}, new TimeSpan(0, 10, 0));
}
}
#region Internal manifest models
internal class Section
{
public Section()
{
Areas = new List<string>();
Tabs = new Dictionary<string, Tab>();
}
[JsonProperty("areas")]
public List<string> Areas { get; set; }
[JsonProperty("tabs")]
public IDictionary<string, Tab> Tabs { get; set; }
}
internal class Tab
{
public Tab()
{
Controls = new List<Control>();
Index = int.MaxValue; //default so we can check if this value has been explicitly set
}
[JsonProperty("controls")]
public List<Control> Controls { get; set; }
[JsonProperty("index")]
public int Index { get; set; }
}
internal class Control
{
[JsonProperty("path")]
public string Path { get; set; }
[JsonProperty("caption")]
public string Caption { get; set; }
}
#endregion
}
}

View File

@@ -0,0 +1,13 @@
using Newtonsoft.Json;
namespace Umbraco.Core.Manifest
{
public class ManifestDashboardControl
{
[JsonProperty("path")]
public string Path { get; set; }
[JsonProperty("caption")]
public string Caption { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace Umbraco.Core.Manifest
{
public class ManifestDashboardSection
{
public ManifestDashboardSection()
{
Areas = new List<string>();
Tabs = new Dictionary<string, ManifestDashboardTab>();
}
[JsonProperty("areas")]
public List<string> Areas { get; set; }
[JsonProperty("tabs")]
public IDictionary<string, ManifestDashboardTab> Tabs { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace Umbraco.Core.Manifest
{
public class ManifestDashboardTab
{
public ManifestDashboardTab()
{
Controls = new List<ManifestDashboardControl>();
Index = int.MaxValue; //default so we can check if this value has been explicitly set
}
[JsonProperty("controls")]
public List<ManifestDashboardControl> Controls { get; set; }
[JsonProperty("index")]
public int Index { get; set; }
}
}

View File

@@ -100,6 +100,7 @@ namespace Umbraco.Core.Manifest
var parameterEditors = new List<IDataEditor>(); var parameterEditors = new List<IDataEditor>();
var gridEditors = new List<GridEditor>(); var gridEditors = new List<GridEditor>();
var contentApps = new List<IContentAppDefinition>(); var contentApps = new List<IContentAppDefinition>();
var dashboards = new Dictionary<string, ManifestDashboardSection>();
foreach (var manifest in manifests) foreach (var manifest in manifests)
{ {
@@ -109,6 +110,35 @@ namespace Umbraco.Core.Manifest
if (manifest.ParameterEditors != null) parameterEditors.AddRange(manifest.ParameterEditors); if (manifest.ParameterEditors != null) parameterEditors.AddRange(manifest.ParameterEditors);
if (manifest.GridEditors != null) gridEditors.AddRange(manifest.GridEditors); if (manifest.GridEditors != null) gridEditors.AddRange(manifest.GridEditors);
if (manifest.ContentApps != null) contentApps.AddRange(manifest.ContentApps); if (manifest.ContentApps != null) contentApps.AddRange(manifest.ContentApps);
if (manifest.Dashboards != null)
{
foreach (var item in manifest.Dashboards)
{
if (dashboards.TryGetValue(item.Key, out var existing))
{
foreach (var area in item.Value.Areas)
if (existing.Areas.Contains(area, StringComparer.InvariantCultureIgnoreCase) == false)
existing.Areas.Add(area);
//merge
foreach (var tab in item.Value.Tabs)
{
if (existing.Tabs.TryGetValue(tab.Key, out var existingTab))
{
//merge
foreach (var control in tab.Value.Controls)
{
existingTab.Controls.Add(control);
}
}
else
existing.Tabs[tab.Key] = tab.Value;
}
}
else
dashboards[item.Key] = item.Value;
}
}
} }
return new PackageManifest return new PackageManifest
@@ -118,7 +148,8 @@ namespace Umbraco.Core.Manifest
PropertyEditors = propertyEditors.ToArray(), PropertyEditors = propertyEditors.ToArray(),
ParameterEditors = parameterEditors.ToArray(), ParameterEditors = parameterEditors.ToArray(),
GridEditors = gridEditors.ToArray(), GridEditors = gridEditors.ToArray(),
ContentApps = contentApps.ToArray() ContentApps = contentApps.ToArray(),
Dashboards = dashboards
}; };
} }
@@ -151,6 +182,7 @@ namespace Umbraco.Core.Manifest
var manifest = JsonConvert.DeserializeObject<PackageManifest>(text, var manifest = JsonConvert.DeserializeObject<PackageManifest>(text,
new DataEditorConverter(_logger), new DataEditorConverter(_logger),
new ValueValidatorConverter(_validators), new ValueValidatorConverter(_validators),
//TODO: DO i need a dashboard one?
new ContentAppDefinitionConverter()); new ContentAppDefinitionConverter());
// scripts and stylesheets are raw string, must process here // scripts and stylesheets are raw string, must process here
@@ -165,6 +197,8 @@ namespace Umbraco.Core.Manifest
if (ppEditors.Count > 0) if (ppEditors.Count > 0)
manifest.ParameterEditors = manifest.ParameterEditors.Union(ppEditors).ToArray(); manifest.ParameterEditors = manifest.ParameterEditors.Union(ppEditors).ToArray();
//TODO: Do we need to deal with dashboards or are they auto parsed?
return manifest; return manifest;
} }
@@ -173,5 +207,6 @@ namespace Umbraco.Core.Manifest
{ {
return JsonConvert.DeserializeObject<IEnumerable<GridEditor>>(text); return JsonConvert.DeserializeObject<IEnumerable<GridEditor>>(text);
} }
} }
} }

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Models.ContentEditing; using Umbraco.Core.Models.ContentEditing;
using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors;
@@ -32,6 +33,9 @@ namespace Umbraco.Core.Manifest
/// <summary> /// <summary>
/// The dictionary of dashboards /// The dictionary of dashboards
/// </summary> /// </summary>
public IDictionary<string, JObject> Dashboards { get; set; } [JsonProperty("dashboards")]
public IReadOnlyDictionary<string, ManifestDashboardSection> Dashboards { get; set; } = new Dictionary<string, ManifestDashboardSection>();
} }
} }

View File

@@ -3,6 +3,7 @@ using Umbraco.Core.Models.Membership;
namespace Umbraco.Core.Models.ContentEditing namespace Umbraco.Core.Models.ContentEditing
{ {
/// <summary> /// <summary>
/// Represents a content app definition. /// Represents a content app definition.
/// </summary> /// </summary>

View File

@@ -335,6 +335,9 @@
<Compile Include="Logging\Serilog\Enrichers\Log4NetLevelMapperEnricher.cs" /> <Compile Include="Logging\Serilog\Enrichers\Log4NetLevelMapperEnricher.cs" />
<Compile Include="Manifest\ContentAppDefinitionConverter.cs" /> <Compile Include="Manifest\ContentAppDefinitionConverter.cs" />
<Compile Include="Manifest\ManifestContentAppDefinition.cs" /> <Compile Include="Manifest\ManifestContentAppDefinition.cs" />
<Compile Include="Manifest\ManifestDashboardControl.cs" />
<Compile Include="Manifest\ManifestDashboardSection.cs" />
<Compile Include="Manifest\ManifestDashboardTab.cs" />
<Compile Include="Migrations\IncompleteMigrationExpressionException.cs" /> <Compile Include="Migrations\IncompleteMigrationExpressionException.cs" />
<Compile Include="Migrations\MigrationBase_Extra.cs" /> <Compile Include="Migrations\MigrationBase_Extra.cs" />
<Compile Include="Migrations\Upgrade\V_7_10_0\RenamePreviewFolder.cs" /> <Compile Include="Migrations\Upgrade\V_7_10_0\RenamePreviewFolder.cs" />

View File

@@ -6,10 +6,10 @@
<area>settings</area> <area>settings</area>
</areas> </areas>
<tab caption="Get Started"> <tab caption="Get Started">
<control showOnce="true" addPanel="true" panelCaption="hello"> <control panelCaption="hello">
views/dashboard/settings/settingsdashboardintro.html views/dashboard/settings/settingsdashboardintro.html
</control> </control>
<control showOnce="false" addPanel="false" panelCaption=""> <control panelCaption="">
views/dashboard/settings/settingsdashboardvideos.html views/dashboard/settings/settingsdashboardvideos.html
</control> </control>
</tab> </tab>
@@ -23,10 +23,10 @@
<area>developer</area> <area>developer</area>
</areas> </areas>
<tab caption="Get Started"> <tab caption="Get Started">
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/developer/developerdashboardintro.html views/dashboard/developer/developerdashboardintro.html
</control> </control>
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/developer/developerdashboardvideos.html views/dashboard/developer/developerdashboardvideos.html
</control> </control>
</tab> </tab>
@@ -37,7 +37,7 @@
<area>media</area> <area>media</area>
</areas> </areas>
<tab caption="Content"> <tab caption="Content">
<control showOnce="false" addPanel="false" panelCaption=""> <control panelCaption="">
views/dashboard/media/mediafolderbrowser.html views/dashboard/media/mediafolderbrowser.html
</control> </control>
</tab> </tab>
@@ -45,13 +45,13 @@
<access> <access>
<grant>admin</grant> <grant>admin</grant>
</access> </access>
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/media/mediadashboardintro.html views/dashboard/media/mediadashboardintro.html
</control> </control>
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/media/desktopmediauploader.html views/dashboard/media/desktopmediauploader.html
</control> </control>
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/media/mediadashboardvideos.html views/dashboard/media/mediadashboardvideos.html
</control> </control>
</tab> </tab>
@@ -70,25 +70,25 @@
<access> <access>
<grant>admin</grant> <grant>admin</grant>
</access> </access>
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/default/startupdashboardintro.html views/dashboard/default/startupdashboardintro.html
</control> </control>
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/default/startupdashboardkits.html views/dashboard/default/startupdashboardkits.html
<access> <access>
<deny>editor</deny> <deny>editor</deny>
<deny>writer</deny> <deny>writer</deny>
</access> </access>
</control> </control>
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/default/startupdashboardvideos.html views/dashboard/default/startupdashboardvideos.html
</control> </control>
</tab> </tab>
<tab caption="Last Edits"> <tab caption="Last Edits">
<control addPanel="true" MaxRecords="30">dashboard/latestEdits.ascx</control> <control MaxRecords="30">dashboard/latestEdits.ascx</control>
</tab> </tab>
<tab caption="Change Password"> <tab caption="Change Password">
<control addPanel="true"> <control >
views/dashboard/changepassword.html views/dashboard/changepassword.html
</control> </control>
</tab> </tab>
@@ -100,13 +100,13 @@
<area>member</area> <area>member</area>
</areas> </areas>
<tab caption="Get Started"> <tab caption="Get Started">
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/members/membersdashboardintro.html views/dashboard/members/membersdashboardintro.html
</control> </control>
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
members/membersearch.ascx members/membersearch.ascx
</control> </control>
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/members/membersdashboardvideos.html views/dashboard/members/membersdashboardvideos.html
</control> </control>
</tab> </tab>

View File

@@ -101,14 +101,10 @@ namespace Umbraco.Tests.Configurations.DashboardSettings
[Test] [Test]
public void Test_Control() public void Test_Control()
{ {
Assert.AreEqual(true, SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(0).ShowOnce);
Assert.AreEqual(true, SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(0).AddPanel);
Assert.AreEqual("hello", SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(0).PanelCaption); Assert.AreEqual("hello", SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(0).PanelCaption);
Assert.AreEqual("views/dashboard/settings/settingsdashboardintro.html", Assert.AreEqual("views/dashboard/settings/settingsdashboardintro.html",
SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(0).ControlPath); SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(0).ControlPath);
Assert.AreEqual(false, SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(1).ShowOnce);
Assert.AreEqual(false, SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(1).AddPanel);
Assert.AreEqual("", SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(1).PanelCaption); Assert.AreEqual("", SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(1).PanelCaption);
Assert.AreEqual("views/dashboard/settings/settingsdashboardvideos.html", Assert.AreEqual("views/dashboard/settings/settingsdashboardvideos.html",
SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(1).ControlPath); SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(1).ControlPath);

View File

@@ -18,18 +18,13 @@
<umb-tab-content ng-repeat="tab in dashboard.tabs" ng-if="tab.active" tab="tab" class="row-fluid"> <umb-tab-content ng-repeat="tab in dashboard.tabs" ng-if="tab.active" tab="tab" class="row-fluid">
<div ng-repeat="property in tab.properties" ng-switch on="property.serverSide"> <div ng-repeat="property in tab.properties">
<div class="clearfix" ng-switch-when="false"> <div class="clearfix">
<h3 ng-show="property.caption">{{property.caption}}</h3> <h3 ng-show="property.caption">{{property.caption}}</h3>
<div ng-include="property.path"></div> <div ng-include="property.path"></div>
</div> </div>
<div class="umb-dashboard-control clearfix" ng-switch-when="true">
<h3 ng-show="property.caption">{{property.caption}}</h3>
<iframe ng-src="dashboard/usercontrolproxy.aspx?ctrl={{ property.path}}"></iframe>
</div>
</div> </div>
</umb-tab-content> </umb-tab-content>
@@ -40,4 +35,4 @@
</form> </form>
</div> </div>

View File

@@ -151,13 +151,6 @@
<Compile Include="Umbraco\Create.aspx.designer.cs"> <Compile Include="Umbraco\Create.aspx.designer.cs">
<DependentUpon>create.aspx</DependentUpon> <DependentUpon>create.aspx</DependentUpon>
</Compile> </Compile>
<Compile Include="Umbraco\Dashboard\UserControlProxy.aspx.cs">
<DependentUpon>UserControlProxy.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="Umbraco\Dashboard\UserControlProxy.aspx.designer.cs">
<DependentUpon>UserControlProxy.aspx</DependentUpon>
</Compile>
<Compile Include="Umbraco\Developer\Macros\EditMacro.aspx.cs"> <Compile Include="Umbraco\Developer\Macros\EditMacro.aspx.cs">
<DependentUpon>editMacro.aspx</DependentUpon> <DependentUpon>editMacro.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType> <SubType>ASPXCodeBehind</SubType>
@@ -236,7 +229,6 @@
</Compile> </Compile>
<Content Include="Config\Splashes\booting.aspx" /> <Content Include="Config\Splashes\booting.aspx" />
<Content Include="Config\Splashes\noNodes.aspx" /> <Content Include="Config\Splashes\noNodes.aspx" />
<Content Include="Umbraco\Dashboard\UserControlProxy.aspx" />
<Content Include="Umbraco\Install\Views\Web.config" /> <Content Include="Umbraco\Install\Views\Web.config" />
<Content Include="App_Plugins\ModelsBuilder\package.manifest" /> <Content Include="App_Plugins\ModelsBuilder\package.manifest" />
<None Include="Config\404handlers.Release.config"> <None Include="Config\404handlers.Release.config">

View File

@@ -1,25 +0,0 @@
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UserControlProxy.aspx.cs" Inherits="Umbraco.Web.UI.Umbraco.Dashboard.UserControlProxy" %>
<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web.UI.JavaScript" Assembly="umbraco" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<cc1:UmbracoClientDependencyLoader runat="server" ID="ClientLoader" />
<umb:CssInclude ID="CssInclude1" runat="server" FilePath="assets/css/umbraco.css" PathNameAlias="UmbracoRoot" />
<umb:JsInclude ID="JsInclude1" runat="server" FilePath="Application/NamespaceManager.js" PathNameAlias="UmbracoClient" Priority="0" />
<umb:JsInclude ID="JsInclude4" runat="server" FilePath="lib/jquery-migrate/jquery-migrate.min.js" PathNameAlias="UmbracoRoot" Priority="1" />
</head>
<body style="overflow: scroll">
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="container" runat="server" />
</div>
</form>
</body>
</html>

View File

@@ -1,40 +0,0 @@
using System;
using System.Web.UI;
using Umbraco.Core.IO;
namespace Umbraco.Web.UI.Umbraco.Dashboard
{
public partial class UserControlProxy : Pages.UmbracoEnsuredPage
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
var path = Request.QueryString["ctrl"];
if (string.IsNullOrEmpty(path) == false)
{
path = IOHelper.FindFile(path);
try
{
var c = LoadControl(path);
container.Controls.Add(c);
}
catch (Exception ee)
{
container.Controls.Add(
new LiteralControl(
"<p class=\"umbracoErrorMessage\">Could not load control: '" + path +
"'. <br/><span class=\"guiDialogTiny\"><strong>Error message:</strong> " +
ee.ToString() + "</span></p>"));
}
}
}
}
}

View File

@@ -1,69 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Umbraco.Web.UI.Umbraco.Dashboard {
public partial class UserControlProxy {
/// <summary>
/// ClientLoader control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::Umbraco.Web.UI.JavaScript.UmbracoClientDependencyLoader ClientLoader;
/// <summary>
/// CssInclude1 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::ClientDependency.Core.Controls.CssInclude CssInclude1;
/// <summary>
/// JsInclude1 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::ClientDependency.Core.Controls.JsInclude JsInclude1;
/// <summary>
/// JsInclude4 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::ClientDependency.Core.Controls.JsInclude JsInclude4;
/// <summary>
/// form1 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.HtmlControls.HtmlForm form1;
/// <summary>
/// container control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.PlaceHolder container;
}
}

View File

@@ -6,7 +6,7 @@
<area>settings</area> <area>settings</area>
</areas> </areas>
<tab caption="Welcome"> <tab caption="Welcome">
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/settings/settingsdashboardintro.html views/dashboard/settings/settingsdashboardintro.html
</control> </control>
</tab> </tab>
@@ -27,7 +27,7 @@
<area>forms</area> <area>forms</area>
</areas> </areas>
<tab caption="Install Umbraco Forms"> <tab caption="Install Umbraco Forms">
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/forms/formsdashboardintro.html views/dashboard/forms/formsdashboardintro.html
</control> </control>
</tab> </tab>
@@ -44,7 +44,7 @@
<area>media</area> <area>media</area>
</areas> </areas>
<tab caption="Content"> <tab caption="Content">
<control showOnce="false" addPanel="false" panelCaption=""> <control panelCaption="">
views/dashboard/media/mediafolderbrowser.html views/dashboard/media/mediafolderbrowser.html
</control> </control>
</tab> </tab>
@@ -63,7 +63,7 @@
<grant>admin</grant> <grant>admin</grant>
</access> </access>
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/default/startupdashboardintro.html views/dashboard/default/startupdashboardintro.html
</control> </control>
@@ -75,7 +75,7 @@
<area>member</area> <area>member</area>
</areas> </areas>
<tab caption="Get Started"> <tab caption="Get Started">
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/members/membersdashboardvideos.html views/dashboard/members/membersdashboardvideos.html
</control> </control>
</tab> </tab>

View File

@@ -5,7 +5,7 @@
<area>settings</area> <area>settings</area>
</areas> </areas>
<tab caption="Welcome"> <tab caption="Welcome">
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/settings/settingsdashboardintro.html views/dashboard/settings/settingsdashboardintro.html
</control> </control>
</tab> </tab>
@@ -25,7 +25,7 @@
<area>forms</area> <area>forms</area>
</areas> </areas>
<tab caption="Install Umbraco Forms"> <tab caption="Install Umbraco Forms">
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/forms/formsdashboardintro.html views/dashboard/forms/formsdashboardintro.html
</control> </control>
</tab> </tab>
@@ -35,7 +35,7 @@
<area>media</area> <area>media</area>
</areas> </areas>
<tab caption="Content"> <tab caption="Content">
<control showOnce="false" addPanel="false" panelCaption=""> <control panelCaption="">
views/dashboard/media/mediafolderbrowser.html views/dashboard/media/mediafolderbrowser.html
</control> </control>
</tab> </tab>
@@ -45,7 +45,7 @@
<area>forms</area> <area>forms</area>
</areas> </areas>
<tab caption="Install Umbraco Forms"> <tab caption="Install Umbraco Forms">
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/forms/formsdashboardintro.html views/dashboard/forms/formsdashboardintro.html
</control> </control>
</tab> </tab>
@@ -61,7 +61,7 @@
<access> <access>
<grant>admin</grant> <grant>admin</grant>
</access> </access>
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/default/startupdashboardintro.html views/dashboard/default/startupdashboardintro.html
</control> </control>
</tab> </tab>
@@ -71,7 +71,7 @@
<area>member</area> <area>member</area>
</areas> </areas>
<tab caption="Get Started"> <tab caption="Get Started">
<control showOnce="true" addPanel="true" panelCaption=""> <control panelCaption="">
views/dashboard/members/membersdashboardvideos.html views/dashboard/members/membersdashboardvideos.html
</control> </control>
</tab> </tab>

View File

@@ -3,8 +3,6 @@ using Umbraco.Core;
using Umbraco.Core.Configuration; using Umbraco.Core.Configuration;
using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Mvc; using Umbraco.Web.Mvc;
using System.Linq;
using Umbraco.Core.IO;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Net.Http; using System.Net.Http;
@@ -27,6 +25,13 @@ namespace Umbraco.Web.Editors
[WebApi.UmbracoAuthorize] [WebApi.UmbracoAuthorize]
public class DashboardController : UmbracoApiController public class DashboardController : UmbracoApiController
{ {
private readonly DashboardHelper _dashboardHelper;
public DashboardController(DashboardHelper dashboardHelper)
{
_dashboardHelper = dashboardHelper;
}
//we have just one instance of HttpClient shared for the entire application //we have just one instance of HttpClient shared for the entire application
private static readonly HttpClient HttpClient = new HttpClient(); private static readonly HttpClient HttpClient = new HttpClient();
//we have baseurl as a param to make previewing easier, so we can test with a dev domain from client side //we have baseurl as a param to make previewing easier, so we can test with a dev domain from client side
@@ -119,8 +124,7 @@ namespace Umbraco.Web.Editors
[ValidateAngularAntiForgeryToken] [ValidateAngularAntiForgeryToken]
public IEnumerable<Tab<DashboardControl>> GetDashboard(string section) public IEnumerable<Tab<DashboardControl>> GetDashboard(string section)
{ {
var dashboardHelper = new DashboardHelper(ApplicationContext); return _dashboardHelper.GetDashboard(section, Security.CurrentUser);
return dashboardHelper.GetDashboard(section, Security.CurrentUser);
} }
} }
} }

View File

@@ -2,9 +2,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Newtonsoft.Json.Linq;
using Umbraco.Core; using Umbraco.Core;
using Umbraco.Core.Configuration; using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.Dashboard;
using Umbraco.Core.IO; using Umbraco.Core.IO;
using Umbraco.Core.Manifest; using Umbraco.Core.Manifest;
using Umbraco.Core.Models.Membership; using Umbraco.Core.Models.Membership;
@@ -13,14 +13,17 @@ using Umbraco.Web.Models.ContentEditing;
namespace Umbraco.Web.Editors namespace Umbraco.Web.Editors
{ {
internal class DashboardHelper public class DashboardHelper
{ {
private readonly ApplicationContext _appContext; private readonly ISectionService _sectionService;
private readonly IDashboardSection _dashboardSection;
private readonly ManifestParser _manifestParser;
public DashboardHelper(ApplicationContext appContext) public DashboardHelper(ISectionService sectionService, IDashboardSection dashboardSection, ManifestParser manifestParser)
{ {
if (appContext == null) throw new ArgumentNullException("appContext"); _sectionService = sectionService ?? throw new ArgumentNullException(nameof(sectionService));
_appContext = appContext; _dashboardSection = dashboardSection;
_manifestParser = manifestParser;
} }
/// <summary> /// <summary>
@@ -31,7 +34,7 @@ namespace Umbraco.Web.Editors
public IDictionary<string, IEnumerable<Tab<DashboardControl>>> GetDashboards(IUser currentUser) public IDictionary<string, IEnumerable<Tab<DashboardControl>>> GetDashboards(IUser currentUser)
{ {
var result = new Dictionary<string, IEnumerable<Tab<DashboardControl>>>(); var result = new Dictionary<string, IEnumerable<Tab<DashboardControl>>>();
foreach (var section in _appContext.Services.SectionService.GetSections()) foreach (var section in _sectionService.GetSections())
{ {
result[section.Alias] = GetDashboard(section.Alias, currentUser); result[section.Alias] = GetDashboard(section.Alias, currentUser);
} }
@@ -87,24 +90,24 @@ namespace Umbraco.Web.Editors
//disable packages section dashboard //disable packages section dashboard
if (section == "packages") return tabs; if (section == "packages") return tabs;
foreach (var dashboardSection in UmbracoConfig.For.DashboardSettings().Sections.Where(x => x.Areas.Contains(section))) foreach (var dashboardSection in _dashboardSection.Sections.Where(x => x.Areas.Contains(section)))
{ {
//we need to validate access to this section //we need to validate access to this section
if (DashboardSecurity.AuthorizeAccess(dashboardSection, currentUser, _appContext.Services.SectionService) == false) if (DashboardSecurity.AuthorizeAccess(dashboardSection, currentUser, _sectionService) == false)
continue; continue;
//User is authorized //User is authorized
foreach (var tab in dashboardSection.Tabs) foreach (var tab in dashboardSection.Tabs)
{ {
//we need to validate access to this tab //we need to validate access to this tab
if (DashboardSecurity.AuthorizeAccess(tab, currentUser, _appContext.Services.SectionService) == false) if (DashboardSecurity.AuthorizeAccess(tab, currentUser, _sectionService) == false)
continue; continue;
var dashboardControls = new List<DashboardControl>(); var dashboardControls = new List<DashboardControl>();
foreach (var control in tab.Controls) foreach (var control in tab.Controls)
{ {
if (DashboardSecurity.AuthorizeAccess(control, currentUser, _appContext.Services.SectionService) == false) if (DashboardSecurity.AuthorizeAccess(control, currentUser, _sectionService) == false)
continue; continue;
var dashboardControl = new DashboardControl(); var dashboardControl = new DashboardControl();
@@ -112,7 +115,7 @@ namespace Umbraco.Web.Editors
dashboardControl.Caption = control.PanelCaption; dashboardControl.Caption = control.PanelCaption;
dashboardControl.Path = IOHelper.FindFile(controlPath); dashboardControl.Path = IOHelper.FindFile(controlPath);
if (controlPath.ToLowerInvariant().EndsWith(".ascx".ToLowerInvariant())) if (controlPath.ToLowerInvariant().EndsWith(".ascx".ToLowerInvariant()))
dashboardControl.ServerSide = true; throw new NotSupportedException("Legacy UserControl (.ascx) dashboards are no longer supported");
dashboardControls.Add(dashboardControl); dashboardControls.Add(dashboardControl);
} }
@@ -138,13 +141,11 @@ namespace Umbraco.Web.Editors
//TODO: Need to integrate the security with the manifest dashboards //TODO: Need to integrate the security with the manifest dashboards
var appPlugins = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.AppPlugins)); var appPlugins = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.AppPlugins));
var parser = new ManifestParser(appPlugins, _appContext.ApplicationCache.RuntimeCache);
var builder = new ManifestBuilder(_appContext.ApplicationCache.RuntimeCache, parser);
var tabs = new List<Tab<DashboardControl>>(); var tabs = new List<Tab<DashboardControl>>();
var i = startTabId; var i = startTabId;
foreach (var sectionDashboard in builder.Dashboards.Where(x => x.Value.Areas.InvariantContains(section))) foreach (var sectionDashboard in _manifestParser.Manifest.Dashboards.Where(x => x.Value.Areas.InvariantContains(section)))
{ {
foreach (var tab in sectionDashboard.Value.Tabs) foreach (var tab in sectionDashboard.Value.Tabs)
{ {
@@ -157,7 +158,7 @@ namespace Umbraco.Web.Editors
dashboardControl.Caption = control.Caption; dashboardControl.Caption = control.Caption;
dashboardControl.Path = IOHelper.FindFile(controlPath); dashboardControl.Path = IOHelper.FindFile(controlPath);
if (controlPath.ToLowerInvariant().EndsWith(".ascx".ToLowerInvariant())) if (controlPath.ToLowerInvariant().EndsWith(".ascx".ToLowerInvariant()))
dashboardControl.ServerSide = true; throw new NotSupportedException("Legacy UserControl (.ascx) dashboards are no longer supported");
dashboardControls.Add(dashboardControl); dashboardControls.Add(dashboardControl);
} }

View File

@@ -17,17 +17,20 @@ namespace Umbraco.Web.Editors
[PluginController("UmbracoApi")] [PluginController("UmbracoApi")]
public class SectionController : UmbracoAuthorizedJsonController public class SectionController : UmbracoAuthorizedJsonController
{ {
private readonly DashboardHelper _dashboardHelper;
public SectionController(DashboardHelper dashboardHelper)
{
_dashboardHelper = dashboardHelper;
}
public IEnumerable<Section> GetSections() public IEnumerable<Section> GetSections()
{ {
var sections = Services.SectionService.GetAllowedSections(Security.GetUserId().ResultOr(0)); var sections = Services.SectionService.GetAllowedSections(Security.GetUserId().ResultOr(0));
var sectionModels = sections.Select(Mapper.Map<Core.Models.Section, Section>).ToArray(); var sectionModels = sections.Select(Mapper.Map<Core.Models.Section, Section>).ToArray();
//Check if there are empty dashboards or dashboards that will end up empty based on the current user's access
//and add the meta data about them
var dashboardHelper = new DashboardHelper(ApplicationContext);
// this is a bit nasty since we'll be proxying via the app tree controller but we sort of have to do that // this is a bit nasty since we'll be proxying via the app tree controller but we sort of have to do that
// since tree's by nature are controllers and require request contextual data - and then we have to // since tree's by nature are controllers and require request contextual data - and then we have to
// remember to inject properties - nasty indeed // remember to inject properties - nasty indeed
@@ -36,7 +39,7 @@ namespace Umbraco.Web.Editors
Current.Container.InjectProperties(appTreeController); Current.Container.InjectProperties(appTreeController);
appTreeController.ControllerContext = ControllerContext; appTreeController.ControllerContext = ControllerContext;
var dashboards = dashboardHelper.GetDashboards(Security.CurrentUser); var dashboards = _dashboardHelper.GetDashboards(Security.CurrentUser);
//now we can add metadata for each section so that the UI knows if there's actually anything at all to render for //now we can add metadata for each section so that the UI knows if there's actually anything at all to render for
//a dashboard for a given section, then the UI can deal with it accordingly (i.e. redirect to the first tree) //a dashboard for a given section, then the UI can deal with it accordingly (i.e. redirect to the first tree)
foreach (var section in sectionModels) foreach (var section in sectionModels)

View File

@@ -10,15 +10,6 @@ namespace Umbraco.Web.Models.ContentEditing
[DataContract(Name = "control", Namespace = "")] [DataContract(Name = "control", Namespace = "")]
public class DashboardControl public class DashboardControl
{ {
[DataMember(Name = "showOnce")]
public bool ShowOnce { get; set; }
[DataMember(Name = "addPanel")]
public bool AddPanel { get; set; }
[DataMember(Name = "serverSide")]
public bool ServerSide { get; set; }
[DataMember(Name = "path")] [DataMember(Name = "path")]
public string Path { get; set; } public string Path { get; set; }

View File

@@ -208,6 +208,8 @@ namespace Umbraco.Web.Runtime
.Append<ListViewContentAppDefinition>() .Append<ListViewContentAppDefinition>()
.Append<ContentEditorContentAppDefinition>() .Append<ContentEditorContentAppDefinition>()
.Append<ContentInfoContentAppDefinition>(); .Append<ContentInfoContentAppDefinition>();
composition.Container.RegisterSingleton<DashboardHelper>();
} }
internal void Initialize( internal void Initialize(