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>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
@ -29,23 +28,25 @@
{
try
{
ShowProgressIndicator();
if (await FileService.UploadFilesAsync(PageState.Site.SiteRootPath, files, ""))
{
ModuleInstance.AddModuleMessage("Files Uploaded Successfully", MessageType.Success);
AddModuleMessage("Files Uploaded Successfully", MessageType.Success);
}
else
{
ModuleInstance.AddModuleMessage("Upload Failed", MessageType.Error);
AddModuleMessage("Upload Failed", MessageType.Error);
}
}
catch (Exception ex)
{
ModuleInstance.AddModuleMessage("Upload Failed. " + ex.Message, MessageType.Error);
AddModuleMessage("Upload Failed. " + ex.Message, MessageType.Error);
}
}
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);
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
{
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
@ -82,7 +82,7 @@
}
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, ""))
{
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;
StateHasChanged();
}
else
{
ModuleInstance.AddModuleMessage("Module Upload Failed.", MessageType.Error);
AddModuleMessage("Module Upload Failed.", MessageType.Error);
}
}
catch (Exception ex)
{
ModuleInstance.AddModuleMessage("Module Upload Failed. " + ex.Message, MessageType.Error);
AddModuleMessage("Module Upload Failed. " + ex.Message, MessageType.Error);
}
}
else
{
ModuleInstance.AddModuleMessage("Invalid Module Package", MessageType.Error);
AddModuleMessage("Invalid Module Package", MessageType.Error);
}
}
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)
{
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;
StateHasChanged();
}

View File

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

View File

@ -35,7 +35,7 @@
}
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)
{
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
AddModuleMessage(ex.Message, MessageType.Error);
}
}
@ -194,7 +194,7 @@
}
catch (Exception ex)
{
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
AddModuleMessage(ex.Message, MessageType.Error);
}
}
@ -273,7 +273,7 @@
}
catch (Exception ex)
{
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
AddModuleMessage(ex.Message, MessageType.Error);
}
}

View File

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

View File

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

View File

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

View File

@ -39,17 +39,25 @@
user.DisplayName = Username;
user.Email = Email;
user.Password = Password;
await UserService.AddUserAsync(user);
NavigationManager.NavigateTo(NavigateUrl(""));
user = await UserService.AddUserAsync(user);
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
{
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)
{
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
AddModuleMessage(ex.Message, MessageType.Error);
}
}

View File

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

View File

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

View File

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

View File

