CSS separation, multi-tenancy fixes

This commit is contained in:
Shaun Walker 2019-10-12 16:32:47 -04:00
parent 7f69f76263
commit c029e70783
82 changed files with 957 additions and 811 deletions

View File

@ -16,7 +16,6 @@
<button type="button" class="btn btn-primary" @onclick="UploadFile">Upload</button> <button type="button" class="btn btn-primary" @onclick="UploadFile">Upload</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
@code { @code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
@ -29,23 +28,25 @@
{ {
try try
{ {
ShowProgressIndicator();
if (await FileService.UploadFilesAsync(PageState.Site.SiteRootPath, files, "")) if (await FileService.UploadFilesAsync(PageState.Site.SiteRootPath, files, ""))
{ {
ModuleInstance.AddModuleMessage("Files Uploaded Successfully", MessageType.Success); AddModuleMessage("Files Uploaded Successfully", MessageType.Success);
} }
else else
{ {
ModuleInstance.AddModuleMessage("Upload Failed", MessageType.Error); AddModuleMessage("Upload Failed", MessageType.Error);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage("Upload Failed. " + ex.Message, MessageType.Error); AddModuleMessage("Upload Failed. " + ex.Message, MessageType.Error);
} }
} }
else else
{ {
ModuleInstance.AddModuleMessage("You Must Select Some Files To Upload", MessageType.Warning); AddModuleMessage("You Must Select Some Files To Upload", MessageType.Warning);
} }
} }
} }

View File

@ -39,6 +39,6 @@ else
{ {
await FileService.DeleteFileAsync(PageState.Site.SiteRootPath, filename); await FileService.DeleteFileAsync(PageState.Site.SiteRootPath, filename);
Files = await FileService.GetFilesAsync(PageState.Site.SiteRootPath); Files = await FileService.GetFilesAsync(PageState.Site.SiteRootPath);
ModuleInstance.AddModuleMessage("File Deleted", MessageType.Success); AddModuleMessage("File Deleted", MessageType.Success);
} }
} }

View File

@ -64,7 +64,7 @@
} }
else else
{ {
ModuleInstance.AddModuleMessage("Login Failed. Please Remember That Passwords Are Case Sensitive.", MessageType.Error); AddModuleMessage("Login Failed. Please Remember That Passwords Are Case Sensitive.", MessageType.Error);
} }
} }
else else
@ -82,7 +82,7 @@
} }
else else
{ {
ModuleInstance.AddModuleMessage("Login Failed. Please Remember That Passwords Are Case Sensitive.", MessageType.Error); AddModuleMessage("Login Failed. Please Remember That Passwords Are Case Sensitive.", MessageType.Error);
} }
} }
} }

View File

@ -76,28 +76,28 @@
{ {
if (await FileService.UploadFilesAsync("Modules", files, "")) if (await FileService.UploadFilesAsync("Modules", files, ""))
{ {
ModuleInstance.AddModuleMessage("Module Uploaded Successfully. Click Install To Complete Installation.", MessageType.Success); AddModuleMessage("Module Uploaded Successfully. Click Install To Complete Installation.", MessageType.Success);
uploaded = true; uploaded = true;
StateHasChanged(); StateHasChanged();
} }
else else
{ {
ModuleInstance.AddModuleMessage("Module Upload Failed.", MessageType.Error); AddModuleMessage("Module Upload Failed.", MessageType.Error);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage("Module Upload Failed. " + ex.Message, MessageType.Error); AddModuleMessage("Module Upload Failed. " + ex.Message, MessageType.Error);
} }
} }
else else
{ {
ModuleInstance.AddModuleMessage("Invalid Module Package", MessageType.Error); AddModuleMessage("Invalid Module Package", MessageType.Error);
} }
} }
else else
{ {
ModuleInstance.AddModuleMessage("You Must Select A Module To Upload", MessageType.Warning); AddModuleMessage("You Must Select A Module To Upload", MessageType.Warning);
} }
} }
@ -110,7 +110,7 @@
private async Task DownloadModule(string moduledefinitionname, string version) private async Task DownloadModule(string moduledefinitionname, string version)
{ {
await PackageService.DownloadPackageAsync(moduledefinitionname, version, "Modules"); await PackageService.DownloadPackageAsync(moduledefinitionname, version, "Modules");
ModuleInstance.AddModuleMessage("Module Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success); AddModuleMessage("Module Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success);
uploaded = true; uploaded = true;
StateHasChanged(); StateHasChanged();
} }

View File

@ -58,7 +58,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -73,7 +73,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
} }

View File

@ -35,7 +35,7 @@
} }
else else
{ {
ModuleInstance.AddModuleMessage("You Must Enter Some Content To Import", MessageType.Warning); AddModuleMessage("You Must Enter Some Content To Import", MessageType.Warning);
} }
} }
} }

View File

@ -173,7 +173,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -194,7 +194,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -273,7 +273,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }

View File

@ -165,7 +165,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -178,7 +178,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
} }

View File

@ -233,7 +233,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -262,7 +262,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -365,7 +365,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
} }

View File

@ -94,12 +94,12 @@
} }
else else
{ {
ModuleInstance.AddModuleMessage("Current User Is Not Logged In", MessageType.Warning); AddModuleMessage("Current User Is Not Logged In", MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -124,7 +124,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }

View File

@ -39,17 +39,25 @@
user.DisplayName = Username; user.DisplayName = Username;
user.Email = Email; user.Email = Email;
user.Password = Password; user.Password = Password;
await UserService.AddUserAsync(user); user = await UserService.AddUserAsync(user);
NavigationManager.NavigateTo(NavigateUrl(""));
if (user != null)
{
NavigationManager.NavigateTo(NavigateUrl(""));
}
else
{
AddModuleMessage("Error Adding User. Please Ensure Password Meets Complexity Requirements And Username Is Not Already In Use.", MessageType.Error);
}
} }
else else
{ {
ModuleInstance.AddModuleMessage("You Must Provide A Username, Password, and Email Address", MessageType.Warning); AddModuleMessage("You Must Provide A Username, Password, and Email Address", MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }

View File

@ -70,7 +70,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }

View File

@ -71,7 +71,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -84,7 +84,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }

View File

@ -71,7 +71,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -92,7 +92,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }

View File

