From 4960e2c668aed5c6c522fa7be85243b42720d78d Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 26 Jun 2020 08:45:13 -0400 Subject: [PATCH 1/6] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ec9fb2c7..180db82e 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ Control panel for adding, editing, and deleting pages as well as adding new modu ![Manage Page](https://github.com/oqtane/framework/blob/master/screenshots/screenshot5.png?raw=true "Manage Page") -Admin dashboard for accessing the variuous administrative features of the framework: +Admin dashboard for accessing the various administrative features of the framework: ![Admin Dashboard](https://github.com/oqtane/framework/blob/master/screenshots/screenshot6.png?raw=true "Admin Dashboard") From fdc39d57fb3599b616e784bcae47931791464590 Mon Sep 17 00:00:00 2001 From: Michael Atwood Date: Sat, 27 Jun 2020 11:49:24 -0700 Subject: [PATCH 2/6] Module Router Enhancement Allows for PageVariables through the URL --- Oqtane.Client/UI/PageState.cs | 3 +- Oqtane.Client/UI/SiteRouter.razor | 115 ++++++++++++++++++++++-------- Oqtane.Server/appsettings.json | 2 +- Oqtane.Shared/Shared/Constants.cs | 4 +- Oqtane.Shared/Shared/Utilities.cs | 12 ++-- 5 files changed, 99 insertions(+), 37 deletions(-) diff --git a/Oqtane.Client/UI/PageState.cs b/Oqtane.Client/UI/PageState.cs index a2678802..14b15bbc 100644 --- a/Oqtane.Client/UI/PageState.cs +++ b/Oqtane.Client/UI/PageState.cs @@ -14,10 +14,11 @@ namespace Oqtane.UI public List Modules { get; set; } public Uri Uri { get; set; } public Dictionary QueryString { get; set; } + public Dictionary PageVariables { get; set; } public int ModuleId { get; set; } public string Action { get; set; } public bool EditMode { get; set; } public DateTime LastSyncDate { get; set; } public Runtime Runtime { get; set; } } -} +} \ No newline at end of file diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index c3142689..3503cb77 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -75,6 +75,7 @@ Page page; User user = null; List modules; + Dictionary pageVariables = new Dictionary(); var moduleid = -1; var action = ""; var editmode = false; @@ -179,23 +180,33 @@ // extract admin route elements from path var segments = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); int result; - // check if path has moduleid and action specification ie. pagename/moduleid/action/ - if (segments.Length >= 2 && int.TryParse(segments[segments.Length - 2], out result)) + + int modIdPos = 0; + + for (int i = 0; i < segments.Length; i++) { - action = segments[segments.Length - 1]; - moduleid = result; - path = path.Replace(moduleid.ToString() + "/" + action + "/", ""); - } - else - { - // check if path has moduleid specification ie. pagename/moduleid/ - if (segments.Length >= 1 && int.TryParse(segments[segments.Length - 1], out result)) + if (segments[i] == Constants.ModuleSegment) { - moduleid = result; - path = path.Replace(moduleid.ToString() + "/", ""); + modIdPos = i + 1; + } + + if (i > modIdPos && modIdPos != 0) + { + action += segments[i] + "/"; } } + // check if path has moduleid and action specification ie. pagename/moduleid/action/ + if (modIdPos > 0) + { + int.TryParse(segments[modIdPos], out result); + moduleid = result; + path = path.Replace(segments[modIdPos - 1] + "/" + segments[modIdPos] + "/" + action, ""); + + } + + if (action.EndsWith("/")) action = action.Substring(0, action.Length - 1); + // remove trailing slash so it can be used as a key for Pages if (path.EndsWith("/")) path = path.Substring(0, path.Length - 1); @@ -246,7 +257,7 @@ if (PageState == null || reload >= Reload.Page) { modules = await ModuleService.GetModulesAsync(site.SiteId); - (page, modules) = ProcessModules(page, modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType); + (page, modules, pageVariables) = ProcessModules(page, modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType); } else { @@ -263,6 +274,7 @@ Modules = modules, Uri = new Uri(_absoluteUri, UriKind.Absolute), QueryString = querystring, + PageVariables = pageVariables, ModuleId = moduleid, Action = action, EditMode = editmode, @@ -314,9 +326,12 @@ return Task.CompletedTask; } - private Dictionary ParseQueryString(string query) + private Dictionary + ParseQueryString(string query) { - Dictionary querystring = new Dictionary(); + Dictionary + querystring = new Dictionary + (); if (!string.IsNullOrEmpty(query)) { query = query.Substring(1); // ignore "?" @@ -339,7 +354,8 @@ return querystring; } - private async Task ProcessPage(Page page, Site site, User user) + private async Task + ProcessPage(Page page, Site site, User user) { try { @@ -355,8 +371,10 @@ page.LayoutType = site.DefaultLayoutType; } - page.Panes = new List(); - page.Resources = new List(); + page.Panes = new List + (); + page.Resources = new List + (); string panes = ""; Type themetype = Type.GetType(page.ThemeType); @@ -393,9 +411,12 @@ return page; } - private (Page Page, List Modules) ProcessModules(Page page, List modules, int moduleid, string action, string defaultcontainertype) + private (Page Page, List + Modules, Dictionary PageVariables) ProcessModules(Page page, List + modules, int moduleid, string action, string defaultcontainertype) { var paneindex = new Dictionary(); + var pageVariables = new Dictionary(); foreach (Module module in modules) { if (module.PageId == page.PageId || module.ModuleId == moduleid) @@ -410,17 +431,52 @@ typename = Constants.ErrorModule; } + var pages = action.Split('/', StringSplitOptions.RemoveEmptyEntries); + if (module.ModuleId == moduleid && action != "") { // check if the module defines custom routes if (module.ModuleDefinition.ControlTypeRoutes != "") { - foreach (string route in module.ModuleDefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) + var controlTypeRoutes = module.ModuleDefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); + foreach (string route in controlTypeRoutes) { - if (route.StartsWith(action + "=")) + var pageAction = route.Split('=')[0]; + + var routes = pageAction.Split('/', StringSplitOptions.RemoveEmptyEntries); + var newRoute = ""; + if (pages.Length == routes.Length) { - typename = route.Replace(action + "=", ""); + for (int i = 0; i < pages.Length; i++) + { + if (pages.Length > i) + { + if (routes[i] == pages[i]) + { + newRoute += pages[i] + "/"; + } + else if (routes[i].StartsWith("[") && routes[i].EndsWith("]")) + { + newRoute += pages[i] + "/"; + var key = routes[i].Replace("[", ""); + key = key.Replace("]", ""); + pageVariables.TryAdd(key, pages[i]); + } + else + { + i = pages.Length; + newRoute = ""; + } + + } + } + + if (newRoute != "") + { + typename = route.Replace(pageAction + "=", ""); + } } + } } module.ModuleType = typename.Replace(Constants.ActionToken, action); @@ -489,10 +545,13 @@ module.PaneModuleCount = paneindex[module.Pane.ToLower()] + 1; } - return (page, modules); + return (page, modules, pageVariables); } - private List ManagePageResources(List pageresources, List resources) + private List + ManagePageResources(List + pageresources, List + resources) { if (resources != null) { @@ -509,7 +568,7 @@ } private Runtime GetRuntime() -=> RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")) - ? Runtime.WebAssembly - : Runtime.Server; -} + => RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")) + ? Runtime.WebAssembly + : Runtime.Server; +} \ No newline at end of file diff --git a/Oqtane.Server/appsettings.json b/Oqtane.Server/appsettings.json index 0ab499f0..4b88e95c 100644 --- a/Oqtane.Server/appsettings.json +++ b/Oqtane.Server/appsettings.json @@ -1,6 +1,6 @@ { "ConnectionStrings": { - "DefaultConnection": "" + "DefaultConnection": "Data Source=(LocalDb)\\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\\Oqtane.mdf;Initial Catalog=Oqtane;Integrated Security=SSPI;" }, "Runtime": "Server", "Installation": { diff --git a/Oqtane.Shared/Shared/Constants.cs b/Oqtane.Shared/Shared/Constants.cs index 0ce9743b..3e02a938 100644 --- a/Oqtane.Shared/Shared/Constants.cs +++ b/Oqtane.Shared/Shared/Constants.cs @@ -19,6 +19,7 @@ namespace Oqtane.Shared public const string ActionToken = "{Action}"; public const string DefaultAction = "Index"; public const string AdminPane = "Admin"; + public const string ModuleSegment = "module"; // Default Module Actions are reserved and should not be used by modules public static readonly string[] DefaultModuleActions = new[] { "Settings", "Import", "Export" }; @@ -46,6 +47,7 @@ namespace Oqtane.Shared public const string ImageFiles = "jpg,jpeg,jpe,gif,bmp,png"; public const string UploadableFiles = "jpg,jpeg,jpe,gif,bmp,png,mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg"; public const string ReservedDevices = "CON,NUL,PRN,COM0,COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8,COM9,LPT0,LPT1,LPT2,LPT3,LPT4,LPT5,LPT6,LPT7,LPT8,LPT9,CONIN$,CONOUT$"; + public static readonly char[] InvalidFileNameChars = { '\"', '<', '>', '|', '\0', (Char) 1, (Char) 2, (Char) 3, (Char) 4, (Char) 5, (Char) 6, (Char) 7, (Char) 8, @@ -55,4 +57,4 @@ namespace Oqtane.Shared }; public static readonly string[] InvalidFileNameEndingChars = { ".", " " }; } -} +} \ No newline at end of file diff --git a/Oqtane.Shared/Shared/Utilities.cs b/Oqtane.Shared/Shared/Utilities.cs index 04f3ea1e..5efe5c38 100644 --- a/Oqtane.Shared/Shared/Utilities.cs +++ b/Oqtane.Shared/Shared/Utilities.cs @@ -39,7 +39,7 @@ namespace Oqtane.Shared { if (moduleid != -1) { - path += $"/{moduleid}"; + path += $"/{Constants.ModuleSegment}/{moduleid}"; if (!string.IsNullOrEmpty(action)) { path += $"/{action}"; @@ -136,6 +136,7 @@ namespace Oqtane.Shared stringBuilder.Append(RemapInternationalCharToAscii(c)); prevdash = false; break; + case UnicodeCategory.SpaceSeparator: case UnicodeCategory.ConnectorPunctuation: case UnicodeCategory.DashPunctuation: @@ -250,7 +251,7 @@ namespace Oqtane.Shared public static string PathCombine(params string[] segments) { - var separators = new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar}; + var separators = new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }; for (int i = 1; i < segments.Length; i++) { @@ -284,7 +285,6 @@ namespace Oqtane.Shared !Constants.ReservedDevices.Split(',').Contains(name.ToUpper().Split('.')[0])); } - public static bool TryGetQueryValue( this Uri uri, string key, @@ -304,7 +304,7 @@ namespace Oqtane.Shared { value = defaultValue; string s; - return uri.TryGetQueryValue(key, out s, (string) null) && int.TryParse(s, out value); + return uri.TryGetQueryValue(key, out s, (string)null) && int.TryParse(s, out value); } public static Dictionary ParseQueryString(string query) @@ -314,7 +314,7 @@ namespace Oqtane.Shared { query = query.Substring(1); string str = query; - char[] separator = new char[1] {'&'}; + char[] separator = new char[1] { '&' }; foreach (string key in str.Split(separator, StringSplitOptions.RemoveEmptyEntries)) { if (key != "") @@ -333,4 +333,4 @@ namespace Oqtane.Shared return dictionary; } } -} +} \ No newline at end of file From c5037e7084046e5c6bcb38b1b507025de31707b7 Mon Sep 17 00:00:00 2001 From: Michael Atwood Date: Tue, 30 Jun 2020 03:41:35 -0700 Subject: [PATCH 3/6] Url parameters working on any page, plus queries and anchors --- Oqtane.Client/UI/PageState.cs | 3 +- Oqtane.Client/UI/SiteRouter.razor | 117 ++++++++++++------------------ Oqtane.Server/appsettings.json | 2 +- Oqtane.Shared/Shared/Constants.cs | 3 +- Oqtane.Shared/Shared/Utilities.cs | 52 ++++++++++++- 5 files changed, 100 insertions(+), 77 deletions(-) diff --git a/Oqtane.Client/UI/PageState.cs b/Oqtane.Client/UI/PageState.cs index 14b15bbc..7bc56ed8 100644 --- a/Oqtane.Client/UI/PageState.cs +++ b/Oqtane.Client/UI/PageState.cs @@ -14,7 +14,8 @@ namespace Oqtane.UI public List Modules { get; set; } public Uri Uri { get; set; } public Dictionary QueryString { get; set; } - public Dictionary PageVariables { get; set; } + public string UrlParameters { get; set; } + public string Anchor { get; set; } public int ModuleId { get; set; } public string Action { get; set; } public bool EditMode { get; set; } diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index 3503cb77..d7f8b931 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -75,9 +75,10 @@ Page page; User user = null; List modules; - Dictionary pageVariables = new Dictionary(); var moduleid = -1; - var action = ""; + var action = string.Empty; + var urlparameters = string.Empty; + var anchor = string.Empty; var editmode = false; var reload = Reload.None; var lastsyncdate = DateTime.UtcNow; @@ -88,6 +89,12 @@ // get path var path = uri.LocalPath.Substring(1); + //set anchor + if (uri.Fragment.StartsWith('#')) + { + anchor = uri.Fragment.Remove(0, 1); + } + // parse querystring var querystring = ParseQueryString(uri.Query); @@ -182,18 +189,29 @@ int result; int modIdPos = 0; + int actionPos = 0; + int ulrParametersPos = 0; for (int i = 0; i < segments.Length; i++) { - if (segments[i] == Constants.ModuleSegment) + + if (segments[i] == Constants.UrlParametersDelimiter) { - modIdPos = i + 1; + ulrParametersPos = i + 1; } - if (i > modIdPos && modIdPos != 0) + if (i >= ulrParametersPos && ulrParametersPos != 0) { - action += segments[i] + "/"; + urlparameters += "/" + segments[i]; } + + if (segments[i] == Constants.ModuleDelimiter) + { + modIdPos = i + 1; + actionPos = modIdPos + 1; + action = segments[actionPos]; + } + } // check if path has moduleid and action specification ie. pagename/moduleid/action/ @@ -201,11 +219,14 @@ { int.TryParse(segments[modIdPos], out result); moduleid = result; - path = path.Replace(segments[modIdPos - 1] + "/" + segments[modIdPos] + "/" + action, ""); + path = path.Replace("/" + segments[modIdPos - 1] + "/" + segments[modIdPos] + "/" + segments[actionPos], ""); } - if (action.EndsWith("/")) action = action.Substring(0, action.Length - 1); + if (ulrParametersPos > 0) + { + path = path.Replace("/" + segments[ulrParametersPos - 1] + urlparameters, ""); + } // remove trailing slash so it can be used as a key for Pages if (path.EndsWith("/")) path = path.Substring(0, path.Length - 1); @@ -257,7 +278,7 @@ if (PageState == null || reload >= Reload.Page) { modules = await ModuleService.GetModulesAsync(site.SiteId); - (page, modules, pageVariables) = ProcessModules(page, modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType); + (page, modules) = ProcessModules(page, modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType); } else { @@ -274,7 +295,8 @@ Modules = modules, Uri = new Uri(_absoluteUri, UriKind.Absolute), QueryString = querystring, - PageVariables = pageVariables, + UrlParameters = urlparameters, + Anchor = anchor, ModuleId = moduleid, Action = action, EditMode = editmode, @@ -326,12 +348,9 @@ return Task.CompletedTask; } - private Dictionary - ParseQueryString(string query) + private Dictionary ParseQueryString(string query) { - Dictionary - querystring = new Dictionary - (); + Dictionary querystring = new Dictionary(); if (!string.IsNullOrEmpty(query)) { query = query.Substring(1); // ignore "?" @@ -354,8 +373,7 @@ return querystring; } - private async Task - ProcessPage(Page page, Site site, User user) + private async Task ProcessPage(Page page, Site site, User user) { try { @@ -371,10 +389,8 @@ page.LayoutType = site.DefaultLayoutType; } - page.Panes = new List - (); - page.Resources = new List - (); + page.Panes = new List(); + page.Resources = new List(); string panes = ""; Type themetype = Type.GetType(page.ThemeType); @@ -411,12 +427,9 @@ return page; } - private (Page Page, List - Modules, Dictionary PageVariables) ProcessModules(Page page, List - modules, int moduleid, string action, string defaultcontainertype) + private (Page Page, List Modules) ProcessModules(Page page, List modules, int moduleid, string action, string defaultcontainertype) { var paneindex = new Dictionary(); - var pageVariables = new Dictionary(); foreach (Module module in modules) { if (module.PageId == page.PageId || module.ModuleId == moduleid) @@ -431,52 +444,17 @@ typename = Constants.ErrorModule; } - var pages = action.Split('/', StringSplitOptions.RemoveEmptyEntries); - if (module.ModuleId == moduleid && action != "") { // check if the module defines custom routes if (module.ModuleDefinition.ControlTypeRoutes != "") { - var controlTypeRoutes = module.ModuleDefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); - foreach (string route in controlTypeRoutes) + foreach (string route in module.ModuleDefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { - var pageAction = route.Split('=')[0]; - - var routes = pageAction.Split('/', StringSplitOptions.RemoveEmptyEntries); - var newRoute = ""; - if (pages.Length == routes.Length) + if (route.StartsWith(action + "=")) { - for (int i = 0; i < pages.Length; i++) - { - if (pages.Length > i) - { - if (routes[i] == pages[i]) - { - newRoute += pages[i] + "/"; - } - else if (routes[i].StartsWith("[") && routes[i].EndsWith("]")) - { - newRoute += pages[i] + "/"; - var key = routes[i].Replace("[", ""); - key = key.Replace("]", ""); - pageVariables.TryAdd(key, pages[i]); - } - else - { - i = pages.Length; - newRoute = ""; - } - - } - } - - if (newRoute != "") - { - typename = route.Replace(pageAction + "=", ""); - } + typename = route.Replace(action + "=", ""); } - } } module.ModuleType = typename.Replace(Constants.ActionToken, action); @@ -545,13 +523,10 @@ module.PaneModuleCount = paneindex[module.Pane.ToLower()] + 1; } - return (page, modules, pageVariables); + return (page, modules); } - private List - ManagePageResources(List - pageresources, List - resources) + private List ManagePageResources(List pageresources, List resources) { if (resources != null) { @@ -568,7 +543,7 @@ } private Runtime GetRuntime() - => RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")) - ? Runtime.WebAssembly - : Runtime.Server; +=> RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")) + ? Runtime.WebAssembly + : Runtime.Server; } \ No newline at end of file diff --git a/Oqtane.Server/appsettings.json b/Oqtane.Server/appsettings.json index 4b88e95c..0ab499f0 100644 --- a/Oqtane.Server/appsettings.json +++ b/Oqtane.Server/appsettings.json @@ -1,6 +1,6 @@ { "ConnectionStrings": { - "DefaultConnection": "Data Source=(LocalDb)\\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\\Oqtane.mdf;Initial Catalog=Oqtane;Integrated Security=SSPI;" + "DefaultConnection": "" }, "Runtime": "Server", "Installation": { diff --git a/Oqtane.Shared/Shared/Constants.cs b/Oqtane.Shared/Shared/Constants.cs index 3e02a938..77f7dc68 100644 --- a/Oqtane.Shared/Shared/Constants.cs +++ b/Oqtane.Shared/Shared/Constants.cs @@ -19,7 +19,8 @@ namespace Oqtane.Shared public const string ActionToken = "{Action}"; public const string DefaultAction = "Index"; public const string AdminPane = "Admin"; - public const string ModuleSegment = "module"; + public const string ModuleDelimiter = "*"; + public const string UrlParametersDelimiter = "!"; // Default Module Actions are reserved and should not be used by modules public static readonly string[] DefaultModuleActions = new[] { "Settings", "Import", "Export" }; diff --git a/Oqtane.Shared/Shared/Utilities.cs b/Oqtane.Shared/Shared/Utilities.cs index 5efe5c38..ce5255a3 100644 --- a/Oqtane.Shared/Shared/Utilities.cs +++ b/Oqtane.Shared/Shared/Utilities.cs @@ -20,8 +20,53 @@ namespace Oqtane.Shared return $"{type.Namespace}, {assemblyName}"; } + public static (string UrlParameters, string Querystring, string Anchor) ParseParameters(string parameters) + { + // /urlparameters /urlparameters?Id=1 /urlparameters#5 /urlparameters?Id=1#5 /urlparameters?reload#5 + + // Id=1 Id=1#5 reload#5 reload + + // #5 + + var urlparameters = string.Empty; + var querystring = string.Empty; + var anchor = string.Empty; + + if (parameters.Contains('#')) + { + anchor = parameters.Split('#').Last(); + parameters = parameters.Replace("#" + anchor, ""); + } + + if (parameters.Contains('?')) + { + urlparameters = parameters.Split('?').First(); + querystring = parameters.Replace(urlparameters + "?", ""); + } + else if (parameters.Contains('/')) + { + urlparameters = parameters; + } + else + { + querystring = parameters; + } + + return (urlparameters, querystring, anchor); + } + public static string NavigateUrl(string alias, string path, string parameters) { + string urlparameters; + string querystring; + string anchor; + (urlparameters, querystring, anchor) = ParseParameters(parameters); + + if (!string.IsNullOrEmpty(urlparameters)) + { + if (urlparameters.StartsWith("/")) urlparameters = urlparameters.Remove(0, 1); + path += $"/{Constants.UrlParametersDelimiter}/{urlparameters}"; + } var uriBuilder = new UriBuilder { Path = !string.IsNullOrEmpty(alias) @@ -29,17 +74,18 @@ namespace Oqtane.Shared ? $"{alias}/{path}" : $"{alias}" : $"{path}", - Query = parameters + Query = querystring, }; - return uriBuilder.Uri.PathAndQuery; + var navigateUrl = uriBuilder.Uri.PathAndQuery + "#" + anchor; + return navigateUrl; } public static string EditUrl(string alias, string path, int moduleid, string action, string parameters) { if (moduleid != -1) { - path += $"/{Constants.ModuleSegment}/{moduleid}"; + path += $"/{Constants.ModuleDelimiter}/{moduleid}"; if (!string.IsNullOrEmpty(action)) { path += $"/{action}"; From cb2d52968951b6adb6fb3b3955d182008ea19cb6 Mon Sep 17 00:00:00 2001 From: Michael Atwood Date: Tue, 30 Jun 2020 04:16:08 -0700 Subject: [PATCH 4/6] added in GetUrlParameters route to Module Index action --- Oqtane.Client/Modules/ModuleBase.cs | 43 ++++++++++++++++++++++++++--- Oqtane.Client/UI/SiteRouter.razor | 19 +++++++++++-- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/Oqtane.Client/Modules/ModuleBase.cs b/Oqtane.Client/Modules/ModuleBase.cs index f36a04ae..84aa19f6 100644 --- a/Oqtane.Client/Modules/ModuleBase.cs +++ b/Oqtane.Client/Modules/ModuleBase.cs @@ -17,7 +17,7 @@ namespace Oqtane.Modules private Logger _logger; protected Logger logger => _logger ?? (_logger = new Logger(this)); - + [Inject] protected ILogService LoggingService { get; set; } @@ -30,7 +30,7 @@ namespace Oqtane.Modules [CascadingParameter] protected Module ModuleState { get; set; } - [CascadingParameter] + [CascadingParameter] protected ModuleInstance ModuleInstance { get; set; } // optional interface properties @@ -62,7 +62,7 @@ namespace Oqtane.Modules } } } - + // path method public string ModulePath() @@ -116,6 +116,38 @@ namespace Oqtane.Modules return Utilities.ContentUrl(PageState.Alias, fileid); } + public Dictionary GetUrlParameters(string parameterTemplate) + { + var urlParameters = new Dictionary(); + + var templateSegments = parameterTemplate.Split('/', StringSplitOptions.RemoveEmptyEntries); + var parameters = PageState.UrlParameters.Split('/', StringSplitOptions.RemoveEmptyEntries); + + if (parameters.Length == templateSegments.Length) + { + for (int i = 0; i < parameters.Length; i++) + { + if (parameters.Length > i) + { + if (templateSegments[i] == parameters[i]) + { + } + else if (templateSegments[i].StartsWith("[") && templateSegments[i].EndsWith("]")) + { + var key = templateSegments[i].Replace("[", ""); + key = key.Replace("]", ""); + urlParameters.TryAdd(key, parameters[i]); + } + else + { + i = parameters.Length; + } + } + } + } + return urlParameters; + } + // user feedback methods public void AddModuleMessage(string message, MessageType type) { @@ -154,12 +186,15 @@ namespace Oqtane.Modules case "add": logFunction = LogFunction.Create; break; + case "edit": logFunction = LogFunction.Update; break; + case "delete": logFunction = LogFunction.Delete; break; + default: logFunction = LogFunction.Read; break; @@ -241,4 +276,4 @@ namespace Oqtane.Modules } } } -} +} \ No newline at end of file diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index d7f8b931..75d9142c 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -209,7 +209,15 @@ { modIdPos = i + 1; actionPos = modIdPos + 1; - action = segments[actionPos]; + if (actionPos > segments.Length - 1) + { + action = Constants.DefaultAction; + } + else + { + action = segments[actionPos]; + + } } } @@ -219,7 +227,14 @@ { int.TryParse(segments[modIdPos], out result); moduleid = result; - path = path.Replace("/" + segments[modIdPos - 1] + "/" + segments[modIdPos] + "/" + segments[actionPos], ""); + if (actionPos > segments.Length - 1) + { + path = path.Replace("/" + segments[modIdPos - 1] + "/" + segments[modIdPos], ""); + } + else + { + path = path.Replace("/" + segments[modIdPos - 1] + "/" + segments[modIdPos] + "/" + segments[actionPos], ""); + } } From 5e816ea912e69ac46c4c47b724f34eb5b118bb00 Mon Sep 17 00:00:00 2001 From: Michael Atwood Date: Tue, 30 Jun 2020 12:49:56 -0700 Subject: [PATCH 5/6] Removed anchor property and hash is only set if there is anchor --- Oqtane.Client/UI/PageState.cs | 1 - Oqtane.Client/UI/SiteRouter.razor | 18 +++++------------- Oqtane.Shared/Shared/Utilities.cs | 4 ++-- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/Oqtane.Client/UI/PageState.cs b/Oqtane.Client/UI/PageState.cs index 7bc56ed8..cde1779b 100644 --- a/Oqtane.Client/UI/PageState.cs +++ b/Oqtane.Client/UI/PageState.cs @@ -15,7 +15,6 @@ namespace Oqtane.UI public Uri Uri { get; set; } public Dictionary QueryString { get; set; } public string UrlParameters { get; set; } - public string Anchor { get; set; } public int ModuleId { get; set; } public string Action { get; set; } public bool EditMode { get; set; } diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index 75d9142c..c7235c1f 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -78,7 +78,6 @@ var moduleid = -1; var action = string.Empty; var urlparameters = string.Empty; - var anchor = string.Empty; var editmode = false; var reload = Reload.None; var lastsyncdate = DateTime.UtcNow; @@ -89,12 +88,6 @@ // get path var path = uri.LocalPath.Substring(1); - //set anchor - if (uri.Fragment.StartsWith('#')) - { - anchor = uri.Fragment.Remove(0, 1); - } - // parse querystring var querystring = ParseQueryString(uri.Query); @@ -190,17 +183,17 @@ int modIdPos = 0; int actionPos = 0; - int ulrParametersPos = 0; + int urlParametersPos = 0; for (int i = 0; i < segments.Length; i++) { if (segments[i] == Constants.UrlParametersDelimiter) { - ulrParametersPos = i + 1; + urlParametersPos = i + 1; } - if (i >= ulrParametersPos && ulrParametersPos != 0) + if (i >= urlParametersPos && urlParametersPos != 0) { urlparameters += "/" + segments[i]; } @@ -238,9 +231,9 @@ } - if (ulrParametersPos > 0) + if (urlParametersPos > 0) { - path = path.Replace("/" + segments[ulrParametersPos - 1] + urlparameters, ""); + path = path.Replace("/" + segments[urlParametersPos - 1] + urlparameters, ""); } // remove trailing slash so it can be used as a key for Pages @@ -311,7 +304,6 @@ Uri = new Uri(_absoluteUri, UriKind.Absolute), QueryString = querystring, UrlParameters = urlparameters, - Anchor = anchor, ModuleId = moduleid, Action = action, EditMode = editmode, diff --git a/Oqtane.Shared/Shared/Utilities.cs b/Oqtane.Shared/Shared/Utilities.cs index ce5255a3..ea36861b 100644 --- a/Oqtane.Shared/Shared/Utilities.cs +++ b/Oqtane.Shared/Shared/Utilities.cs @@ -76,8 +76,8 @@ namespace Oqtane.Shared : $"{path}", Query = querystring, }; - - var navigateUrl = uriBuilder.Uri.PathAndQuery + "#" + anchor; + anchor = string.IsNullOrEmpty(anchor) ? "" : "#" + anchor; + var navigateUrl = uriBuilder.Uri.PathAndQuery + anchor; return navigateUrl; } From fccdd07a08d8dffd745e59ee4b9c16a9b28a6d04 Mon Sep 17 00:00:00 2001 From: Michael Atwood Date: Tue, 30 Jun 2020 12:59:19 -0700 Subject: [PATCH 6/6] Replaced token identifiers for { } --- Oqtane.Client/Modules/ModuleBase.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/Modules/ModuleBase.cs b/Oqtane.Client/Modules/ModuleBase.cs index 84aa19f6..1f6d38eb 100644 --- a/Oqtane.Client/Modules/ModuleBase.cs +++ b/Oqtane.Client/Modules/ModuleBase.cs @@ -132,10 +132,10 @@ namespace Oqtane.Modules if (templateSegments[i] == parameters[i]) { } - else if (templateSegments[i].StartsWith("[") && templateSegments[i].EndsWith("]")) + else if (templateSegments[i].StartsWith("{") && templateSegments[i].EndsWith("}")) { - var key = templateSegments[i].Replace("[", ""); - key = key.Replace("]", ""); + var key = templateSegments[i].Replace("{", ""); + key = key.Replace("}", ""); urlParameters.TryAdd(key, parameters[i]); } else