diff --git a/Oqtane.Client/Shared/ModuleInstance.razor b/Oqtane.Client/Shared/ModuleInstance.razor index 930b396c..c980a546 100644 --- a/Oqtane.Client/Shared/ModuleInstance.razor +++ b/Oqtane.Client/Shared/ModuleInstance.razor @@ -67,7 +67,7 @@ public void HideProgressIndicator() { - progressindicator = true; + progressindicator = false; StateHasChanged(); } } diff --git a/Oqtane.Client/Shared/Pane.razor b/Oqtane.Client/Shared/Pane.razor index e1f17c41..e943529b 100644 --- a/Oqtane.Client/Shared/Pane.razor +++ b/Oqtane.Client/Shared/Pane.razor @@ -117,7 +117,7 @@ } else { - foreach (Module module in PageState.Modules.Where(item => item.Pane.ToLower() == Name.ToLower()).OrderBy(x => x.Order).ToArray()) + foreach (Module module in PageState.Modules.Where(item => item.Pane.ToLower() == Name.ToLower() && !item.IsDeleted).OrderBy(x => x.Order).ToArray()) { // check if user is authorized to view module if (UserSecurity.IsAuthorized(PageState.User, "View", module.Permissions)) diff --git a/Oqtane.Client/Themes/Controls/ControlPanel.razor b/Oqtane.Client/Themes/Controls/ControlPanel.razor index 2ae00349..1053f9b7 100644 --- a/Oqtane.Client/Themes/Controls/ControlPanel.razor +++ b/Oqtane.Client/Themes/Controls/ControlPanel.razor @@ -196,6 +196,8 @@ pages.Add(p); } } + var panes = PageState.Page.Panes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); + pane = panes.Count() == 1 ? panes.SingleOrDefault() : ""; containers = ThemeService.GetContainerTypes(PageState.Themes); containertype = PageState.Site.DefaultContainerType; List modules = await ModuleService.GetModulesAsync(PageState.Site.SiteId, Constants.PageManagementModule); diff --git a/Oqtane.Client/Themes/Controls/ModuleActions.razor b/Oqtane.Client/Themes/Controls/ModuleActions.razor index 16ded142..c0c7fe31 100644 --- a/Oqtane.Client/Themes/Controls/ModuleActions.razor +++ b/Oqtane.Client/Themes/Controls/ModuleActions.razor @@ -23,7 +23,7 @@ } @code { - List actions; + List actions; protected override void OnParametersSet() { @@ -103,7 +103,8 @@ url = EditUrl(pagemodule.ModuleId, "Export"); break; case "delete": - await PageModuleService.DeletePageModuleAsync(pagemodule.PageModuleId); + pagemodule.IsDeleted = true; + await PageModuleService.UpdatePageModuleAsync(pagemodule); await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane); break; default: // move to pane diff --git a/Oqtane.Server/Controllers/ModuleController.cs b/Oqtane.Server/Controllers/ModuleController.cs index 896daf09..98cc0567 100644 --- a/Oqtane.Server/Controllers/ModuleController.cs +++ b/Oqtane.Server/Controllers/ModuleController.cs @@ -47,6 +47,7 @@ namespace Oqtane.Controllers module.CreatedOn = pagemodule.Module.CreatedOn; module.ModifiedBy = pagemodule.Module.ModifiedBy; module.ModifiedOn = pagemodule.Module.ModifiedOn; + module.IsDeleted = pagemodule.IsDeleted; module.PageModuleId = pagemodule.PageModuleId; module.ModuleId = pagemodule.ModuleId; diff --git a/Oqtane.Server/Repository/ModuleRepository.cs b/Oqtane.Server/Repository/ModuleRepository.cs index 2754161c..f9a71d29 100644 --- a/Oqtane.Server/Repository/ModuleRepository.cs +++ b/Oqtane.Server/Repository/ModuleRepository.cs @@ -64,7 +64,7 @@ namespace Oqtane.Repository public void DeleteModule(int ModuleId) { Module Module = db.Module.Find(ModuleId); - Permissions.UpdatePermissions(Module.SiteId, "Module", ModuleId, ""); + Permissions.DeletePermissions(Module.SiteId, "Module", ModuleId); db.Module.Remove(Module); db.SaveChanges(); } diff --git a/Oqtane.Server/Repository/PageRepository.cs b/Oqtane.Server/Repository/PageRepository.cs index 5b849d1b..78a21e9e 100644 --- a/Oqtane.Server/Repository/PageRepository.cs +++ b/Oqtane.Server/Repository/PageRepository.cs @@ -9,11 +9,15 @@ namespace Oqtane.Repository { private TenantDBContext db; private readonly IPermissionRepository Permissions; + private readonly IPageModuleRepository PageModules; + private readonly IModuleRepository ModuleRepository; - public PageRepository(TenantDBContext context, IPermissionRepository Permissions) + public PageRepository(TenantDBContext context, IPermissionRepository Permissions, IPageModuleRepository PageModules, IModuleRepository ModuleRepository) { db = context; this.Permissions = Permissions; + this.PageModules = PageModules; + this.ModuleRepository = ModuleRepository; } public IEnumerable GetPages() @@ -62,7 +66,12 @@ namespace Oqtane.Repository public void DeletePage(int PageId) { Page Page = db.Page.Find(PageId); - Permissions.UpdatePermissions(Page.SiteId, "Page", PageId, ""); + Permissions.DeletePermissions(Page.SiteId, "Page", PageId); + IEnumerable pageModules = db.PageModule.Where(item => item.PageId == PageId).ToList(); + foreach (var pageModule in pageModules) + { + PageModules.DeletePageModule(pageModule.PageModuleId); + } db.Page.Remove(Page); db.SaveChanges(); } diff --git a/Oqtane.Server/Scripts/00.00.00.sql b/Oqtane.Server/Scripts/00.00.00.sql index db6befc2..34013954 100644 --- a/Oqtane.Server/Scripts/00.00.00.sql +++ b/Oqtane.Server/Scripts/00.00.00.sql @@ -18,7 +18,7 @@ CREATE TABLE [dbo].[Site]( [ModifiedOn] [datetime] NOT NULL, [DeletedBy] [nvarchar](256) NULL, [DeletedOn] [datetime] NULL, - [IsDeleted][bit] NOT NULL + [IsDeleted][bit] NOT NULL, CONSTRAINT [PK_Site] PRIMARY KEY CLUSTERED ( [SiteId] ASC @@ -44,7 +44,7 @@ CREATE TABLE [dbo].[Page]( [ModifiedOn] [datetime] NOT NULL, [DeletedBy] [nvarchar](256) NULL, [DeletedOn] [datetime] NULL, - [IsDeleted][bit] NOT NULL + [IsDeleted][bit] NOT NULL, CONSTRAINT [PK_Page] PRIMARY KEY CLUSTERED ( [PageId] ASC @@ -79,6 +79,9 @@ CREATE TABLE [dbo].[PageModule]( [CreatedOn] [datetime] NOT NULL, [ModifiedBy] [nvarchar](256) NOT NULL, [ModifiedOn] [datetime] NOT NULL, + [DeletedBy] [nvarchar](256) NULL, + [DeletedOn] [datetime] NULL, + [IsDeleted][bit] NOT NULL, CONSTRAINT [PK_PageModule] PRIMARY KEY CLUSTERED ( [PageModuleId] ASC @@ -97,7 +100,7 @@ CREATE TABLE [dbo].[User]( [ModifiedOn] [datetime] NOT NULL, [DeletedBy] [nvarchar](256) NULL, [DeletedOn] [datetime] NULL, - [IsDeleted][bit] NOT NULL + [IsDeleted][bit] NOT NULL, CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED ( [UserId] ASC diff --git a/Oqtane.Shared/Models/Module.cs b/Oqtane.Shared/Models/Module.cs index 8816205a..09393b0a 100644 --- a/Oqtane.Shared/Models/Module.cs +++ b/Oqtane.Shared/Models/Module.cs @@ -16,6 +16,9 @@ namespace Oqtane.Models public string ModifiedBy { get; set; } public DateTime ModifiedOn { get; set; } + [NotMapped] + public bool IsDeleted { get; set; } + [NotMapped] public string Permissions { get; set; } diff --git a/Oqtane.Shared/Models/PageModule.cs b/Oqtane.Shared/Models/PageModule.cs index ffeb1872..7812861a 100644 --- a/Oqtane.Shared/Models/PageModule.cs +++ b/Oqtane.Shared/Models/PageModule.cs @@ -2,7 +2,7 @@ namespace Oqtane.Models { - public class PageModule : IAuditable + public class PageModule : IAuditable, IDeletable { public int PageModuleId { get; set; } public int PageId { get; set; } @@ -16,6 +16,9 @@ namespace Oqtane.Models public DateTime CreatedOn { get; set; } public string ModifiedBy { get; set; } public DateTime ModifiedOn { get; set; } + public string DeletedBy { get; set; } + public DateTime? DeletedOn { get; set; } + public bool IsDeleted { get; set; } public Module Module { get; set; } diff --git a/README.md b/README.md index 1dc1e8d4..5a346887 100644 --- a/README.md +++ b/README.md @@ -22,18 +22,8 @@ Security - Logging - Need support for JwT tokens for external client access to API -Design -- Need modern Admin UI theme -- Need to cleanly separate site.css - Admin - Need ability to soft delete core entities -- Drag and Drop modules - -Upgrade -- Need ability to upgrade application seamlessly -- integrated store/catalog of extensions -- auto update - provide url to check for updates, perhaps even download in background - core and extensions Database - Need ability to run on SQLite @@ -49,6 +39,14 @@ At this point Oqtane offers a minimum of desired functionality and is not recomm # Example Screenshots +Install Wizard: + +![Installer](https://github.com/oqtane/framework/blob/master/installer.png?raw=true "Installer") + +Default view after installation: + +![Home](https://github.com/oqtane/framework/blob/master/screenshot0.png?raw=true "Home") + A seamless login flow utilizing .NET Core Identity services: ![Login](https://github.com/oqtane/framework/blob/master/screenshot1.png?raw=true "Login")