@ -5,6 +5,7 @@
@inject IAliasService AliasService @inject IAliasService AliasService
@inject ISiteService SiteService @inject ISiteService SiteService
@inject IThemeService ThemeService @inject IThemeService ThemeService
@inject IUserService UserService
@if (tenants == null) @if (tenants == null)
{ {
@ -12,74 +13,93 @@
} }
else else
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr>
<td>
<label for="Name" class="control-label">Tenant: </label>
</td>
<td>
<select class="form-control" @onchange="(e => TenantChanged(e))">
<option value="-1">&lt;Select Tenant&gt;</option>
@foreach (Tenant tenant in tenants)
{
<option value="@tenant.TenantId">@tenant.Name</option>
}
</select>
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Name: </label>
</td>
<td>
<input class="form-control" @bind="@name" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Aliases: </label>
</td>
<td>
<textarea class="form-control" @bind="@urls" rows="3" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Logo: </label>
</td>
<td>
<input class="form-control" @bind="@logo" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Default Theme: </label>
</td>
<td>
<select class="form-control" @bind="@themetype">
<option value="">&lt;Select Theme&gt;</option>
@foreach (KeyValuePair<string, string> item in themes)
{
<option value="@item.Key">@item.Value</option>
}
</select>
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Default Layout: </label>
</td>
<td>
<select class="form-control" @bind="@layouttype">
<option value="">&lt;Select Layout&gt;</option>
@foreach (KeyValuePair<string, string> panelayout in panelayouts)
{
<option value="@panelayout.Key">@panelayout.Value</option>
}
</select>
</td>
</tr>
@if (!isinitialized)
{
<tr> <tr>
<td> <td>
<label for="Name" class="control-label">Tenant: </label> <label for="Name" class="control-label">Host Username:</label>
</td> </td>
<td> <td>
<select class="form-control" @bind="@tenantid"> <input class="form-control" @bind="@username" disabled />
<option value="-1">&lt;Select Tenant&gt;</option>
@foreach (Tenant tenant in tenants)
{
<option value="@tenant.TenantId">@tenant.Name</option>
}
</select>
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<label for="Name" class="control-label">Name: </label> <label for="Name" class="control-label">Host Password:</label>
</td> </td>
<td> <td>
<input class="form-control" @bind="@name" /> <input type="password" class="form-control" @bind="@password" />
</td> </td>
</tr> </tr>
<tr> }
<td> </table>
<label for="Name" class="control-label">Aliases: </label>
</td>
<td>
<textarea class="form-control" @bind="@urls" rows="3" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Logo: </label>
</td>
<td>
<input class="form-control" @bind="@logo" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Default Theme: </label>
</td>
<td>
<select class="form-control" @bind="@themetype">
<option value="">&lt;Select Theme&gt;</option>
@foreach (KeyValuePair<string, string> item in themes)
{
<option value="@item.Key">@item.Value</option>
}
</select>
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Default Layout: </label>
</td>
<td>
<select class="form-control" @bind="@layouttype">
<option value="">&lt;Select Layout&gt;</option>
@foreach (KeyValuePair<string, string> panelayout in panelayouts)
{
<option value="@panelayout.Key">@panelayout.Value</option>
}
</select>
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveSite">Save</button> <button type="button" class="btn btn-success" @onclick="SaveSite">Save</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
} }
@ -97,6 +117,9 @@ else
string logo = ""; string logo = "";
string themetype = ""; string themetype = "";
string layouttype = ""; string layouttype = "";
bool isinitialized = true;
string username = "";
string password = "";
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
@ -104,35 +127,103 @@ else
urls = PageState.Alias.Name; urls = PageState.Alias.Name;
themes = ThemeService.GetThemeTypes(PageState.Themes); themes = ThemeService.GetThemeTypes(PageState.Themes);
panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes); panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes);
username = PageState.User.Username;
}
private void TenantChanged(ChangeEventArgs e)
{
try
{
tenantid = (string)e.Value;
if (tenantid != "-1")
{
Tenant tenant = tenants.Where(item => item.TenantId == int.Parse(tenantid)).FirstOrDefault();
if (tenant != null)
{
isinitialized = tenant.IsInitialized;
StateHasChanged();
}
}
}
catch (Exception ex)
{
AddModuleMessage(ex.Message, MessageType.Error);
}
} }
private async Task SaveSite() private async Task SaveSite()
{ {
if (tenantid != "-1" && name != "" && urls != "" && themetype != "") if (tenantid != "-1" && name != "" && urls != "" && themetype != "")
{ {
Site site = new Site(); bool isvalid = true;
site.TenantId = int.Parse(tenantid);
site.Name = name;
site.Logo = (logo == null ? "" : logo);
site.DefaultThemeType = themetype;
site.DefaultLayoutType = (layouttype == null ? "" : layouttype);
site = await SiteService.AddSiteAsync(site);
urls = urls.Replace("\n", ","); if (!isinitialized)
foreach(string name in urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{ {
Alias alias = new Alias(); User user = new User();
alias.Name = name; user.SiteId = PageState.Site.SiteId;
alias.TenantId = int.Parse(tenantid); user.Username = username;
alias.SiteId = site.SiteId; user.Password = password;
await AliasService.AddAliasAsync(alias); user = await UserService.LoginUserAsync(user, false, false);
isvalid = user.IsAuthenticated;
} }
NavigationManager.NavigateTo("http://" + urls.Split(',')[0], true); if (isvalid)
{
List<Alias> aliases = new List<Alias>();
urls = urls.Replace("\n", ",");
foreach (string name in urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
Alias alias = new Alias();
alias.Name = name;
alias.TenantId = int.Parse(tenantid);
alias.SiteId = -1;
alias = await AliasService.AddAliasAsync(alias);
aliases.Add(alias);
}
Site site = new Site();
site.TenantId = int.Parse(tenantid);
site.Name = name;
site.Logo = (logo == null ? "" : logo);
site.DefaultThemeType = themetype;
site.DefaultLayoutType = (layouttype == null ? "" : layouttype);
site = await SiteService.AddSiteAsync(site, aliases[0]);
foreach(Alias alias in aliases)
{
alias.SiteId = site.SiteId;
await AliasService.UpdateAliasAsync(alias);
}
if (!isinitialized)
{
User user = new User();
user.SiteId = site.SiteId;
user.Username = username;
user.Password = password;
user.Email = PageState.User.Email;
user.DisplayName = PageState.User.DisplayName;
user = await UserService.AddUserAsync(user, aliases[0]);
if (user != null)
{
Tenant tenant = tenants.Where(item => item.TenantId == int.Parse(tenantid)).FirstOrDefault();
tenant.IsInitialized = true;
await TenantService.UpdateTenantAsync(tenant);
}
}
Uri uri = new Uri(NavigationManager.Uri);
NavigationManager.NavigateTo(uri.Scheme + "://" + aliases[0].Name, true);
}
else
{
AddModuleMessage("Invalid Host Password", MessageType.Error);
}
} }
else else
{ {
ModuleInstance.AddModuleMessage("You Must Provide A Tenant, Site Name, Alias, And Default Theme", MessageType.Warning); AddModuleMessage("You Must Provide A Tenant, Site Name, Alias, And Default Theme", MessageType.Warning);
} }
} }

View File

@ -88,6 +88,7 @@ else
Dictionary<string, string> themes = new Dictionary<string, string>(); Dictionary<string, string> themes = new Dictionary<string, string>();
Dictionary<string, string> panelayouts = new Dictionary<string, string>(); Dictionary<string, string> panelayouts = new Dictionary<string, string>();
Alias Alias;
int siteid; int siteid;
string name = ""; string name = "";
List<Alias> aliases; List<Alias> aliases;
@ -109,9 +110,10 @@ else
{ {
themes = ThemeService.GetThemeTypes(PageState.Themes); themes = ThemeService.GetThemeTypes(PageState.Themes);
panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes); panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes);
Alias = PageState.Aliases.Where(item => item.AliasId == Int32.Parse(PageState.QueryString["id"])).FirstOrDefault();
siteid = Int32.Parse(PageState.QueryString["id"]); siteid = Alias.SiteId;
Site site = await SiteService.GetSiteAsync(siteid); Site site = await SiteService.GetSiteAsync(siteid, Alias);
if (site != null) if (site != null)
{ {
name = site.Name; name = site.Name;
@ -135,7 +137,7 @@ else
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -143,12 +145,12 @@ else
{ {
try try
{ {
await SiteService.DeleteSiteAsync(PageState.Site.SiteId); await SiteService.DeleteSiteAsync(siteid, Alias);
NavigationManager.NavigateTo(NavigateUrl()); NavigationManager.NavigateTo(NavigateUrl());
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
} }

View File

@ -89,6 +89,7 @@ else
Dictionary<string, string> themes = new Dictionary<string, string>(); Dictionary<string, string> themes = new Dictionary<string, string>();
Dictionary<string, string> panelayouts = new Dictionary<string, string>(); Dictionary<string, string> panelayouts = new Dictionary<string, string>();
Alias Alias;
int siteid; int siteid;
string name = ""; string name = "";
List<Alias> aliases; List<Alias> aliases;
@ -111,9 +112,10 @@ else
{ {
themes = ThemeService.GetThemeTypes(PageState.Themes); themes = ThemeService.GetThemeTypes(PageState.Themes);
panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes); panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes);
Alias = PageState.Aliases.Where(item => item.AliasId == Int32.Parse(PageState.QueryString["id"])).FirstOrDefault();
siteid = Int32.Parse(PageState.QueryString["id"]); siteid = Alias.SiteId;
Site site = await SiteService.GetSiteAsync(siteid); Site site = await SiteService.GetSiteAsync(siteid, Alias);
if (site != null) if (site != null)
{ {
name = site.Name; name = site.Name;
@ -137,7 +139,7 @@ else
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -147,7 +149,7 @@ else
{ {
if (name != "" && urls != "" && themetype != "") if (name != "" && urls != "" && themetype != "")
{ {
Site site = await SiteService.GetSiteAsync(siteid); Site site = await SiteService.GetSiteAsync(siteid, Alias);
if (site != null) if (site != null)
{ {
site.Name = name; site.Name = name;
@ -156,7 +158,7 @@ else
site.DefaultLayoutType = (layouttype == null ? "" : layouttype); site.DefaultLayoutType = (layouttype == null ? "" : layouttype);
site.IsDeleted = (isdeleted == null ? true : Boolean.Parse(isdeleted)); site.IsDeleted = (isdeleted == null ? true : Boolean.Parse(isdeleted));
site = await SiteService.UpdateSiteAsync(site); site = await SiteService.UpdateSiteAsync(site, Alias);
urls = urls.Replace("\n", ","); urls = urls.Replace("\n", ",");
string[] names = urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); string[] names = urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
@ -184,12 +186,12 @@ else
} }
else else
{ {
ModuleInstance.AddModuleMessage("You Must Provide A Site Name, Alias, And Default Theme", MessageType.Warning); AddModuleMessage("You Must Provide A Site Name, Alias, And Default Theme", MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
} }

View File

@ -1,7 +1,7 @@
@namespace Oqtane.Modules.Admin.Sites @namespace Oqtane.Modules.Admin.Sites
@inherits ModuleBase @inherits ModuleBase
@inject NavigationManager NavigationManager
@inject ISiteService SiteService @inject IAliasService AliasService
@if (sites == null) @if (sites == null)
{ {
@ -18,9 +18,9 @@ else
<th>&nbsp;</th> <th>&nbsp;</th>
</Header> </Header>
<Row> <Row>
<td>@context.Name</td> <td><a href="@(scheme + context.Name)">@context.Name</a></td>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.SiteId.ToString())" /></td> <td><ActionLink Action="Edit" Parameters="@($"id=" + context.AliasId.ToString())" /></td>
<td><ActionLink Action="Delete" Parameters="@($"id=" + context.SiteId.ToString())" Class="btn btn-danger" /></td> <td><ActionLink Action="Delete" Parameters="@($"id=" + context.AliasId.ToString())" Class="btn btn-danger" /></td>
</Row> </Row>
</Pager> </Pager>
} }
@ -28,10 +28,21 @@ else
@code { @code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
List<Site> sites; List<Alias> sites;
string scheme;
protected override async Task OnInitializedAsync() protected override void OnInitialized()
{ {
sites = await SiteService.GetSitesAsync(); Uri uri = new Uri(NavigationManager.Uri);
scheme = uri.Scheme + "://";
sites = new List<Alias>();
foreach (Alias alias in PageState.Aliases.OrderBy(item => item.Name))
{
if (!sites.Exists(item => item.TenantId == alias.TenantId && item.SiteId == alias.SiteId))
{
sites.Add(alias);
}
}
} }
} }

View File

@ -42,6 +42,8 @@
private async Task SaveTenant() private async Task SaveTenant()
{ {
ShowProgressIndicator();
connectionstring = connectionstring.Replace("\\\\", "\\"); connectionstring = connectionstring.Replace("\\\\", "\\");
GenericResponse response = await InstallationService.Install(connectionstring); GenericResponse response = await InstallationService.Install(connectionstring);
if (response.Success) if (response.Success)
@ -50,13 +52,14 @@
tenant.Name = name; tenant.Name = name;
tenant.DBConnectionString = connectionstring; tenant.DBConnectionString = connectionstring;
tenant.DBSchema = schema; tenant.DBSchema = schema;
tenant.IsInitialized = false;
await TenantService.AddTenantAsync(tenant); await TenantService.AddTenantAsync(tenant);
NavigationManager.NavigateTo(NavigateUrl()); NavigationManager.NavigateTo(NavigateUrl());
} }
else else
{ {
ModuleInstance.AddModuleMessage(response.Message, MessageType.Error); AddModuleMessage(response.Message, MessageType.Error);
} }
} }
} }

View File

@ -55,7 +55,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
private async Task DeleteTenant() private async Task DeleteTenant()

View File

@ -55,7 +55,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
private async Task SaveTenant() private async Task SaveTenant()

View File

@ -75,28 +75,28 @@
{ {
if (await FileService.UploadFilesAsync("Themes", files, "")) if (await FileService.UploadFilesAsync("Themes", files, ""))
{ {
ModuleInstance.AddModuleMessage("Theme Uploaded Successfully. Click Install To Complete Installation.", MessageType.Success); AddModuleMessage("Theme Uploaded Successfully. Click Install To Complete Installation.", MessageType.Success);
uploaded = true; uploaded = true;
StateHasChanged(); StateHasChanged();
} }
else else
{ {
ModuleInstance.AddModuleMessage("Theme Upload Failed.", MessageType.Error); AddModuleMessage("Theme Upload Failed.", MessageType.Error);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage("Theme Upload Failed. " + ex.Message, MessageType.Error); AddModuleMessage("Theme Upload Failed. " + ex.Message, MessageType.Error);
} }
} }
else else
{ {
ModuleInstance.AddModuleMessage("Invalid Theme Package", MessageType.Error); AddModuleMessage("Invalid Theme Package", MessageType.Error);
} }
} }
else else
{ {
ModuleInstance.AddModuleMessage("You Must Select A Theme To Upload", MessageType.Warning); AddModuleMessage("You Must Select A Theme To Upload", MessageType.Warning);
} }
} }
@ -109,7 +109,7 @@
private async Task DownloadTheme(string packageid, string version) private async Task DownloadTheme(string packageid, string version)
{ {
await PackageService.DownloadPackageAsync(packageid, version, "Themes"); await PackageService.DownloadPackageAsync(packageid, version, "Themes");
ModuleInstance.AddModuleMessage("Theme Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success); AddModuleMessage("Theme Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success);
uploaded = true; uploaded = true;
StateHasChanged(); StateHasChanged();
} }

View File

@ -49,7 +49,7 @@ else
} }
if (!upgradeavailable) if (!upgradeavailable)
{ {
ModuleInstance.AddModuleMessage("Framework Is Up To Date", MessageType.Info); AddModuleMessage("Framework Is Up To Date", MessageType.Info);
} }
} }
@ -64,28 +64,28 @@ else
{ {
if (await FileService.UploadFilesAsync("Framework", files, "")) if (await FileService.UploadFilesAsync("Framework", files, ""))
{ {
ModuleInstance.AddModuleMessage("Framework Uploaded Successfully. Click Upgrade To Complete Installation.", MessageType.Success); AddModuleMessage("Framework Uploaded Successfully. Click Upgrade To Complete Installation.", MessageType.Success);
uploaded = true; uploaded = true;
StateHasChanged(); StateHasChanged();
} }
else else
{ {
ModuleInstance.AddModuleMessage("Framework Upload Failed.", MessageType.Error); AddModuleMessage("Framework Upload Failed.", MessageType.Error);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage("Framework Upload Failed. " + ex.Message, MessageType.Error); AddModuleMessage("Framework Upload Failed. " + ex.Message, MessageType.Error);
} }
} }
else else
{ {
ModuleInstance.AddModuleMessage("Invalid Framework Package", MessageType.Error); AddModuleMessage("Invalid Framework Package", MessageType.Error);
} }
} }
else else
{ {
ModuleInstance.AddModuleMessage("You Must Select A Framework Package To Upload", MessageType.Warning); AddModuleMessage("You Must Select A Framework Package To Upload", MessageType.Warning);
} }
} }