@ -5,6 +5,7 @@
@inject IAliasService AliasService
@inject ISiteService SiteService
@inject IThemeService ThemeService
@inject IUserService UserService
@if (tenants == null)
{
@ -12,74 +13,93 @@
}
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>
<td>
<label for="Name" class="control-label">Tenant: </label>
<label for="Name" class="control-label">Host Username:</label>
</td>
<td>
<select class="form-control" @bind="@tenantid">
<option value="-1">&lt;Select Tenant&gt;</option>
@foreach (Tenant tenant in tenants)
{
<option value="@tenant.TenantId">@tenant.Name</option>
}
</select>
<input class="form-control" @bind="@username" disabled />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Name: </label>
<label for="Name" class="control-label">Host Password:</label>
</td>
<td>
<input class="form-control" @bind="@name" />
<input type="password" class="form-control" @bind="@password" />
</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>
</table>
}
</table>
<button type="button" class="btn btn-success" @onclick="SaveSite">Save</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
}
@ -97,6 +117,9 @@ else
string logo = "";
string themetype = "";
string layouttype = "";
bool isinitialized = true;
string username = "";
string password = "";
protected override async Task OnInitializedAsync()
{
@ -104,35 +127,103 @@ else
urls = PageState.Alias.Name;
themes = ThemeService.GetThemeTypes(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()
{
if (tenantid != "-1" && name != "" && urls != "" && themetype != "")
{
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);
bool isvalid = true;
urls = urls.Replace("\n", ",");
foreach(string name in urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
if (!isinitialized)
{
Alias alias = new Alias();
alias.Name = name;
alias.TenantId = int.Parse(tenantid);
alias.SiteId = site.SiteId;
await AliasService.AddAliasAsync(alias);
User user = new User();
user.SiteId = PageState.Site.SiteId;
user.Username = username;
user.Password = password;
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
{
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> panelayouts = new Dictionary<string, string>();
Alias Alias;
int siteid;
string name = "";
List<Alias> aliases;
@ -109,9 +110,10 @@ else
{
themes = ThemeService.GetThemeTypes(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"]);
Site site = await SiteService.GetSiteAsync(siteid);
siteid = Alias.SiteId;
Site site = await SiteService.GetSiteAsync(siteid, Alias);
if (site != null)
{
name = site.Name;
@ -135,7 +137,7 @@ else
}
catch (Exception ex)
{
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
AddModuleMessage(ex.Message, MessageType.Error);
}
}
@ -143,12 +145,12 @@ else
{
try
{
await SiteService.DeleteSiteAsync(PageState.Site.SiteId);
await SiteService.DeleteSiteAsync(siteid, Alias);
NavigationManager.NavigateTo(NavigateUrl());
}
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> panelayouts = new Dictionary<string, string>();
Alias Alias;
int siteid;
string name = "";
List<Alias> aliases;
@ -111,9 +112,10 @@ else
{
themes = ThemeService.GetThemeTypes(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"]);
Site site = await SiteService.GetSiteAsync(siteid);
siteid = Alias.SiteId;
Site site = await SiteService.GetSiteAsync(siteid, Alias);
if (site != null)
{
name = site.Name;
@ -137,7 +139,7 @@ else
}
catch (Exception ex)
{
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
AddModuleMessage(ex.Message, MessageType.Error);
}
}
@ -147,7 +149,7 @@ else
{
if (name != "" && urls != "" && themetype != "")
{
Site site = await SiteService.GetSiteAsync(siteid);
Site site = await SiteService.GetSiteAsync(siteid, Alias);
if (site != null)
{
site.Name = name;
@ -156,7 +158,7 @@ else
site.DefaultLayoutType = (layouttype == null ? "" : layouttype);
site.IsDeleted = (isdeleted == null ? true : Boolean.Parse(isdeleted));
site = await SiteService.UpdateSiteAsync(site);
site = await SiteService.UpdateSiteAsync(site, Alias);
urls = urls.Replace("\n", ",");
string[] names = urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
@ -184,12 +186,12 @@ 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)
{
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
AddModuleMessage(ex.Message, MessageType.Error);
}
}
}

View File

@ -1,7 +1,7 @@
@namespace Oqtane.Modules.Admin.Sites
@inherits ModuleBase
@inject ISiteService SiteService
@inject NavigationManager NavigationManager
@inject IAliasService AliasService
@if (sites == null)
{
@ -18,9 +18,9 @@ else
<th>&nbsp;</th>
</Header>
<Row>
<td>@context.Name</td>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.SiteId.ToString())" /></td>
<td><ActionLink Action="Delete" Parameters="@($"id=" + context.SiteId.ToString())" Class="btn btn-danger" /></td>
<td><a href="@(scheme + context.Name)">@context.Name</a></td>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.AliasId.ToString())" /></td>
<td><ActionLink Action="Delete" Parameters="@($"id=" + context.AliasId.ToString())" Class="btn btn-danger" /></td>
</Row>
</Pager>
}
@ -28,10 +28,21 @@ else
@code {
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()
{
ShowProgressIndicator();
connectionstring = connectionstring.Replace("\\\\", "\\");
GenericResponse response = await InstallationService.Install(connectionstring);
if (response.Success)
@ -50,13 +52,14 @@
tenant.Name = name;
tenant.DBConnectionString = connectionstring;
tenant.DBSchema = schema;
tenant.IsInitialized = false;
await TenantService.AddTenantAsync(tenant);
NavigationManager.NavigateTo(NavigateUrl());
}
else
{
ModuleInstance.AddModuleMessage(response.Message, MessageType.Error);
AddModuleMessage(response.Message, MessageType.Error);
}
}
}

View File

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

View File

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

View File

@ -75,28 +75,28 @@
{
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;
StateHasChanged();
}
else
{
ModuleInstance.AddModuleMessage("Theme Upload Failed.", MessageType.Error);
AddModuleMessage("Theme Upload Failed.", MessageType.Error);
}
}
catch (Exception ex)
{
ModuleInstance.AddModuleMessage("Theme Upload Failed. " + ex.Message, MessageType.Error);
AddModuleMessage("Theme Upload Failed. " + ex.Message, MessageType.Error);
}
}
else
{
ModuleInstance.AddModuleMessage("Invalid Theme Package", MessageType.Error);
AddModuleMessage("Invalid Theme Package", MessageType.Error);
}
}
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)
{
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;
StateHasChanged();
}

View File

@ -49,7 +49,7 @@ else
}
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, ""))
{
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;
StateHasChanged();
}
else
{
ModuleInstance.AddModuleMessage("Framework Upload Failed.", MessageType.Error);
AddModuleMessage("Framework Upload Failed.", MessageType.Error);
}
}
catch (Exception ex)
{
ModuleInstance.AddModuleMessage("Framework Upload Failed. " + ex.Message, MessageType.Error);
AddModuleMessage("Framework Upload Failed. " + ex.Message, MessageType.Error);
}
}
else
{
ModuleInstance.AddModuleMessage("Invalid Framework Package", MessageType.Error);
AddModuleMessage("Invalid Framework Package", MessageType.Error);
}
}
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)
{
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
AddModuleMessage(ex.Message, MessageType.Error);
}
}
@ -111,12 +111,12 @@
}
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)
{
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
AddModuleMessage(ex.Message, MessageType.Error);
}
}