View File

@ -87,7 +87,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -111,12 +111,12 @@
} }
else else
{ {
ModuleInstance.AddModuleMessage("Error Adding User. Please Ensure Password Meets Complexity Requirements And Username Is Not Already In Use.", MessageType.Error); AddModuleMessage("Error Adding User. Please Ensure Password Meets Complexity Requirements And Username Is Not Already In Use.", MessageType.Error);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }

View File

@ -88,7 +88,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -106,7 +106,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }

View File

@ -125,7 +125,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -153,7 +153,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }

View File

@ -84,7 +84,7 @@ else
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -145,16 +145,16 @@ else
await UserRoleService.AddUserRoleAsync(userrole); await UserRoleService.AddUserRoleAsync(userrole);
} }
await GetUserRoles(); await GetUserRoles();
ModuleInstance.AddModuleMessage("User Assigned To Role", MessageType.Success); AddModuleMessage("User Assigned To Role", MessageType.Success);
} }
else else
{ {
ModuleInstance.AddModuleMessage("You Must Select A Role", MessageType.Warning); AddModuleMessage("You Must Select A Role", MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -162,7 +162,7 @@ else
{ {
await UserRoleService.DeleteUserRoleAsync(UserRoleId); await UserRoleService.DeleteUserRoleAsync(UserRoleId);
await GetUserRoles(); await GetUserRoles();
ModuleInstance.AddModuleMessage("User Removed From Role", MessageType.Success); AddModuleMessage("User Removed From Role", MessageType.Success);
} }
} }

View File

@ -49,7 +49,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -75,7 +75,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
} }

View File

@ -28,7 +28,7 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
} }

View File

@ -42,16 +42,6 @@ namespace Oqtane.Modules
return "Modules/" + this.GetType().Namespace + "/"; return "Modules/" + this.GetType().Namespace + "/";
} }
public async Task AddCSS(string Url)
{
if (!Url.StartsWith("http"))
{
Url = ModulePath() + Url;
}
var interop = new Interop(JSRuntime);
await interop.AddCSS("Module:" + Utilities.CreateIdFromUrl(Url), Url);
}
public string NavigateUrl() public string NavigateUrl()
{ {
return NavigateUrl(PageState.Page.Path); return NavigateUrl(PageState.Page.Path);
@ -106,5 +96,20 @@ namespace Oqtane.Modules
{ {
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters); return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters);
} }
public void AddModuleMessage(string message, MessageType type)
{
AddModuleMessage(message, type);
}
public void ShowProgressIndicator()
{
ModuleInstance.ShowProgressIndicator();
}
public void HideProgressIndicator()
{
ModuleInstance.HideProgressIndicator();
}
} }
} }

View File

@ -7,13 +7,18 @@ namespace Oqtane.Services
public interface ISiteService public interface ISiteService
{ {
Task<List<Site>> GetSitesAsync(); Task<List<Site>> GetSitesAsync();
Task<List<Site>> GetSitesAsync(Alias Alias);
Task<Site> GetSiteAsync(int SiteId); Task<Site> GetSiteAsync(int SiteId);
Task<Site> GetSiteAsync(int SiteId, Alias Alias);
Task<Site> AddSiteAsync(Site Site); Task<Site> AddSiteAsync(Site Site);
Task<Site> AddSiteAsync(Site Site, Alias Alias);
Task<Site> UpdateSiteAsync(Site Site); Task<Site> UpdateSiteAsync(Site Site);
Task<Site> UpdateSiteAsync(Site Site, Alias Alias);
Task DeleteSiteAsync(int SiteId); Task DeleteSiteAsync(int SiteId);
Task DeleteSiteAsync(int SiteId, Alias Alias);
} }
} }

View File

@ -14,6 +14,8 @@ namespace Oqtane.Services
Task<User> AddUserAsync(User User); Task<User> AddUserAsync(User User);
Task<User> AddUserAsync(User User, Alias alias);
Task<User> UpdateUserAsync(User User); Task<User> UpdateUserAsync(User User);
Task DeleteUserAsync(int UserId); Task DeleteUserAsync(int UserId);

View File

@ -10,11 +10,13 @@ namespace Oqtane.Services
public static string CreateApiUrl(Alias alias, string absoluteUri, string serviceName) public static string CreateApiUrl(Alias alias, string absoluteUri, string serviceName)
{ {
string apiurl = ""; Uri uri = new Uri(absoluteUri);
string apiurl;
if (alias != null) if (alias != null)
{ {
// build a url which passes the alias that may include a subfolder for multi-tenancy // build a url which passes the alias that may include a subfolder for multi-tenancy
apiurl = alias.Url + "/"; apiurl = uri.Scheme + "://" + alias.Name + "/";
if (alias.Path == "") if (alias.Path == "")
{ {
apiurl += "~/"; apiurl += "~/";
@ -23,7 +25,6 @@ namespace Oqtane.Services
else else
{ {
// build a url which ignores any subfolder for multi-tenancy // build a url which ignores any subfolder for multi-tenancy
Uri uri = new Uri(absoluteUri);
apiurl = uri.Scheme + "://" + uri.Authority + "/~/"; apiurl = uri.Scheme + "://" + uri.Authority + "/~/";
} }
apiurl += "api/" + serviceName; apiurl += "api/" + serviceName;

View File

@ -31,25 +31,47 @@ namespace Oqtane.Services
List<Site> sites = await http.GetJsonAsync<List<Site>>(apiurl); List<Site> sites = await http.GetJsonAsync<List<Site>>(apiurl);
return sites.OrderBy(item => item.Name).ToList(); return sites.OrderBy(item => item.Name).ToList();
} }
public async Task<List<Site>> GetSitesAsync(Alias Alias)
{
List<Site> sites = await http.GetJsonAsync<List<Site>>(CreateApiUrl(Alias, NavigationManager.Uri, "Site"));
return sites.OrderBy(item => item.Name).ToList();
}
public async Task<Site> GetSiteAsync(int SiteId) public async Task<Site> GetSiteAsync(int SiteId)
{ {
return await http.GetJsonAsync<Site>(apiurl + "/" + SiteId.ToString()); return await http.GetJsonAsync<Site>(apiurl + "/" + SiteId.ToString());
} }
public async Task<Site> GetSiteAsync(int SiteId, Alias Alias)
{
return await http.GetJsonAsync<Site>(CreateApiUrl(Alias, NavigationManager.Uri, "Site") + "/" + SiteId.ToString());
}
public async Task<Site> AddSiteAsync(Site Site) public async Task<Site> AddSiteAsync(Site Site)
{ {
return await http.PostJsonAsync<Site>(apiurl, Site); return await http.PostJsonAsync<Site>(apiurl, Site);
} }
public async Task<Site> AddSiteAsync(Site Site, Alias Alias)
{
return await http.PostJsonAsync<Site>(CreateApiUrl(Alias, NavigationManager.Uri, "Site"), Site);
}
public async Task<Site> UpdateSiteAsync(Site Site) public async Task<Site> UpdateSiteAsync(Site Site)
{ {
return await http.PutJsonAsync<Site>(apiurl + "/" + Site.SiteId.ToString(), Site); return await http.PutJsonAsync<Site>(apiurl + "/" + Site.SiteId.ToString(), Site);
} }
public async Task<Site> UpdateSiteAsync(Site Site, Alias Alias)
{
return await http.PutJsonAsync<Site>(CreateApiUrl(Alias, NavigationManager.Uri, "Site") + "/" + Site.SiteId.ToString(), Site);
}
public async Task DeleteSiteAsync(int SiteId) public async Task DeleteSiteAsync(int SiteId)
{ {
await http.DeleteAsync(apiurl + "/" + SiteId.ToString()); await http.DeleteAsync(apiurl + "/" + SiteId.ToString());
} }
public async Task DeleteSiteAsync(int SiteId, Alias Alias)
{
await http.DeleteAsync(CreateApiUrl(Alias, NavigationManager.Uri, "Site") + "/" + SiteId.ToString());
}
} }
} }

View File

@ -55,6 +55,18 @@ namespace Oqtane.Services
} }
} }
public async Task<User> AddUserAsync(User User, Alias Alias)
{
try
{
return await http.PostJsonAsync<User>(CreateApiUrl(Alias, NavigationManager.Uri, "User"), User);
}
catch
{
return null;
}
}
public async Task<User> UpdateUserAsync(User User) public async Task<User> UpdateUserAsync(User User)
{ {
return await http.PutJsonAsync<User>(apiurl + "/" + User.UserId.ToString(), User); return await http.PutJsonAsync<User>(apiurl + "/" + User.UserId.ToString(), User);

View File

@ -114,7 +114,7 @@
<button type="button" class="btn btn-success" @onclick="Install">Install Now</button><br /><br /> <button type="button" class="btn btn-success" @onclick="Install">Install Now</button><br /><br />
@((MarkupString)@Message) @((MarkupString)@Message)
</div> </div>
<div class="loading" style="@LoadingDisplay"></div> <div class="app-progress-indicator" style="@LoadingDisplay"></div>
</div> </div>
</div> </div>
@ -177,7 +177,7 @@
site.TenantId = tenants.FirstOrDefault().TenantId; site.TenantId = tenants.FirstOrDefault().TenantId;
site.Name = "Default Site"; site.Name = "Default Site";
site.Logo = "oqtane.png"; site.Logo = "oqtane.png";
site.DefaultThemeType = "Oqtane.Themes.Theme2.Theme2, Oqtane.Client"; site.DefaultThemeType = Constants.DefaultTheme;
site.DefaultLayoutType = ""; site.DefaultLayoutType = "";
site = await SiteService.AddSiteAsync(site); site = await SiteService.AddSiteAsync(site);

View File

@ -41,12 +41,12 @@ namespace Oqtane.Shared
} }
} }
public Task AddCSS(string id, string url) public Task IncludeCSS(string id, string url)
{ {
try try
{ {
jsRuntime.InvokeAsync<string>( jsRuntime.InvokeAsync<string>(
"interop.addCSS", "interop.includeCSS",
id, url); id, url);
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -56,21 +56,6 @@ namespace Oqtane.Shared
} }
} }
public Task RemoveCSS(string pattern)
{
try
{
jsRuntime.InvokeAsync<string>(
"interop.removeCSS",
pattern);
return Task.CompletedTask;
}
catch
{
return Task.CompletedTask;
}
}
public ValueTask<string> GetElementByName(string name) public ValueTask<string> GetElementByName(string name)
{ {
try try

View File

@ -1,9 +1,14 @@
@namespace Oqtane.Shared @namespace Oqtane.Shared
<ModuleMessage Message="@message" Type="MessageType.Error" />
<CascadingValue Value="this"> <CascadingValue Value="this">
<ModuleMessage @ref="modulemessage" /> <ModuleMessage @ref="modulemessage" />
@DynamicComponent @DynamicComponent
</CascadingValue> </CascadingValue>
@if (progressindicator)
{
<div class="app-progress-indicator"></div>
}
@code { @code {
[CascadingParameter] [CascadingParameter]
@ -13,9 +18,12 @@
private Module ModuleState { get; set; } private Module ModuleState { get; set; }
private ModuleMessage modulemessage { get; set; } private ModuleMessage modulemessage { get; set; }
string message;
RenderFragment DynamicComponent { get; set; } RenderFragment DynamicComponent { get; set; }
bool progressindicator = false;
protected override void OnParametersSet() protected override void OnParametersSet()
{ {
DynamicComponent = builder => DynamicComponent = builder =>
@ -40,13 +48,26 @@
else else
{ {
// module does not exist with typename specified // module does not exist with typename specified
modulemessage.SetModuleMessage("Error Loading Component For Module " + ModuleState.ModuleDefinitionName, MessageType.Error); message = "Module Does Not Have A Component Named " + Utilities.GetTypeNameClass(typename) + ".razor";
} }
}; };
} }
public void AddModuleMessage(string message, MessageType type) public void AddModuleMessage(string message, MessageType type)
{ {
progressindicator = false;
modulemessage.SetModuleMessage(message, type); modulemessage.SetModuleMessage(message, type);
} }
public void ShowProgressIndicator()
{
progressindicator = true;
StateHasChanged();
}
public void HideProgressIndicator()
{
progressindicator = true;
StateHasChanged();
}
} }

View File

@ -27,8 +27,8 @@
{ {
if (PageState.DesignMode && UserSecurity.IsAuthorized(PageState.User, "Edit", PageState.Page.Permissions) && Name != Constants.AdminPane) if (PageState.DesignMode && UserSecurity.IsAuthorized(PageState.User, "Edit", PageState.Page.Permissions) && Name != Constants.AdminPane)
{ {
paneadminborder = "pane-admin-border"; paneadminborder = "app-pane-admin-border";
panetitle = "<div class=\"pane-admin-title\">" + Name + " Pane</div>"; panetitle = "<div class=\"app-pane-admin-title\">" + Name + " Pane</div>";
} }
else else
{ {
@ -87,7 +87,7 @@
{ {
module.Title = module.ControlTitle; module.Title = module.ControlTitle;
} }
builder.OpenComponent(0, Type.GetType(Constants.DefaultContainer)); builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
builder.AddAttribute(1, "Module", module); builder.AddAttribute(1, "Module", module);
builder.CloseComponent(); builder.CloseComponent();
} }
@ -109,7 +109,7 @@
// check if user is authorized to view module // check if user is authorized to view module
if (UserSecurity.IsAuthorized(PageState.User, "View", module.Permissions)) if (UserSecurity.IsAuthorized(PageState.User, "View", module.Permissions))
{ {
builder.OpenComponent(0, Type.GetType(Constants.DefaultContainer)); builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
builder.AddAttribute(1, "Module", module); builder.AddAttribute(1, "Module", module);
builder.CloseComponent(); builder.CloseComponent();
} }
@ -122,7 +122,7 @@
// check if user is authorized to view module // check if user is authorized to view module
if (UserSecurity.IsAuthorized(PageState.User, "View", module.Permissions)) if (UserSecurity.IsAuthorized(PageState.User, "View", module.Permissions))
{ {
builder.OpenComponent(0, Type.GetType(Constants.DefaultContainer)); builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
builder.AddAttribute(1, "Module", module); builder.AddAttribute(1, "Module", module);
builder.SetKey(module.PageModuleId); builder.SetKey(module.PageModuleId);
builder.CloseComponent(); builder.CloseComponent();

View File

@ -20,8 +20,8 @@
} }
else else
{ {
// layout does not exist with type specified // layout does not exist with type specified
} }
}; };
} }
} }

View File

@ -38,7 +38,7 @@
{ {
if (PageState != null) if (PageState != null)
{ {
builder.OpenComponent(0, Type.GetType(Constants.DefaultPage)); builder.OpenComponent(0, Type.GetType(Constants.PageComponent));
builder.CloseComponent(); builder.CloseComponent();
} }
}; };
@ -407,7 +407,6 @@
// use first alias if Uri does not exist // use first alias if Uri does not exist
alias = aliases.FirstOrDefault(); alias = aliases.FirstOrDefault();
} }
alias.Scheme = uri.Scheme;
return alias; return alias;
} }

View File

@ -20,19 +20,11 @@
} }
else else
{ {
// theme does not exist with type specified // theme does not exist with type specified
builder.OpenComponent(0, Type.GetType(Constants.ModuleMessageControl)); builder.OpenComponent(0, Type.GetType(Constants.ModuleMessageControl));
builder.AddAttribute(1, "Message", "Error Loading Page Theme " + PageState.Page.ThemeType); builder.AddAttribute(1, "Message", "Error Loading Page Theme " + PageState.Page.ThemeType);
builder.CloseComponent(); builder.CloseComponent();
} }
}; };
} }
protected override async Task OnParametersSetAsync()
{
// remove any custom CSS
var interop = new Interop(jsRuntime);
await interop.RemoveCSS("Theme:");
await interop.RemoveCSS("Module:");
}
} }

View File

@ -203,10 +203,5 @@ namespace Oqtane.Shared
return ""; return "";
} }
} }
public static string CreateIdFromUrl(string value)
{
return value.Replace("/", "_").Replace("\\", "_").Replace(".", "_");
}
} }
} }

View File

@ -1,8 +1,8 @@
@namespace Oqtane.Themes @namespace Oqtane.Themes
@inherits ContainerBase @inherits ContainerBase
<div id="modal" class="modal" style="display: block"> <div id="modal" class="app-admin-modal" style="display: block">
<div class="modal-content"> <div class="app-admin-modal-content">
<a href="@closeurl" class="close">x</a> <a href="@closeurl" class="app-admin-modal-close">x</a>
<div class="container"> <div class="container">
<div class="row px-4"> <div class="row px-4">
<h2><ModuleTitle /></h2> <h2><ModuleTitle /></h2>

View File