View File

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

View File

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

View File

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

View File

@ -28,7 +28,7 @@
}
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 + "/";
}
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()
{
return NavigateUrl(PageState.Page.Path);
@ -106,5 +96,20 @@ namespace Oqtane.Modules
{
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
{
Task<List<Site>> GetSitesAsync();
Task<List<Site>> GetSitesAsync(Alias Alias);
Task<Site> GetSiteAsync(int SiteId);
Task<Site> GetSiteAsync(int SiteId, Alias Alias);
Task<Site> AddSiteAsync(Site Site);
Task<Site> AddSiteAsync(Site Site, Alias Alias);
Task<Site> UpdateSiteAsync(Site Site);
Task<Site> UpdateSiteAsync(Site Site, Alias Alias);
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, Alias alias);
Task<User> UpdateUserAsync(User User);
Task DeleteUserAsync(int UserId);

View File

@ -10,11 +10,13 @@ namespace Oqtane.Services
public static string CreateApiUrl(Alias alias, string absoluteUri, string serviceName)
{
string apiurl = "";
Uri uri = new Uri(absoluteUri);
string apiurl;
if (alias != null)
{
// 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 == "")
{
apiurl += "~/";
@ -23,7 +25,6 @@ namespace Oqtane.Services
else
{
// build a url which ignores any subfolder for multi-tenancy
Uri uri = new Uri(absoluteUri);
apiurl = uri.Scheme + "://" + uri.Authority + "/~/";
}
apiurl += "api/" + serviceName;

View File

@ -31,25 +31,47 @@ namespace Oqtane.Services
List<Site> sites = await http.GetJsonAsync<List<Site>>(apiurl);
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)
{
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)
{
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)
{
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)
{
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)
{
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 />
@((MarkupString)@Message)
</div>
<div class="loading" style="@LoadingDisplay"></div>
<div class="app-progress-indicator" style="@LoadingDisplay"></div>
</div>
</div>
@ -177,7 +177,7 @@
site.TenantId = tenants.FirstOrDefault().TenantId;
site.Name = "Default Site";
site.Logo = "oqtane.png";
site.DefaultThemeType = "Oqtane.Themes.Theme2.Theme2, Oqtane.Client";
site.DefaultThemeType = Constants.DefaultTheme;
site.DefaultLayoutType = "";
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
{
jsRuntime.InvokeAsync<string>(
"interop.addCSS",
"interop.includeCSS",
id, url);
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)
{
try

View File

@ -1,9 +1,14 @@
@namespace Oqtane.Shared
<ModuleMessage Message="@message" Type="MessageType.Error" />
<CascadingValue Value="this">
<ModuleMessage @ref="modulemessage" />
@DynamicComponent
</CascadingValue>
@if (progressindicator)
{
<div class="app-progress-indicator"></div>
}
@code {
[CascadingParameter]
@ -13,16 +18,19 @@
private Module ModuleState { get; set; }
private ModuleMessage modulemessage { get; set; }
string message;
RenderFragment DynamicComponent { get; set; }
bool progressindicator = false;
protected override void OnParametersSet()
{
DynamicComponent = builder =>
{
string typename = ModuleState.ModuleType;
// check for core module actions component
if (Constants.DefaultModuleActions.Contains(PageState.Control))
if (Constants.DefaultModuleActions.Contains(PageState.Control))
{
typename = Constants.DefaultModuleActionsTemplate.Replace("{Control}", PageState.Control);
}
@ -40,13 +48,26 @@
else
{
// 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)
{
progressindicator = false;
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)
{
paneadminborder = "pane-admin-border";
panetitle = "<div class=\"pane-admin-title\">" + Name + " Pane</div>";
paneadminborder = "app-pane-admin-border";
panetitle = "<div class=\"app-pane-admin-title\">" + Name + " Pane</div>";
}
else
{
@ -87,7 +87,7 @@
{
module.Title = module.ControlTitle;
}
builder.OpenComponent(0, Type.GetType(Constants.DefaultContainer));
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
builder.AddAttribute(1, "Module", module);
builder.CloseComponent();
}
@ -109,7 +109,7 @@
// check if user is authorized to view module
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.CloseComponent();
}
@ -122,7 +122,7 @@
// check if user is authorized to view module
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.SetKey(module.PageModuleId);
builder.CloseComponent();

View File

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

View File

@ -38,7 +38,7 @@
{
if (PageState != null)
{
builder.OpenComponent(0, Type.GetType(Constants.DefaultPage));
builder.OpenComponent(0, Type.GetType(Constants.PageComponent));
builder.CloseComponent();
}
};
@ -343,7 +343,7 @@
// get IModuleControl properties
typename = module.ModuleType;
// check for core module actions component
if (Constants.DefaultModuleActions.Contains(control))
if (Constants.DefaultModuleActions.Contains(control))
{
typename = Constants.DefaultModuleActionsTemplate.Replace("{Control}", control);
}
@ -407,7 +407,6 @@
// use first alias if Uri does not exist
alias = aliases.FirstOrDefault();
}
alias.Scheme = uri.Scheme;
return alias;
}

View File

@ -20,19 +20,11 @@
}
else
{
// theme does not exist with type specified
builder.OpenComponent(0, Type.GetType(Constants.ModuleMessageControl));
// theme does not exist with type specified
builder.OpenComponent(0, Type.GetType(Constants.ModuleMessageControl));
builder.AddAttribute(1, "Message", "Error Loading Page Theme " + PageState.Page.ThemeType);
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 "";
}
}
public static string CreateIdFromUrl(string value)
{
return value.Replace("/", "_").Replace("\\", "_").Replace(".", "_");
}
}
}

View File

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

View File

@ -1,4 +1,4 @@
@namespace Oqtane.Themes.Theme2
@namespace Oqtane.Themes.BlazorTheme
@inherits ThemeBase
<div class="sidebar">
@ -8,7 +8,7 @@
<div class="main">
<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 class="container">
<div class="row px-4">
@ -24,6 +24,11 @@
</div>
@code {
public override string Name { get { return "Theme2"; } }
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;
namespace Oqtane.Themes.Theme2
namespace Oqtane.Themes.BlazorTheme
{
public class Theme : ITheme
{
@ -10,7 +10,7 @@ namespace Oqtane.Themes.Theme2
{
Dictionary<string, string> properties = new Dictionary<string, string>
{
{ "Name", "Theme2" },
{ "Name", "Blazor Theme" },
{ "Version", "1.0.0" }
};
return properties;

View File

@ -33,16 +33,6 @@ namespace Oqtane.Themes
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()
{
return NavigateUrl(PageState.Page.Path);

View File

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

View File

@ -1,5 +1,6 @@
@namespace Oqtane.Themes.Controls
@inherits ThemeControlBase
@inject NavigationManager NavigationManager
@((MarkupString)logo)
@ -10,7 +11,8 @@
{
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))
{
<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">
@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
{
string Name { get; }
string Panes { get; } // if a theme has different panes, delimit them with ";"
string Panes { get; } // identifies all panes in a theme ( delimited by ";" ) - assumed to be a layout if no panes specified
}
}

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
<div class="container">
<div class="row px-4">

View File

@ -1,4 +1,4 @@
@namespace Oqtane.Themes.Theme1
@namespace Oqtane.Themes.OqtaneTheme
@inherits ThemeBase
<div class="sidebar">
@ -8,16 +8,14 @@
<div class="main">
<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 class="container">
<div class="row px-4">
<div class="col-sm">
<Pane Name="Left" />
</div>
<div class="col-sm">
<Pane Name="Right" />
</div>
<Pane Name="Top" />
</div>
<div class="row px-4">
<Pane Name="Bottom" />
</div>
<div class="row px-4">
<Pane Name="Admin" />
@ -26,6 +24,10 @@
</div>
@code {
public override string Name { get { return "Theme1"; } }
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
@inherits ThemeBase
@namespace Oqtane.Themes.OqtaneTheme
@inherits LayoutBase
<div class="row px-4">
<div class="col-sm">
@ -11,6 +11,5 @@
</div>
@code {
public override string Name { get { return "Horizontal Layout"; } }
public override string Panes { get { return "Left;Right"; } }
}

View File

@ -1,4 +1,4 @@
@namespace Oqtane.Themes.Theme3
@namespace Oqtane.Themes.OqtaneTheme
@inherits ThemeBase
<div class="sidebar">
@ -8,7 +8,7 @@
<div class="main">
<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 class="container">
<PaneLayout />
@ -19,6 +19,8 @@
</div>
@code {
public override string Name { get { return "Theme3"; } }
public override string Panes { get { return ""; } }
protected override async Task OnParametersSetAsync()
{
await IncludeCSS("Theme.css");
}
}

View File

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

View File

@ -1,5 +1,5 @@
@namespace Oqtane.Themes.Theme3
@inherits ThemeBase
@namespace Oqtane.Themes.OqtaneTheme
@inherits LayoutBase
<div class="row px-4">
<Pane Name="Top" />
@ -9,6 +9,5 @@
</div>
@code {
public override string Name { get { return "Vertical Layout"; } }
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]
protected PageState PageState { get; set; }
public virtual string Name { get; set; }
public virtual string Panes { get; set; }
public string ThemePath()
@ -20,14 +19,14 @@ namespace Oqtane.Themes
return "Themes/" + this.GetType().Namespace + "/";
}
public async Task AddCSS(string Url)
public async Task IncludeCSS(string Url)
{
if (!Url.StartsWith("http"))
{
Url = ThemePath() + Url;
}
var interop = new Interop(JSRuntime);
await interop.AddCSS("Theme:" + Utilities.CreateIdFromUrl(Url), Url);
await interop.IncludeCSS("Theme", Url);
}
public string NavigateUrl()

View File

@ -10,144 +10,8 @@ app {
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 & width depends on how you want to reveal the overlay (see JS below) */
.app-controlpanel {
height: 100%;
width: 0;
position: fixed; /* Stay in place */
@ -161,7 +25,7 @@ app {
}
/* Position the content inside the overlay */
.overlay-content {
.app-controlpanel-content {
position: relative;
top: 5%; /* 5% from the top */
width: 100%; /* 100% width */
@ -170,7 +34,7 @@ app {
}
/* Position the close button (top right corner) */
.overlay .closebtn {
.app-controlpanel .closebtn {
position: absolute;
top: 20px;
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 */
@media screen and (max-height: 450px) {
.overlay a {
.app-controlpanel a {
font-size: 20px
}
.overlay .closebtn {
.app-controlpanel-close {
font-size: 40px;
top: 15px;
right: 35px;
@ -191,7 +55,7 @@ app {
}
/* Admin Modal */
.modal {
.app-admin-modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 9999; /* Sit on top */
@ -204,7 +68,7 @@ app {
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
.modal-content {
.app-admin-modal-content {
background-color: #fefefe;
margin: 5% auto; /* 5% from the top and centered */
padding: 20px;
@ -212,22 +76,22 @@ app {
width: 80%; /* Could be more or less, depending on screen size */
}
.close {
.app-admin-modal-close {
position: absolute;
top: 20px;
right: 45px;
font-size: 40px;
}
.close:hover,
.close:focus {
.app-admin-modal-close:hover,
.app-admin-modal-close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
}
/* Action Menu */
.dropdown-toggle {
.app-actions-toggle {
background-color: transparent;
border-color: #fff;
border-style: hidden;
@ -236,20 +100,20 @@ app {
border-left: none;
}
.pane-admin-border {
.app-pane-admin-border {
width: 100%;
border-width: 1px;
border-style: dashed;
border-color: gray;
}
.pane-admin-title {
.app-pane-admin-title {
width: 100%;
text-align: center;
color: gray;
}
.loading {
.app-progress-indicator {
background: rgba(0,0,0,0.2) url('../loading.gif') no-repeat 50% 50%;
width: 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>
<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 href="css/site.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
</head>
<body>
<app>

View File

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

View File

@ -210,6 +210,19 @@ namespace Oqtane.Controllers
}
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()
.Where(item => item.FullName.Contains(".Module.")).ToArray();
@ -283,6 +296,7 @@ namespace Oqtane.Controllers
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer(_connectionString);
public virtual DbSet<ApplicationVersion> ApplicationVersion { get; set; }
public virtual DbSet<Tenant> Tenant { get; set; }
}
}

View File

@ -11,7 +11,7 @@
<title>Oqtane</title>
<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 href="css/site.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
</head>
<body>
@(Html.AntiForgeryToken())

View File

@ -19,7 +19,7 @@ namespace Oqtane.Repository
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
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> {
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>" +
"<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>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>" +
"<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>" +
@ -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> {
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> {
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> {
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> {
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> {
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> {
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> {
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> {
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> {
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> {
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> {
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> {
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> {
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;
string path = accessor.HttpContext.Request.Path.Value;
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("/"))
{

View File

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

View File

@ -24,6 +24,7 @@ CREATE TABLE [dbo].[Tenant](
[Name] [nvarchar](100) NOT NULL,
[DBConnectionString] [nvarchar](1024) NOT NULL,
[DBSchema] [nvarchar](50) NOT NULL,
[IsInitialized] [bit] NOT NULL,
[CreatedBy] [nvarchar](256) NOT NULL,
[CreatedOn] [datetime] NOT NULL,
[ModifiedBy] [nvarchar](256) NOT NULL,
@ -49,6 +50,17 @@ CREATE TABLE [dbo].[ModuleDefinition](
)
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
@ -66,8 +78,8 @@ Create seed data
*/
SET IDENTITY_INSERT [dbo].[Tenant] ON
GO
INSERT [dbo].[Tenant] ([TenantId], [Name], [DBConnectionString], [DBSchema], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn])
VALUES (1, N'Tenant1', N'{ConnectionString}', N'', '', getdate(), '', getdate())
INSERT [dbo].[Tenant] ([TenantId], [Name], [DBConnectionString], [DBSchema], [IsInitialized], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn])
VALUES (1, N'Master', N'{ConnectionString}', N'', 1, '', getdate(), '', getdate())
GO
SET IDENTITY_INSERT [dbo].[Tenant] OFF
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 "";
}
},
addCSS: function (id, url) {
if (document.getElementById(id) === null) {
var link = document.createElement("link");
includeCSS: function (id, url) {
var link = document.getElementById('yourid');
if (link === null) {
link = document.createElement("link");
link.id = id;
link.type = "text/css";
link.rel = "stylesheet";
link.href = url;
document.head.appendChild(link);
}
},
removeCSS: function (pattern) {
var links = document.getElementsByTagName("link");
for (var i = 0; i < links.length; i++) {
if (links[i].id.includes(pattern)) {
document.head.removeChild(links[i]);
else {
if (link.href !== url) {
link.setAttribute('href', url);
}
}
},

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 */
function openActions() {
document.getElementById("actions").style.width = "25%";

View File

@ -15,33 +15,6 @@ namespace Oqtane.Models
public string ModifiedBy { 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]
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 DBConnectionString { get; set; }
public string DBSchema { get; set; }
public bool IsInitialized { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }

View File

@ -5,25 +5,24 @@
public const string PackageId = "Oqtane.Framework";
public const string Version = "0.0.1";
public const string DefaultPage = "Oqtane.Shared.ThemeBuilder, Oqtane.Client";
public const string DefaultContainer = "Oqtane.Shared.ContainerBuilder, Oqtane.Client";
public const string PageComponent = "Oqtane.Shared.ThemeBuilder, 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 static readonly string[] DefaultModuleActions = new[] { "Settings", "Import", "Export" };
public const string DefaultModuleActionsTemplate = "Oqtane.Modules.Admin.Modules.{Control}, 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 DefaultControl = "Index";
public const string DefaultControl = "Index";
public const string AdminPane = "Admin";
public const string AllUsersRole = "All Users";
public const string HostRole = "Host Users";
public const string AdminRole = "Administrators";
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;
}
}