@ -1,4 +1,4 @@
@namespace Oqtane.Themes.Theme2 @namespace Oqtane.Themes.BlazorTheme
@inherits ThemeBase @inherits ThemeBase
<div class="sidebar"> <div class="sidebar">
@ -8,7 +8,7 @@
<div class="main"> <div class="main">
<div class="top-row px-4"> <div class="top-row px-4">
<h1>@PageState.Page.Name - Theme #2</h1> <div class="ml-md-auto"><UserProfile /> <Login /> <ControlPanel /></div> <h1>@PageState.Page.Name</h1> <div class="ml-md-auto"><UserProfile /> <Login /> <ControlPanel /></div>
</div> </div>
<div class="container"> <div class="container">
<div class="row px-4"> <div class="row px-4">
@ -24,6 +24,11 @@
</div> </div>
@code { @code {
public override string Name { get { return "Theme2"; } }
public override string Panes { get { return "Top;Bottom"; } } public override string Panes { get { return "Top;Bottom"; } }
protected override async Task OnParametersSetAsync()
{
await IncludeCSS("Theme.css");
}
} }

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Oqtane.Themes.Theme2 namespace Oqtane.Themes.BlazorTheme
{ {
public class Theme : ITheme public class Theme : ITheme
{ {
@ -10,7 +10,7 @@ namespace Oqtane.Themes.Theme2
{ {
Dictionary<string, string> properties = new Dictionary<string, string> Dictionary<string, string> properties = new Dictionary<string, string>
{ {
{ "Name", "Theme2" }, { "Name", "Blazor Theme" },
{ "Version", "1.0.0" } { "Version", "1.0.0" }
}; };
return properties; return properties;

View File

@ -33,16 +33,6 @@ namespace Oqtane.Themes
return "Themes/" + this.GetType().Namespace + "/"; return "Themes/" + this.GetType().Namespace + "/";
} }
public async Task AddCSS(string Url)
{
if (!Url.StartsWith("http"))
{
Url = ThemePath() + Url;
}
var interop = new Interop(JSRuntime);
await interop.AddCSS("Theme:" + Utilities.CreateIdFromUrl(Url), Url);
}
public string NavigateUrl() public string NavigateUrl()
{ {
return NavigateUrl(PageState.Page.Path); return NavigateUrl(PageState.Page.Path);

View File

@ -9,9 +9,9 @@
@if (UserSecurity.IsAuthorized(PageState.User, "Edit", PageState.Page.Permissions)) @if (UserSecurity.IsAuthorized(PageState.User, "Edit", PageState.Page.Permissions))
{ {
<div id="actions" class="overlay"> <div id="actions" class="app-controlpanel">
<a href="javascript:void(0)" class="closebtn" onclick="closeActions()">x</a> <a href="javascript:void(0)" class="app-controlpanel-close" onclick="closeActions()">x</a>
<div class="overlay-content"> <div class="app-controlpanel-content">
<ul class="nav flex-column"> <ul class="nav flex-column">
<li class="nav-item px-3"> <li class="nav-item px-3">
<NavLink class="btn btn-primary mx-auto" href="@NavigateUrl("admin")">Admin Dashboard</NavLink> <NavLink class="btn btn-primary mx-auto" href="@NavigateUrl("admin")">Admin Dashboard</NavLink>

View File

@ -1,5 +1,6 @@
@namespace Oqtane.Themes.Controls @namespace Oqtane.Themes.Controls
@inherits ThemeControlBase @inherits ThemeControlBase
@inject NavigationManager NavigationManager
@((MarkupString)logo) @((MarkupString)logo)
@ -10,7 +11,8 @@
{ {
if (PageState.Site.Logo != "") if (PageState.Site.Logo != "")
{ {
logo = "<a href=\"" + PageState.Alias.Url + "\"><img src=\"" + PageState.Alias.BaseUrl + "/" + PageState.Site.SiteRootPath + PageState.Site.Logo + "\" alt=\"" + PageState.Site.Name + "\"/></a>"; Uri uri = new Uri(NavigationManager.Uri);
logo = "<a href=\"" + uri.Scheme + "://" + uri.Authority + "\"><img src=\"" + uri.Scheme + "://" + uri.Authority + "/" + PageState.Site.SiteRootPath + PageState.Site.Logo + "\" alt=\"" + PageState.Site.Name + "\"/></a>";
} }
} }
} }

View File

@ -7,7 +7,7 @@
@if (PageState.DesignMode && UserSecurity.IsAuthorized(PageState.User, "Edit", ModuleState.Permissions)) @if (PageState.DesignMode && UserSecurity.IsAuthorized(PageState.User, "Edit", ModuleState.Permissions))
{ {
<div class="dropdown"> <div class="dropdown">
<button type="button" class="btn dropdown-toggle" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button> <button type="button" class="btn app-actions-toggle" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
@foreach (var action in actions) @foreach (var action in actions)
{ {

View File

@ -0,0 +1,7 @@
namespace Oqtane.Themes
{
public interface ILayoutControl
{
}
}

View File

@ -2,7 +2,6 @@
{ {
public interface IThemeControl public interface IThemeControl
{ {
string Name { get; } string Panes { get; } // identifies all panes in a theme ( delimited by ";" ) - assumed to be a layout if no panes specified
string Panes { get; } // if a theme has different panes, delimit them with ";"
} }
} }

View File

@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Components;
using Oqtane.Shared;
namespace Oqtane.Themes
{
public class LayoutBase : ComponentBase, ILayoutControl
{
[CascadingParameter]
protected PageState PageState { get; set; }
public virtual string Panes { get; set; }
public string LayoutPath()
{
return "Themes/" + this.GetType().Namespace + "/";
}
}
}

View File

@ -1,4 +1,4 @@
@namespace Oqtane.Themes.Theme2 @namespace Oqtane.Themes.OqtaneTheme
@inherits ContainerBase @inherits ContainerBase
<div class="container"> <div class="container">
<div class="row px-4"> <div class="row px-4">

View File

@ -1,4 +1,4 @@
@namespace Oqtane.Themes.Theme1 @namespace Oqtane.Themes.OqtaneTheme
@inherits ThemeBase @inherits ThemeBase
<div class="sidebar"> <div class="sidebar">
@ -8,16 +8,14 @@
<div class="main"> <div class="main">
<div class="top-row px-4"> <div class="top-row px-4">
<h1>@PageState.Page.Name - Theme #1</h1> <div class="ml-md-auto"><UserProfile /> <Login /> <ControlPanel /></div> <h1>@PageState.Page.Name</h1> <div class="ml-md-auto"><UserProfile /> <Login /> <ControlPanel /></div>
</div> </div>
<div class="container"> <div class="container">
<div class="row px-4"> <div class="row px-4">
<div class="col-sm"> <Pane Name="Top" />
<Pane Name="Left" /> </div>
</div> <div class="row px-4">
<div class="col-sm"> <Pane Name="Bottom" />
<Pane Name="Right" />
</div>
</div> </div>
<div class="row px-4"> <div class="row px-4">
<Pane Name="Admin" /> <Pane Name="Admin" />
@ -26,6 +24,10 @@
</div> </div>
@code { @code {
public override string Name { get { return "Theme1"; } }
public override string Panes { get { return "Left;Right"; } } public override string Panes { get { return "Left;Right"; } }
protected override async Task OnParametersSetAsync()
{
await IncludeCSS("Theme.css");
}
} }

View File

@ -1,5 +1,5 @@
@namespace Oqtane.Themes.Theme3 @namespace Oqtane.Themes.OqtaneTheme
@inherits ThemeBase @inherits LayoutBase
<div class="row px-4"> <div class="row px-4">
<div class="col-sm"> <div class="col-sm">
@ -11,6 +11,5 @@
</div> </div>
@code { @code {
public override string Name { get { return "Horizontal Layout"; } }
public override string Panes { get { return "Left;Right"; } } public override string Panes { get { return "Left;Right"; } }
} }

View File

@ -1,4 +1,4 @@
@namespace Oqtane.Themes.Theme3 @namespace Oqtane.Themes.OqtaneTheme
@inherits ThemeBase @inherits ThemeBase
<div class="sidebar"> <div class="sidebar">
@ -8,7 +8,7 @@
<div class="main"> <div class="main">
<div class="top-row px-4"> <div class="top-row px-4">
<h1>@PageState.Page.Name - Theme #3</h1> <div class="ml-md-auto"><UserProfile /> <Login /> <ControlPanel /></div> <h1>@PageState.Page.Name</h1> <div class="ml-md-auto"><UserProfile /> <Login /> <ControlPanel /></div>
</div> </div>
<div class="container"> <div class="container">
<PaneLayout /> <PaneLayout />
@ -19,6 +19,8 @@
</div> </div>
@code { @code {
public override string Name { get { return "Theme3"; } } protected override async Task OnParametersSetAsync()
public override string Panes { get { return ""; } } {
await IncludeCSS("Theme.css");
}
} }

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Oqtane.Themes.Theme1 namespace Oqtane.Themes.OqtaneTheme
{ {
public class Theme : ITheme public class Theme : ITheme
{ {
@ -10,7 +10,7 @@ namespace Oqtane.Themes.Theme1
{ {
Dictionary<string, string> properties = new Dictionary<string, string> Dictionary<string, string> properties = new Dictionary<string, string>
{ {
{ "Name", "Theme1" }, { "Name", "Oqtane Theme" },
{ "Version", "1.0.0" } { "Version", "1.0.0" }
}; };
return properties; return properties;

View File

@ -1,5 +1,5 @@
@namespace Oqtane.Themes.Theme3 @namespace Oqtane.Themes.OqtaneTheme
@inherits ThemeBase @inherits LayoutBase
<div class="row px-4"> <div class="row px-4">
<Pane Name="Top" /> <Pane Name="Top" />
@ -9,6 +9,5 @@
</div> </div>
@code { @code {
public override string Name { get { return "Vertical Layout"; } }
public override string Panes { get { return "Top;Bottom"; } } public override string Panes { get { return "Top;Bottom"; } }
} }

View File

@ -1,13 +0,0 @@
@namespace Oqtane.Themes.Theme1
@inherits ContainerBase
<div class="container">
<div class="row px-4">
<ModuleActions /><h2><ModuleTitle /></h2>
<hr style="width: 100%; color: gray; height: 1px; background-color:gray;" />
</div>
<div class="row px-4">
<div class="container">
<ModuleInstance />
</div>
</div>
</div>

View File

@ -1,20 +0,0 @@
using System.Collections.Generic;
namespace Oqtane.Themes.Theme3
{
public class Theme : ITheme
{
public Dictionary<string, string> Properties
{
get
{
Dictionary<string, string> properties = new Dictionary<string, string>
{
{ "Name", "Theme3" },
{ "Version", "1.0.0" }
};
return properties;
}
}
}
}

View File

@ -12,7 +12,6 @@ namespace Oqtane.Themes
[CascadingParameter] [CascadingParameter]
protected PageState PageState { get; set; } protected PageState PageState { get; set; }
public virtual string Name { get; set; }
public virtual string Panes { get; set; } public virtual string Panes { get; set; }
public string ThemePath() public string ThemePath()
@ -20,14 +19,14 @@ namespace Oqtane.Themes
return "Themes/" + this.GetType().Namespace + "/"; return "Themes/" + this.GetType().Namespace + "/";
} }
public async Task AddCSS(string Url) public async Task IncludeCSS(string Url)
{ {
if (!Url.StartsWith("http")) if (!Url.StartsWith("http"))
{ {
Url = ThemePath() + Url; Url = ThemePath() + Url;
} }
var interop = new Interop(JSRuntime); var interop = new Interop(JSRuntime);
await interop.AddCSS("Theme:" + Utilities.CreateIdFromUrl(Url), Url); await interop.IncludeCSS("Theme", Url);
} }
public string NavigateUrl() public string NavigateUrl()

View File

@ -10,144 +10,8 @@ app {
flex-direction: column; flex-direction: column;
} }
.top-row {
height: 3.5rem;
display: flex;
align-items: center;
}
.main {
flex: 1;
}
.main .top-row {
background-color: #e6e6e6;
border-bottom: 1px solid #d6d5d5;
}
.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.sidebar .top-row {
background-color: rgba(0,0,0,0.4);
}
.sidebar .navbar-brand {
font-size: 1.1rem;
}
.sidebar .oi {
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item a {
color: #d7d7d7;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
}
.nav-item a.active {
background-color: rgba(255,255,255,0.25);
color: white;
}
.nav-item a:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.content {
padding-top: 1.1rem;
}
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}
@media (max-width: 767.98px) {
.main .top-row {
display: none;
}
}
@media (min-width: 768px) {
app {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.main .top-row {
position: sticky;
top: 0;
z-index: 9999;
}
.main > div {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
.navbar-toggler {
display: none;
}
.sidebar .collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
}
@-webkit-keyframes sk-stretchdelay {
0%, 40%, 100% {
-webkit-transform: scaleY(0.4)
}
20% {
-webkit-transform: scaleY(1.0)
}
}
@keyframes sk-stretchdelay {
0%, 40%, 100% {
transform: scaleY(0.4);
-webkit-transform: scaleY(0.4);
}
20% {
transform: scaleY(1.0);
-webkit-transform: scaleY(1.0);
}
}
/* Control Panel */ /* Control Panel */
.overlay { .app-controlpanel {
/* Height & width depends on how you want to reveal the overlay (see JS below) */
height: 100%; height: 100%;
width: 0; width: 0;
position: fixed; /* Stay in place */ position: fixed; /* Stay in place */
@ -161,7 +25,7 @@ app {
} }
/* Position the content inside the overlay */ /* Position the content inside the overlay */
.overlay-content { .app-controlpanel-content {
position: relative; position: relative;
top: 5%; /* 5% from the top */ top: 5%; /* 5% from the top */
width: 100%; /* 100% width */ width: 100%; /* 100% width */
@ -170,7 +34,7 @@ app {
} }
/* Position the close button (top right corner) */ /* Position the close button (top right corner) */
.overlay .closebtn { .app-controlpanel .closebtn {
position: absolute; position: absolute;
top: 20px; top: 20px;
right: 45px; right: 45px;
@ -179,11 +43,11 @@ app {
/* When the height of the screen is less than 450 pixels, change the font-size of the links and position the close button again, so they don't overlap */ /* When the height of the screen is less than 450 pixels, change the font-size of the links and position the close button again, so they don't overlap */
@media screen and (max-height: 450px) { @media screen and (max-height: 450px) {
.overlay a { .app-controlpanel a {
font-size: 20px font-size: 20px
} }
.overlay .closebtn { .app-controlpanel-close {
font-size: 40px; font-size: 40px;
top: 15px; top: 15px;
right: 35px; right: 35px;
@ -191,7 +55,7 @@ app {
} }
/* Admin Modal */ /* Admin Modal */
.modal { .app-admin-modal {
display: none; /* Hidden by default */ display: none; /* Hidden by default */
position: fixed; /* Stay in place */ position: fixed; /* Stay in place */
z-index: 9999; /* Sit on top */ z-index: 9999; /* Sit on top */
@ -204,7 +68,7 @@ app {
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
} }
.modal-content { .app-admin-modal-content {
background-color: #fefefe; background-color: #fefefe;
margin: 5% auto; /* 5% from the top and centered */ margin: 5% auto; /* 5% from the top and centered */
padding: 20px; padding: 20px;
@ -212,22 +76,22 @@ app {
width: 80%; /* Could be more or less, depending on screen size */ width: 80%; /* Could be more or less, depending on screen size */
} }
.close { .app-admin-modal-close {
position: absolute; position: absolute;
top: 20px; top: 20px;
right: 45px; right: 45px;
font-size: 40px; font-size: 40px;
} }
.close:hover, .app-admin-modal-close:hover,
.close:focus { .app-admin-modal-close:focus {
color: black; color: black;
text-decoration: none; text-decoration: none;
cursor: pointer; cursor: pointer;
} }
/* Action Menu */ /* Action Menu */
.dropdown-toggle { .app-actions-toggle {
background-color: transparent; background-color: transparent;
border-color: #fff; border-color: #fff;
border-style: hidden; border-style: hidden;
@ -236,20 +100,20 @@ app {
border-left: none; border-left: none;
} }
.pane-admin-border { .app-pane-admin-border {
width: 100%; width: 100%;
border-width: 1px; border-width: 1px;
border-style: dashed; border-style: dashed;
border-color: gray; border-color: gray;
} }
.pane-admin-title { .app-pane-admin-title {
width: 100%; width: 100%;
text-align: center; text-align: center;
color: gray; color: gray;
} }
.loading { .app-progress-indicator {
background: rgba(0,0,0,0.2) url('../loading.gif') no-repeat 50% 50%; background: rgba(0,0,0,0.2) url('../loading.gif') no-repeat 50% 50%;
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@ -1,259 +0,0 @@
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
app {
position: relative;
display: flex;
flex-direction: column;
}
.top-row {
height: 3.5rem;
display: flex;
align-items: center;
}
.main {
flex: 1;
}
.main .top-row {
background-color: #e6e6e6;
border-bottom: 1px solid #d6d5d5;
}
.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.sidebar .top-row {
background-color: rgba(0,0,0,0.4);
}
.sidebar .navbar-brand {
font-size: 1.1rem;
}
.sidebar .oi {
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item a {
color: #d7d7d7;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
}
.nav-item a.active {
background-color: rgba(255,255,255,0.25);
color: white;
}
.nav-item a:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.content {
padding-top: 1.1rem;
}
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}
@media (max-width: 767.98px) {
.main .top-row {
display: none;
}
}
@media (min-width: 768px) {
app {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.main .top-row {
position: sticky;
top: 0;
z-index: 9999;
}
.main > div {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
.navbar-toggler {
display: none;
}
.sidebar .collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
}
@-webkit-keyframes sk-stretchdelay {
0%, 40%, 100% {
-webkit-transform: scaleY(0.4)
}
20% {
-webkit-transform: scaleY(1.0)
}
}
@keyframes sk-stretchdelay {
0%, 40%, 100% {
transform: scaleY(0.4);
-webkit-transform: scaleY(0.4);
}
20% {
transform: scaleY(1.0);
-webkit-transform: scaleY(1.0);
}
}
/* Control Panel */
.overlay {
height: 100%;
width: 0;
position: fixed; /* Stay in place */
z-index: 9999; /* Sit on top */
right: 0; /* Position at right side of screen */
top: 0; /* Position at top of screen */
background-color: rgb(0,0,0); /* Black fallback color */
background-color: rgba(0,0,0, 0.9); /* Black w/opacity */
overflow-x: hidden; /* Disable horizontal scroll */
transition: 0.5s; /* 0.5 second transition effect to slide in or slide down the overlay (height or width, depending on reveal) */
}
/* Position the content inside the overlay */
.overlay-content {
position: relative;
top: 5%; /* 5% from the top */
width: 100%; /* 100% width */
text-align: center; /* Centered text/links */
margin-top: 30px; /* 30px top margin to avoid conflict with the close button on smaller screens */
}
/* Position the close button (top right corner) */
.overlay .closebtn {
position: absolute;
top: 20px;
right: 45px;
font-size: 40px;
}
/* When the height of the screen is less than 450 pixels, change the font-size of the links and position the close button again, so they don't overlap */
@media screen and (max-height: 450px) {
.overlay a {
font-size: 20px
}
.overlay .closebtn {
font-size: 40px;
top: 15px;
right: 35px;
}
}
/* Admin Modal */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 9999; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
.modal-content {
background-color: #fefefe;
margin: 5% auto; /* 5% from the top and centered */
padding: 20px;
border: 1px solid #888;
width: 80%; /* Could be more or less, depending on screen size */
}
.close {
position: absolute;
top: 20px;
right: 45px;
font-size: 40px;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
/* Action Menu */
.dropdown-toggle {
background-color: transparent;
border-color: #fff;
border-style: hidden;
border-top: none;
border-right: none;
border-left: none;
}
.pane-admin-border {
width: 100%;
border-width: 1px;
border-style: dashed;
border-color: gray;
}
.pane-admin-title {
width: 100%;
text-align: center;
color: gray;
}
.loading {
background: rgba(0,0,0,0.2) url('../loading.gif') no-repeat 50% 50%;
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 9999; /* Sit on top */
}

View File

@ -6,7 +6,7 @@
<title>Oqtane</title> <title>Oqtane</title>
<base href="/" /> <base href="/" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link href="css/site.css" rel="stylesheet" /> <link href="css/app.css" rel="stylesheet" />
</head> </head>
<body> <body>
<app> <app>

View File

@ -28,21 +28,19 @@ window.interop = {
return ""; return "";
} }
}, },
addCSS: function (id, url) { includeCSS: function (id, url) {
if (document.getElementById(id) === null) { var link = document.getElementById('yourid');
var link = document.createElement("link"); if (link === null) {
link = document.createElement("link");
link.id = id; link.id = id;
link.type = "text/css"; link.type = "text/css";
link.rel = "stylesheet"; link.rel = "stylesheet";
link.href = url; link.href = url;
document.head.appendChild(link); document.head.appendChild(link);
} }
}, else {
removeCSS: function (pattern) { if (link.href !== url) {
var links = document.getElementsByTagName("link"); link.setAttribute('href', url);
for (var i = 0; i < links.length; i++) {
if (links[i].id.includes(pattern)) {
document.head.removeChild(links[i]);
} }
} }
}, },

View File

@ -210,6 +210,19 @@ namespace Oqtane.Controllers
} }
else else
{ {
using (var db = new InstallationContext(connectionString))
{
ApplicationVersion version = db.ApplicationVersion.ToList().LastOrDefault();
if (version == null || version.Version != Constants.Version)
{
version = new ApplicationVersion();
version.Version = Constants.Version;
version.CreatedOn = DateTime.Now;
db.ApplicationVersion.Add(version);
db.SaveChanges();
}
}
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies() Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies()
.Where(item => item.FullName.Contains(".Module.")).ToArray(); .Where(item => item.FullName.Contains(".Module.")).ToArray();
@ -283,6 +296,7 @@ namespace Oqtane.Controllers
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer(_connectionString); => optionsBuilder.UseSqlServer(_connectionString);
public virtual DbSet<ApplicationVersion> ApplicationVersion { get; set; }
public virtual DbSet<Tenant> Tenant { get; set; } public virtual DbSet<Tenant> Tenant { get; set; }
} }
} }

View File

@ -11,7 +11,7 @@
<title>Oqtane</title> <title>Oqtane</title>
<base href="~/" /> <base href="~/" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link href="css/site.css" rel="stylesheet" /> <link href="css/app.css" rel="stylesheet" />
</head> </head>
<body> <body>
@(Html.AntiForgeryToken()) @(Html.AntiForgeryToken())

View File

@ -19,7 +19,7 @@ namespace Oqtane.Repository
public TenantDBContext(ITenantResolver TenantResolver, IHttpContextAccessor accessor) : base(TenantResolver, accessor) public TenantDBContext(ITenantResolver TenantResolver, IHttpContextAccessor accessor) : base(TenantResolver, accessor)
{ {
// ContextBase handles multi-tenant database connections // DBContextBase handles multi-tenant database connections
} }
} }

View File

@ -36,13 +36,13 @@ namespace Oqtane.Repository
// define the default site template // define the default site template
SiteTemplate = new List<PageTemplate>(); SiteTemplate = new List<PageTemplate>();
SiteTemplate.Add(new PageTemplate { Name = "Home", Parent = "", Path = "", Order = 1, Icon = "home", IsNavigation = true, EditMode = false, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "Home", Parent = "", Path = "", Order = 1, Icon = "home", IsNavigation = true, EditMode = false, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Welcome To Oqtane...", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Welcome To Oqtane...", Pane = "Top", ContainerType = Constants.DefaultContainer,
Content = "<p><a href=\"https://www.oqtane.org\" target=\"_new\">Oqtane</a> is an open source <b>modular application framework</b> built from the ground up using modern .NET Core technology. It leverages the revolutionary new Blazor component model to create a <b>fully dynamic</b> web development experience which can be executed on a client or server. Whether you are looking for a platform to <b>accelerate your web development</b> efforts, or simply interested in exploring the anatomy of a large-scale Blazor application, Oqtane provides a solid foundation based on proven enterprise architectural principles.</p>" + Content = "<p><a href=\"https://www.oqtane.org\" target=\"_new\">Oqtane</a> is an open source <b>modular application framework</b> built from the ground up using modern .NET Core technology. It leverages the revolutionary new Blazor component model to create a <b>fully dynamic</b> web development experience which can be executed on a client or server. Whether you are looking for a platform to <b>accelerate your web development</b> efforts, or simply interested in exploring the anatomy of a large-scale Blazor application, Oqtane provides a solid foundation based on proven enterprise architectural principles.</p>" +
"<p align=\"center\"><a href=\"https://www.oqtane.org\" target=\"_new\"><img src=\"oqtane.png\"></a><br /><br /><a class=\"btn btn-primary\" href=\"https://www.oqtane.org/Community\" target=\"_new\">Join Our Community</a>&nbsp;&nbsp;<a class=\"btn btn-primary\" href=\"https://github.com/oqtane/oqtane.framework\" target=\"_new\">Clone Our Repo</a><br /><br /></p>" + "<p align=\"center\"><a href=\"https://www.oqtane.org\" target=\"_new\"><img src=\"oqtane.png\"></a><br /><br /><a class=\"btn btn-primary\" href=\"https://www.oqtane.org/Community\" target=\"_new\">Join Our Community</a>&nbsp;&nbsp;<a class=\"btn btn-primary\" href=\"https://github.com/oqtane/oqtane.framework\" target=\"_new\">Clone Our Repo</a><br /><br /></p>" +
"<p><a href=\"https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor\" target=\"_new\">Blazor</a> is a single-page app framework that lets you build interactive web applications using C# instead of JavaScript. Client-side Blazor relies on WebAssembly, an open web standard that does not require plugins or code transpilation in order to run natively in a web browser. Server-side Blazor uses SignalR to host your application on a web server and provide a responsive and robust debugging experience. Blazor applications works in all modern web browsers, including mobile browsers.</p>" + "<p><a href=\"https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor\" target=\"_new\">Blazor</a> is a single-page app framework that lets you build interactive web applications using C# instead of JavaScript. Client-side Blazor relies on WebAssembly, an open web standard that does not require plugins or code transpilation in order to run natively in a web browser. Server-side Blazor uses SignalR to host your application on a web server and provide a responsive and robust debugging experience. Blazor applications works in all modern web browsers, including mobile browsers.</p>" +
"<p>Blazor is a feature of <a href=\"https://dotnet.microsoft.com/apps/aspnet\" target=\"_new\">ASP.NET Core 3.0</a>, the popular cross platform web development framework from Microsoft that extends the <a href=\"https://dotnet.microsoft.com/learn/dotnet/what-is-dotnet\" target=\"_new\" >.NET developer platform</a> with tools and libraries for building web apps.</p>" "<p>Blazor is a feature of <a href=\"https://dotnet.microsoft.com/apps/aspnet\" target=\"_new\">ASP.NET Core 3.0</a>, the popular cross platform web development framework from Microsoft that extends the <a href=\"https://dotnet.microsoft.com/learn/dotnet/what-is-dotnet\" target=\"_new\" >.NET developer platform</a> with tools and libraries for building web apps.</p>"
}, },
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "MIT License", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "MIT License", Pane = "Top", ContainerType = Constants.DefaultContainer,
Content = "<p>Copyright (c) 2019 .NET Foundation</p>" + Content = "<p>Copyright (c) 2019 .NET Foundation</p>" +
"<p>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</p>" + "<p>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</p>" +
"<p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</p>" + "<p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</p>" +
@ -51,43 +51,43 @@ namespace Oqtane.Repository
} }
}); });
SiteTemplate.Add(new PageTemplate { Name = "Admin", Parent = "", Path = "admin", Order = 1, Icon = "", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "Admin", Parent = "", Path = "admin", Order = 1, Icon = "", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Dashboard, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Administration", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", Content = "" } new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Dashboard, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Administration", Pane = "Top", ContainerType = Constants.DefaultContainer, Content = "" }
}}); }});
SiteTemplate.Add(new PageTemplate { Name = "Site Management", Parent = "Admin", Path = "admin/sites", Order = 1, Icon = "globe", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "Site Management", Parent = "Admin", Path = "admin/sites", Order = 1, Icon = "globe", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Sites, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Site Management", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", Content = "" } new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Sites, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Site Management", Pane = "Top", ContainerType = Constants.DefaultContainer, Content = "" }
}}); }});
SiteTemplate.Add(new PageTemplate { Name = "Page Management", Parent = "Admin", Path = "admin/pages", Order = 1, Icon = "layers", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "Page Management", Parent = "Admin", Path = "admin/pages", Order = 1, Icon = "layers", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Pages, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Page Management", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", Content = "" } new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Pages, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Page Management", Pane = "Top", ContainerType = Constants.DefaultContainer, Content = "" }
}}); }});
SiteTemplate.Add(new PageTemplate { Name = "File Management", Parent = "Admin", Path = "admin/files", Order = 1, Icon = "file", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "File Management", Parent = "Admin", Path = "admin/files", Order = 1, Icon = "file", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Files, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "File Management", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", Content = "" } new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Files, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "File Management", Pane = "Top", ContainerType = Constants.DefaultContainer, Content = "" }
}}); }});
SiteTemplate.Add(new PageTemplate { Name = "User Management", Parent = "Admin", Path = "admin/users", Order = 1, Icon = "person", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "User Management", Parent = "Admin", Path = "admin/users", Order = 1, Icon = "person", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Users, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "User Management", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", Content = "" } new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Users, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "User Management", Pane = "Top", ContainerType = Constants.DefaultContainer, Content = "" }
}}); }});
SiteTemplate.Add(new PageTemplate { Name = "Role Management", Parent = "Admin", Path = "admin/roles", Order = 1, Icon = "lock-locked", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "Role Management", Parent = "Admin", Path = "admin/roles", Order = 1, Icon = "lock-locked", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Roles, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Role Management", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", Content = "" } new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Roles, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Role Management", Pane = "Top", ContainerType = Constants.DefaultContainer, Content = "" }
}}); }});
SiteTemplate.Add(new PageTemplate { Name = "Tenant Management", Parent = "Admin", Path = "admin/tenants", Order = 1, Icon = "list", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "Tenant Management", Parent = "Admin", Path = "admin/tenants", Order = 1, Icon = "list", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Tenants, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Tenant Management", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", Content = "" } new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Tenants, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Tenant Management", Pane = "Top", ContainerType = Constants.DefaultContainer, Content = "" }
}}); }});
SiteTemplate.Add(new PageTemplate { Name = "Module Management", Parent = "Admin", Path = "admin/modules", Order = 1, Icon = "browser", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "Module Management", Parent = "Admin", Path = "admin/modules", Order = 1, Icon = "browser", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.ModuleDefinitions, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Module Management", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", Content = "" } new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.ModuleDefinitions, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Module Management", Pane = "Top", ContainerType = Constants.DefaultContainer, Content = "" }
}}); }});
SiteTemplate.Add(new PageTemplate { Name = "Theme Management", Parent = "Admin", Path = "admin/themes", Order = 1, Icon = "brush", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "Theme Management", Parent = "Admin", Path = "admin/themes", Order = 1, Icon = "brush", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Themes, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Theme Management", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", Content = "" } new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Themes, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Theme Management", Pane = "Top", ContainerType = Constants.DefaultContainer, Content = "" }
}}); }});
SiteTemplate.Add(new PageTemplate { Name = "Upgrade Service", Parent = "Admin", Path = "admin/upgrade", Order = 1, Icon = "aperture", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "Upgrade Service", Parent = "Admin", Path = "admin/upgrade", Order = 1, Icon = "aperture", IsNavigation = false, EditMode = true, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Upgrade, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Upgrade Service", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", Content = "" } new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Upgrade, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "Upgrade Service", Pane = "Top", ContainerType = Constants.DefaultContainer, Content = "" }
}}); }});
SiteTemplate.Add(new PageTemplate { Name = "Login", Parent = "", Path = "login", Order = 1, Icon = "lock-locked", IsNavigation = false, EditMode = false, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "Login", Parent = "", Path = "login", Order = 1, Icon = "lock-locked", IsNavigation = false, EditMode = false, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Login, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "User Login", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", Content = "" } new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Login, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "User Login", Pane = "Top", ContainerType = Constants.DefaultContainer, Content = "" }
}}); }});
SiteTemplate.Add(new PageTemplate { Name = "Register", Parent = "", Path = "register", Order = 1, Icon = "person", IsNavigation = false, EditMode = false, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "Register", Parent = "", Path = "register", Order = 1, Icon = "person", IsNavigation = false, EditMode = false, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Register, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "User Registration", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", Content = "" } new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Register, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "User Registration", Pane = "Top", ContainerType = Constants.DefaultContainer, Content = "" }
}}); }});
SiteTemplate.Add(new PageTemplate { Name = "Profile", Parent = "", Path = "profile", Order = 1, Icon = "person", IsNavigation = false, EditMode = false, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> { SiteTemplate.Add(new PageTemplate { Name = "Profile", Parent = "", Path = "profile", Order = 1, Icon = "person", IsNavigation = false, EditMode = false, PagePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", PageTemplateModules = new List<PageTemplateModule> {
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Profile, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "User Profile", Pane = "Top", ContainerType = "Oqtane.Themes.Theme2.Container2, Oqtane.Client", Content = "" } new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.Profile, Oqtane.Client", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]", Title = "User Profile", Pane = "Top", ContainerType = Constants.DefaultContainer, Content = "" }
}}); }});
} }

View File

@ -23,9 +23,9 @@ namespace Oqtane.Repository
aliasname = accessor.HttpContext.Request.Host.Value; aliasname = accessor.HttpContext.Request.Host.Value;
string path = accessor.HttpContext.Request.Path.Value; string path = accessor.HttpContext.Request.Path.Value;
string[] segments = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); string[] segments = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
if (segments.Length > 0 && segments[0] == "api" && segments[1] != "~") if (segments.Length > 1 && segments[1] == "api" && segments[0] != "~")
{ {
aliasname += "/" + segments[1]; aliasname += "/" + segments[0];
} }
if (aliasname.EndsWith("/")) if (aliasname.EndsWith("/"))
{ {

View File

@ -88,15 +88,22 @@ namespace Oqtane.Repository
index = themes.FindIndex(item => item.ThemeName == Namespace); index = themes.FindIndex(item => item.ThemeName == Namespace);
} }
theme = themes[index]; theme = themes[index];
// layouts and themes theme.ThemeControls += (themeControlType.FullName + ", " + typename[1] + ";");
if (themeControlType.FullName.EndsWith("Layout"))
// layouts
Type[] layouttypes = assembly.GetTypes()
.Where(item => item.Namespace != null)
.Where(item => item.Namespace.StartsWith(Namespace))
.Where(item => item.GetInterfaces().Contains(typeof(ILayoutControl))).ToArray();
foreach (Type layouttype in layouttypes)
{ {
theme.PaneLayouts += (themeControlType.FullName + ", " + typename[1] + ";"); string panelayout = layouttype.FullName + ", " + typename[1] + ";";
} if (!theme.PaneLayouts.Contains(panelayout))
else {
{ theme.PaneLayouts += panelayout;
theme.ThemeControls += (themeControlType.FullName + ", " + typename[1] + ";"); }
} }
// containers // containers
Type[] containertypes = assembly.GetTypes() Type[] containertypes = assembly.GetTypes()
.Where(item => item.Namespace != null) .Where(item => item.Namespace != null)
@ -104,8 +111,13 @@ namespace Oqtane.Repository
.Where(item => item.GetInterfaces().Contains(typeof(IContainerControl))).ToArray(); .Where(item => item.GetInterfaces().Contains(typeof(IContainerControl))).ToArray();
foreach (Type containertype in containertypes) foreach (Type containertype in containertypes)
{ {
theme.ContainerControls += (containertype.FullName + ", " + typename[1] + ";"); string container = containertype.FullName + ", " + typename[1] + ";";
if (!theme.ContainerControls.Contains(container))
{
theme.ContainerControls += container;
}
} }
themes[index] = theme; themes[index] = theme;
} }
} }

View File

@ -24,6 +24,7 @@ CREATE TABLE [dbo].[Tenant](
[Name] [nvarchar](100) NOT NULL, [Name] [nvarchar](100) NOT NULL,
[DBConnectionString] [nvarchar](1024) NOT NULL, [DBConnectionString] [nvarchar](1024) NOT NULL,
[DBSchema] [nvarchar](50) NOT NULL, [DBSchema] [nvarchar](50) NOT NULL,
[IsInitialized] [bit] NOT NULL,
[CreatedBy] [nvarchar](256) NOT NULL, [CreatedBy] [nvarchar](256) NOT NULL,
[CreatedOn] [datetime] NOT NULL, [CreatedOn] [datetime] NOT NULL,
[ModifiedBy] [nvarchar](256) NOT NULL, [ModifiedBy] [nvarchar](256) NOT NULL,
@ -49,6 +50,17 @@ CREATE TABLE [dbo].[ModuleDefinition](
) )
GO GO
CREATE TABLE [dbo].[ApplicationVersion](
[ApplicationVersionId] [int] IDENTITY(1,1) NOT NULL,
[Version] [nvarchar](50) NOT NULL,
[CreatedOn] [datetime] NOT NULL
CONSTRAINT [PK_ApplicationVersion] PRIMARY KEY CLUSTERED
(
[ApplicationVersionId] ASC
)
)
GO
/* /*
Create foreign key relationships Create foreign key relationships
@ -66,8 +78,8 @@ Create seed data
*/ */
SET IDENTITY_INSERT [dbo].[Tenant] ON SET IDENTITY_INSERT [dbo].[Tenant] ON
GO GO
INSERT [dbo].[Tenant] ([TenantId], [Name], [DBConnectionString], [DBSchema], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn]) INSERT [dbo].[Tenant] ([TenantId], [Name], [DBConnectionString], [DBSchema], [IsInitialized], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn])
VALUES (1, N'Tenant1', N'{ConnectionString}', N'', '', getdate(), '', getdate()) VALUES (1, N'Master', N'{ConnectionString}', N'', 1, '', getdate(), '', getdate())
GO GO
SET IDENTITY_INSERT [dbo].[Tenant] OFF SET IDENTITY_INSERT [dbo].[Tenant] OFF
GO GO

View File

@ -0,0 +1,135 @@

.top-row {
height: 3.5rem;
display: flex;
align-items: center;
}
.main {
flex: 1;
}
.main .top-row {
background-color: #e6e6e6;
border-bottom: 1px solid #d6d5d5;
}
.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.sidebar .top-row {
background-color: rgba(0,0,0,0.4);
}
.sidebar .navbar-brand {
font-size: 1.1rem;
}
.sidebar .oi {
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item a {
color: #d7d7d7;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
}
.nav-item a.active {
background-color: rgba(255,255,255,0.25);
color: white;
}
.nav-item a:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.content {
padding-top: 1.1rem;
}
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}
@media (max-width: 767.98px) {
.main .top-row {
display: none;
}
}
@media (min-width: 768px) {
app {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.main .top-row {
position: sticky;
top: 0;
z-index: 9999;
}
.main > div {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
.navbar-toggler {
display: none;
}
.sidebar .collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
}
@-webkit-keyframes sk-stretchdelay {
0%, 40%, 100% {
-webkit-transform: scaleY(0.4)
}
20% {
-webkit-transform: scaleY(1.0)
}
}
@keyframes sk-stretchdelay {
0%, 40%, 100% {
transform: scaleY(0.4);
-webkit-transform: scaleY(0.4);
}
20% {
transform: scaleY(1.0);
-webkit-transform: scaleY(1.0);
}
}

View File

@ -0,0 +1,135 @@

.top-row {
height: 3.5rem;
display: flex;
align-items: center;
}
.main {
flex: 1;
}
.main .top-row {
background-color: #e6e6e6;
border-bottom: 1px solid #d6d5d5;
}
.sidebar {
background-image: linear-gradient(180deg, black 0%, black 70%);
}
.sidebar .top-row {
background-color: rgba(0,0,0,0.4);
}
.sidebar .navbar-brand {
font-size: 1.1rem;
}
.sidebar .oi {
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item a {
color: #FFFFFF;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
}
.nav-item a.active {
background-color: rgba(255,255,255,0.25);
color: white;
}
.nav-item a:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.content {
padding-top: 1.1rem;
}
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}
@media (max-width: 767.98px) {
.main .top-row {
display: none;
}
}
@media (min-width: 768px) {
app {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.main .top-row {
position: sticky;
top: 0;
z-index: 9999;
}
.main > div {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
.navbar-toggler {
display: none;
}
.sidebar .collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
}
@-webkit-keyframes sk-stretchdelay {
0%, 40%, 100% {
-webkit-transform: scaleY(0.4)
}
20% {
-webkit-transform: scaleY(1.0)
}
}
@keyframes sk-stretchdelay {
0%, 40%, 100% {
transform: scaleY(0.4);
-webkit-transform: scaleY(0.4);
}
20% {
transform: scaleY(1.0);
-webkit-transform: scaleY(1.0);
}
}

View File

@ -0,0 +1,124 @@
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
app {
position: relative;
display: flex;
flex-direction: column;
}
/* Control Panel */
.app-controlpanel {
height: 100%;
width: 0;
position: fixed; /* Stay in place */
z-index: 9999; /* Sit on top */
right: 0;
top: 0;
background-color: rgb(0,0,0); /* Black fallback color */
background-color: rgba(0,0,0, 0.9); /* Black w/opacity */
overflow-x: hidden; /* Disable horizontal scroll */
transition: 0.5s; /* 0.5 second transition effect to slide in or slide down the overlay (height or width, depending on reveal) */
}
/* Position the content inside the overlay */
.app-controlpanel-content {
position: relative;
top: 5%; /* 5% from the top */
width: 100%; /* 100% width */
text-align: center; /* Centered text/links */
margin-top: 30px; /* 30px top margin to avoid conflict with the close button on smaller screens */
}
/* Position the close button (top right corner) */
.app-controlpanel-close {
position: absolute;
top: 20px;
right: 45px;
font-size: 40px;
}
/* When the height of the screen is less than 450 pixels, change the font-size of the links and position the close button again, so they don't overlap */
@media screen and (max-height: 450px) {
.app-controlpanel a {
font-size: 20px
}
.app-controlpanel-close {
font-size: 40px;
top: 15px;
right: 35px;
}
}
/* Admin Modal */
.app-admin-modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 9999; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
.app-admin-modal-content {
background-color: #fefefe;
margin: 5% auto; /* 5% from the top and centered */
padding: 20px;
border: 1px solid #888;
width: 80%; /* Could be more or less, depending on screen size */
}
.app-admin-modal-close {
position: absolute;
top: 20px;
right: 45px;
font-size: 40px;
}
.app-admin-modal-close:hover,
.app-admin-modal-close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
/* Action Menu */
.app-actions-toggle {
background-color: transparent;
border-color: #fff;
border-style: hidden;
border-top: none;
border-right: none;
border-left: none;
}
.app-pane-admin-border {
width: 100%;
border-width: 1px;
border-style: dashed;
border-color: gray;
}
.app-pane-admin-title {
width: 100%;
text-align: center;
color: gray;
}
.app-progress-indicator {
background: rgba(0,0,0,0.2) url('../loading.gif') no-repeat 50% 50%;
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 9999; /* Sit on top */
}

View File

@ -28,21 +28,19 @@ window.interop = {
return ""; return "";
} }
}, },
addCSS: function (id, url) { includeCSS: function (id, url) {
if (document.getElementById(id) === null) { var link = document.getElementById('yourid');
var link = document.createElement("link"); if (link === null) {
link = document.createElement("link");
link.id = id; link.id = id;
link.type = "text/css"; link.type = "text/css";
link.rel = "stylesheet"; link.rel = "stylesheet";
link.href = url; link.href = url;
document.head.appendChild(link); document.head.appendChild(link);
} }
}, else {
removeCSS: function (pattern) { if (link.href !== url) {
var links = document.getElementsByTagName("link"); link.setAttribute('href', url);
for (var i = 0; i < links.length; i++) {
if (links[i].id.includes(pattern)) {
document.head.removeChild(links[i]);
} }
} }
}, },

View File

@ -1,20 +1,3 @@
/* called by index.html to check if mode is set */
function getCookie(name) {
name = name + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
/* Open when someone clicks on the span element */ /* Open when someone clicks on the span element */
function openActions() { function openActions() {
document.getElementById("actions").style.width = "25%"; document.getElementById("actions").style.width = "25%";

View File

@ -15,33 +15,6 @@ namespace Oqtane.Models
public string ModifiedBy { get; set; } public string ModifiedBy { get; set; }
public DateTime ModifiedOn { get; set; } public DateTime ModifiedOn { get; set; }
[NotMapped]
public string Scheme { get; set; }
[NotMapped]
public string Url
{
get
{
return Scheme + "://" + Name;
}
}
[NotMapped]
public string BaseUrl
{
get
{
string name = Name;
if (name.Contains("/"))
{
name = name.Substring(0, name.IndexOf("/"));
}
return Scheme + "://" + name;
}
}
[NotMapped] [NotMapped]
public string Path public string Path
{ {

View File

@ -0,0 +1,11 @@
using System;
namespace Oqtane.Models
{
public class ApplicationVersion
{
public int ApplicationVersionId { get; set; }
public string Version { get; set; }
public DateTime CreatedOn { get; set; }
}
}

View File

@ -8,6 +8,7 @@ namespace Oqtane.Models
public string Name { get; set; } public string Name { get; set; }
public string DBConnectionString { get; set; } public string DBConnectionString { get; set; }
public string DBSchema { get; set; } public string DBSchema { get; set; }
public bool IsInitialized { get; set; }
public string CreatedBy { get; set; } public string CreatedBy { get; set; }
public DateTime CreatedOn { get; set; } public DateTime CreatedOn { get; set; }

View File

@ -5,25 +5,24 @@
public const string PackageId = "Oqtane.Framework"; public const string PackageId = "Oqtane.Framework";
public const string Version = "0.0.1"; public const string Version = "0.0.1";
public const string DefaultPage = "Oqtane.Shared.ThemeBuilder, Oqtane.Client"; public const string PageComponent = "Oqtane.Shared.ThemeBuilder, Oqtane.Client";
public const string DefaultContainer = "Oqtane.Shared.ContainerBuilder, Oqtane.Client"; public const string ContainerComponent = "Oqtane.Shared.ContainerBuilder, Oqtane.Client";
public const string DefaultTheme = "Oqtane.Themes.OqtaneTheme.Default, Oqtane.Client";
public const string DefaultContainer = "Oqtane.Themes.OqtaneTheme.Container, Oqtane.Client";
public const string DefaultAdminContainer = "Oqtane.Themes.AdminContainer, Oqtane.Client"; public const string DefaultAdminContainer = "Oqtane.Themes.AdminContainer, Oqtane.Client";
public static readonly string[] DefaultModuleActions = new[] { "Settings", "Import", "Export" }; public static readonly string[] DefaultModuleActions = new[] { "Settings", "Import", "Export" };
public const string DefaultModuleActionsTemplate = "Oqtane.Modules.Admin.Modules.{Control}, Oqtane.Client"; public const string DefaultModuleActionsTemplate = "Oqtane.Modules.Admin.Modules.{Control}, Oqtane.Client";
public const string PageManagementModule = "Oqtane.Modules.Admin.Pages, Oqtane.Client"; public const string PageManagementModule = "Oqtane.Modules.Admin.Pages, Oqtane.Client";
public const string ModuleMessageControl = "Oqtane.Modules.Controls.ModuleMessage, Oqtane.Client"; public const string ModuleMessageControl = "Oqtane.Modules.Controls.ModuleMessage, Oqtane.Client";
public const string DefaultControl = "Index";
public const string DefaultControl = "Index";
public const string AdminPane = "Admin"; public const string AdminPane = "Admin";
public const string AllUsersRole = "All Users"; public const string AllUsersRole = "All Users";
public const string HostRole = "Host Users"; public const string HostRole = "Host Users";
public const string AdminRole = "Administrators"; public const string AdminRole = "Administrators";
public const string RegisteredRole = "Registered Users"; public const string RegisteredRole = "Registered Users";
public const int ReloadApplication = 3;
public const int ReloadSite = 2;
public const int ReloadPage = 1;
public const int ReloadReset = 0;
} }
} }