Merge pull request #1790 from oqtane/dev

version 3.0.0 release
This commit is contained in:
Shaun Walker 2021-11-11 10:13:00 -05:00 committed by GitHub
commit 7e699136d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
111 changed files with 1069 additions and 789 deletions

View File

@ -62,21 +62,10 @@
_initialized = true;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
if (string.IsNullOrEmpty(AntiForgeryToken))
{
// parameter values are not set when running on WebAssembly (seems to be a .NET 5 bug) - need to retrieve using JSInterop
var interop = new Interop(JSRuntime);
SiteState.AntiForgeryToken = await interop.GetElementByName(Constants.RequestVerificationToken);
InstallationService.SetAntiForgeryTokenHeader(SiteState.AntiForgeryToken);
Runtime = await interop.GetElementByName("app_runtime");
RenderMode = await interop.GetElementByName("app_rendermode");
}
_display = "";
StateHasChanged();
}

View File

@ -24,7 +24,7 @@
if (!String.IsNullOrEmpty(_server) && !String.IsNullOrEmpty(_database))
{
connectionString = $"Data Source={_server};AttachDbFilename=|DataDirectory|\\{_database}.mdf;Initial Catalog={_database};Integrated Security=SSPI;";
connectionString = $"Data Source={_server};AttachDbFilename=|DataDirectory|\\{_database}.mdf;Initial Catalog={_database};Integrated Security=SSPI;Encrypt=false;";
}
return connectionString;

View File

@ -1,6 +1,7 @@
@namespace Oqtane.Installer.Controls
@implements Oqtane.Interfaces.IDatabaseConfigControl
@inject IStringLocalizer<SqlServerConfig> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="server" HelpText="Enter the database server" ResourceKey="Server">Server:</Label>
@ -38,6 +39,27 @@
</div>
</div>
}
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="encryption" HelpText="Specify if you are using an encrypted database connection. It is highly recommended to use encryption in a production environment." ResourceKey="Encryption">Encryption:</Label>
<div class="col-sm-9">
<select id="encryption" class="form-select custom-select" @bind="@_encryption">
<option value="true">@SharedLocalizer["True"]</option>
<option value="false">@SharedLocalizer["False"]</option>
</select>
</div>
</div>
@if (_encryption == "true")
{
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="trustservercertificate" HelpText="Specify the type of certificate you are using for encryption" ResourceKey="TrustServerCertificate">Certificate:</Label>
<div class="col-sm-9">
<select id="encryption" class="form-select custom-select" @bind="@_trustservercertificate">
<option value="true">@Localizer["Self Signed"]</option>
<option value="false">@Localizer["Verifiable"]</option>
</select>
</div>
</div>
}
@code {
private string _server = String.Empty;
@ -45,6 +67,8 @@
private string _security = "integrated";
private string _uid = String.Empty;
private string _pwd = String.Empty;
private string _encryption = "false";
private string _trustservercertificate = "false";
public string GetConnectionString()
{
@ -60,16 +84,11 @@
connectionString += "Integrated Security=SSPI;";
}
else
{
if (!String.IsNullOrEmpty(_uid) && !String.IsNullOrEmpty(_pwd))
{
connectionString += $"User ID={_uid};Password={_pwd};";
}
else
{
connectionString = String.Empty;
}
}
connectionString += $"Encrypt={_encryption};";
connectionString += $"TrustServerCertificate={_trustservercertificate};";
return connectionString;
}

View File

@ -24,10 +24,10 @@
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="databasetype" HelpText="Select the type of database you wish to use" ResourceKey="DatabaseType">Database:</Label>
<div class="col-sm-9">
<select id="databasetype" class="form-select custom-select" value="@_databaseName" @onchange="(e => DatabaseChanged(e))">
@if (_databases != null)
{
foreach (var database in _databases)
<select id="databasetype" class="form-select custom-select" value="@_databaseName" @onchange="(e => DatabaseChanged(e))">
@foreach (var database in _databases)
{
if (database.IsDefault)
{
@ -38,8 +38,8 @@
<option value="@database.Name">@Localizer[@database.Name]</option>
}
}
}
</select>
}
</div>
</div>
@{
@ -97,7 +97,7 @@
@code {
private List<Database> _databases;
private string _databaseName = "LocalDB";
private string _databaseName;
private Type _databaseConfigType;
private object _databaseConfig;
private RenderFragment DatabaseConfigComponent { get; set; }
@ -113,6 +113,14 @@
protected override async Task OnInitializedAsync()
{
_databases = await DatabaseService.GetDatabasesAsync();
if (_databases.Exists(item => item.IsDefault))
{
_databaseName = _databases.Find(item => item.IsDefault).Name;
}
else
{
_databaseName = "LocalDB";
}
LoadDatabaseConfigComponent();
}
@ -150,8 +158,8 @@
if (firstRender)
{
var interop = new Interop(JSRuntime);
await interop.IncludeLink("", "stylesheet", "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css", "text/css", "sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC", "anonymous", "");
await interop.IncludeScript("", "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js", "sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM", "anonymous", "", "head", "");
await interop.IncludeLink("", "stylesheet", "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css", "text/css", "sha512-usVBAd66/NpVNfBge19gws2j6JZinnca12rAe2l+d+QkLU9fiG02O1X8Q6hepIpr/EYKZvKx/I9WsnujJuOmBA==", "anonymous", "");
await interop.IncludeScript("", "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/js/bootstrap.min.js", "sha512-a6ctI6w1kg3J4dSjknHj3aWLEbjitAXAjLDRUxo2wyYmDFRcz2RJuQr5M3Kt8O/TtUSp8n2rAyaXYy1sjoKmrQ==", "anonymous", "", "head", "");
}
}

View File

@ -13,7 +13,7 @@
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="upload" HelpText="Upload the file you want" ResourceKey="Upload">Upload: </Label>
<div class="col-sm-9">
<FileManager UploadMultiple="true" ShowFiles="false" FolderId="@_folderId" />
<FileManager UploadMultiple="true" ShowFiles="false" FolderId="@_folderId" ShowSuccess="true" />
</div>
</div>
</div>

View File

@ -115,7 +115,7 @@ else
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" HelpText="Upload one or more translations. Once they are uploaded click Install to complete the installation." ResourceKey="Module">Language: </Label>
<div class="col-sm-9">
<FileManager Filter="nupkg" ShowFiles="true" Folder="Packages" UploadMultiple="true" />
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" />
</div>
</div>
</div>
@ -317,7 +317,7 @@ else
{
try
{
await PackageService.DownloadPackageAsync(_packageid, _version, "Packages");
await PackageService.DownloadPackageAsync(_packageid, _version, Constants.PackagesFolder);
await logger.LogInformation("Language Package {Name} {Version} Downloaded Successfully", _packageid, _version);
AddModuleMessage(Localizer["Success.Language.Download"], MessageType.Success);
StateHasChanged();

View File

@ -97,7 +97,7 @@ else
{
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
await PackageService.DownloadPackageAsync(Constants.PackageId + ".Client." + code, Constants.Version, "Packages");
await PackageService.DownloadPackageAsync(Constants.PackageId + ".Client." + code, Constants.Version, Constants.PackagesFolder);
await logger.LogInformation("Translation Downloaded {Code} {Version}", code, Constants.Version);
await PackageService.InstallPackagesAsync();
AddModuleMessage(string.Format(Localizer["Success.Language.Install"], NavigateUrl("admin/system")), MessageType.Success);

View File

@ -16,7 +16,7 @@
<text>...</text>
</Authorizing>
<Authorized>
<ModuleMessage Message="@Localizer["Info.SignedIn"]" Type="MessageType.Info" />
<div>@Localizer["Info.SignedIn"]</div>
</Authorized>
<NotAuthorized>
<form @ref="login" class="@(validated ? "was-validated" : "needs-validation")" novalidate>

View File

@ -67,13 +67,12 @@
</div>
}
</div>
</form>
<button type="button" class="btn btn-success" @onclick="CreateModule">@Localizer["Module.Create"]</button>
}
else
{
<button type="button" class="btn btn-success" @onclick="ActivateModule">@Localizer["Module.Activate"]</button>
</form>
}
@code {
@ -92,14 +91,9 @@
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
protected override async Task OnParametersSetAsync()
{
try
protected override void OnInitialized()
{
_moduledefinitionname = SettingService.GetSetting(ModuleState.Settings, "ModuleDefinitionName", "");
_templates = await ModuleDefinitionService.GetModuleDefinitionTemplatesAsync();
_versions = Constants.ReleaseVersions.Split(',').Where(item => Version.Parse(item).CompareTo(Version.Parse("2.0.0")) >= 0).ToArray();
if (string.IsNullOrEmpty(_moduledefinitionname))
{
AddModuleMessage(Localizer["Info.Module.Creator"], MessageType.Info);
@ -109,6 +103,14 @@
AddModuleMessage(Localizer["Info.Module.Activate"], MessageType.Info);
}
}
protected override async Task OnParametersSetAsync()
{
try
{
_templates = await ModuleDefinitionService.GetModuleDefinitionTemplatesAsync();
_versions = Constants.ReleaseVersions.Split(',').Where(item => Version.Parse(item).CompareTo(Version.Parse("2.0.0")) >= 0).ToArray();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Module Creator");
@ -131,7 +133,6 @@
await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId);
GetLocation();
AddModuleMessage(string.Format(Localizer["Success.Module.Create"], NavigateUrl("admin/system")), MessageType.Success);
}
catch (Exception ex)

View File

@ -70,7 +70,7 @@
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" HelpText="Upload one or more module packages. Once they are uploaded click Install to complete the installation." ResourceKey="Module">Module: </Label>
<div class="col-sm-9">
<FileManager Filter="nupkg" ShowFiles="false" Folder="Packages" UploadMultiple="true" />
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" />
</div>
</div>
</div>
@ -229,7 +229,7 @@
{
try
{
await PackageService.DownloadPackageAsync(_packageid, _version, "Packages");
await PackageService.DownloadPackageAsync(_packageid, _version, Constants.PackagesFolder);
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _version);
AddModuleMessage(Localizer["Success.Module.Download"], MessageType.Success);
_productname = "";

View File

@ -87,13 +87,17 @@
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
protected override void OnInitialized()
{
AddModuleMessage(Localizer["Info.Module.Development"], MessageType.Info);
}
protected override async Task OnParametersSetAsync()
{
try
{
_templates = await ModuleDefinitionService.GetModuleDefinitionTemplatesAsync();
_versions = Constants.ReleaseVersions.Split(',').Where(item => Version.Parse(item).CompareTo(Version.Parse("2.0.0")) >= 0).ToArray();
AddModuleMessage(Localizer["Info.Module.Development"], MessageType.Info);
}
catch (Exception ex)
{

View File

@ -111,7 +111,7 @@ else
{
try
{
await PackageService.DownloadPackageAsync(packagename, version, "Packages");
await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder);
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version);
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success);

View File

@ -74,7 +74,7 @@
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="path" HelpText="Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used." ResourceKey="UrlPath">Url Path: </Label>
<Label Class="col-sm-3" For="path" HelpText="Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used. If the page is intended to be the root path specify '/'." ResourceKey="UrlPath">Url Path: </Label>
<div class="col-sm-9">
<input id="path" class="form-control" @bind="@_path" />
</div>
@ -293,11 +293,11 @@
page.SiteId = PageState.Page.SiteId;
page.Name = _name;
page.Title = _title;
if (string.IsNullOrEmpty(_path))
{
_path = _name;
}
if (_path.Contains("/"))
{
_path = _path.Substring(_path.LastIndexOf("/") + 1);

View File

@ -81,7 +81,7 @@
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="path" HelpText="Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used." ResourceKey="UrlPath">Url Path: </Label>
<Label Class="col-sm-3" For="path" HelpText="Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used. If the page is intended to be the root path specify '/'." ResourceKey="UrlPath">Url Path: </Label>
<div class="col-sm-9">
<input id="path" class="form-control" @bind="@_path" maxlength="256"/>
</div>
@ -225,10 +225,17 @@
_title = page.Title;
_path = page.Path;
if (string.IsNullOrEmpty(_path))
{
_path = "/";
}
else
{
if (_path.Contains("/"))
{
_path = _path.Substring(_path.LastIndexOf("/") + 1);
}
}
if (page.ParentId == null)
{
@ -370,7 +377,8 @@
page.Name = _name;
page.Title = _title;
if (string.IsNullOrEmpty(_path) && _name.ToLower() != "home")
if (string.IsNullOrEmpty(_path))
{
_path = _name;
}
@ -378,6 +386,7 @@
{
_path = _path.Substring(_path.LastIndexOf("/") + 1);
}
if (_parentid == "-1")
{
page.ParentId = null;

View File

@ -18,6 +18,7 @@
<Row>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.PageId.ToString())" ResourceKey="EditPage" /></td>
<td><ActionDialog Header="Delete Page" Message="@string.Format(Localizer["Confirm.Page.Delete"], context.Name)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeletePage(context))" ResourceKey="DeletePage" /></td>
<td><button type="button" class="btn btn-secondary" @onclick="@(async () => NavigationManager.NavigateTo(Browse(context)))">@Localizer["Browse"]</button></td>
<td>@(new string('-', context.Level * 2))@(context.Name)</td>
</Row>
</Pager>
@ -42,4 +43,8 @@
AddModuleMessage(Localizer["Error.Page.Delete"], MessageType.Error);
}
}
protected string Browse(Page page)
{
return string.IsNullOrEmpty(page.Url) ? NavigateUrl(page.Path) : page.Url;
}
}

View File

@ -35,13 +35,13 @@ else
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="effectiveDate" HelpText="The date that this role assignment is active" ResourceKey="EffectiveDate">Effective Date: </Label>
<div class="col-sm-9">
<input type="date" id="effectiveDate" class="form-control" @bind="@effectivedate" required />
<input type="date" id="effectiveDate" class="form-control" @bind="@effectivedate" />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="expiryDate" HelpText="The date that this role assignment expires" ResourceKey="ExpiryDate">Expiry Date: </Label>
<div class="col-sm-9">
<input type="date" id="expiryDate" class="form-control" @bind="@expirydate" required />
<input type="date" id="expiryDate" class="form-control" @bind="@expirydate" />
</div>
</div>
<br /><br />

View File

@ -104,7 +104,6 @@
</select>
</div>
</div>
</div>
</Section>
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
@ -157,10 +156,7 @@
</div>
<button type="button" class="btn btn-secondary" @onclick="SendEmail">@Localizer["Smtp.TestConfig"]</button>
<br /><br />
</div>
</Section>
<Section Name="PWA" Heading="Progressive Web Application Settings" ResourceKey="PWASettings">
<div class="container">
@ -189,6 +185,28 @@
</Section>
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
<Section Name="Hosting" Heading="Hosting Model" ResourceKey="Hosting">
<div class="container">
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="runtime" HelpText="The Blazor runtime hosting model" ResourceKey="Runtime">Runtime: </Label>
<div class="col-sm-9">
<select id="runtime" class="form-select" @bind="@_runtime" required>
<option value="Server">@SharedLocalizer["BlazorServer"]</option>
<option value="WebAssembly">@SharedLocalizer["BlazorWebAssembly"]</option>
</select>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="prerender" HelpText="Specifies if the site should be prerendered (for search crawlers, etc...)" ResourceKey="Prerender">Prerender? </Label>
<div class="col-sm-9">
<select id="prerender" class="form-select" @bind="@_prerender" required>
<option value="Prerendered">@SharedLocalizer["Yes"]</option>
<option value="">@SharedLocalizer["No"]</option>
</select>
</div>
</div>
</div>
</Section>
<Section Name="TenantInformation" Heading="Tenant Information" ResourceKey="TenantInformation">
<div class="container">
<div class="row mb-1 align-items-center">
@ -231,6 +249,8 @@
private string _name = string.Empty;
private List<Alias> _aliasList;
private string _urls = string.Empty;
private string _runtime = "";
private string _prerender = "";
private int _logofileid = -1;
private FileManager _logofilemanager;
private int _faviconfileid = -1;
@ -272,6 +292,8 @@
if (site != null)
{
_name = site.Name;
_runtime = site.Runtime;
_prerender = site.RenderMode.Replace(_runtime, "");
_allowregistration = site.AllowRegistration.ToString();
_isdeleted = site.IsDeleted.ToString();
@ -413,9 +435,20 @@
var site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
if (site != null)
{
bool reload = false;
bool refresh = (site.DefaultThemeType != _themetype || site.DefaultContainerType != _containertype);
site.Name = _name;
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
if (site.Runtime != _runtime || site.RenderMode != _runtime + _prerender)
{
site.Runtime = _runtime;
site.RenderMode = _runtime + _prerender;
refresh = true;
reload = true;
}
}
site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration));
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
@ -485,7 +518,7 @@
if (refresh)
{
NavigationManager.NavigateTo(NavigateUrl()); // refresh to show new theme or container
NavigationManager.NavigateTo(NavigateUrl(), reload); // refresh to show new theme or container
}
else
{

View File

@ -82,6 +82,24 @@ else
</select>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="runtime" HelpText="The runtime hosting model" ResourceKey="Runtime">Runtime: </Label>
<div class="col-sm-9">
<select id="runtime" class="form-select" @bind="@_runtime" required>
<option value="Server">@SharedLocalizer["BlazorServer"]</option>
<option value="WebAssembly">@SharedLocalizer["BlazorWebAssembly"]</option>
</select>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="prerender" HelpText="Specifies if the site should be prerendered (for search crawlers, etc...)" ResourceKey="Prerender">Prerender? </Label>
<div class="col-sm-9">
<select id="prerender" class="form-select" @bind="@_prerender" required>
<option value="Prerendered">@SharedLocalizer["Yes"]</option>
<option value="">@SharedLocalizer["No"]</option>
</select>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="tenant" HelpText="Select the tenant for the site" ResourceKey="Tenant">Tenant: </Label>
<div class="col-sm-9">
@ -129,13 +147,13 @@ else
@DatabaseConfigComponent;
}
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="hostUsername" HelpText="Enter the username of the host for this site" ResourceKey="HostUsername">Host Username:</Label>
<Label Class="col-sm-3" For="hostUsername" HelpText="Enter the username of an existing host user" ResourceKey="HostUsername">Host Username:</Label>
<div class="col-sm-9">
<input id="hostUsername" class="form-control" @bind="@_hostUserName" readonly />
<input id="hostUsername" class="form-control" @bind="@_hostusername" required />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="hostPassword" HelpText="Enter the password for the host of this site" ResourceKey="HostPassword">Host Password:</Label>
<Label Class="col-sm-3" For="hostPassword" HelpText="Enter the password of an existing host user" ResourceKey="HostPassword">Host Password:</Label>
<div class="col-sm-9">
<input id="hostPassword" type="password" class="form-control" @bind="@_hostpassword" required />
</div>
@ -168,7 +186,7 @@ else
private string _tenantName = string.Empty;
private string _hostUserName = UserNames.Host;
private string _hostusername = string.Empty;
private string _hostpassword = string.Empty;
private string _name = string.Empty;
@ -177,6 +195,8 @@ else
private string _containertype = "-";
private string _admincontainertype = "";
private string _sitetemplatetype = "-";
private string _runtime = "Server";
private string _prerender = "Prerendered";
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
@ -283,7 +303,7 @@ else
// validate host credentials
var user = new User();
user.SiteId = PageState.Site.SiteId;
user.Username = UserNames.Host;
user.Username = _hostusername;
user.Password = _hostpassword;
user = await UserService.LoginUserAsync(user, false, false);
if (user.IsAuthenticated)
@ -300,8 +320,9 @@ else
config.TenantName = _tenantName;
config.DatabaseType = database.DBType;
config.ConnectionString = connectionString;
config.HostEmail = user.Email;
config.HostUsername = _hostusername;
config.HostPassword = _hostpassword;
config.HostEmail = user.Email;
config.HostName = user.DisplayName;
config.IsNewTenant = true;
}
@ -340,6 +361,8 @@ else
config.DefaultContainer = _containertype;
config.DefaultAdminContainer = _admincontainertype;
config.SiteTemplate = _sitetemplatetype;
config.Runtime = _runtime;
config.RenderMode = _runtime + _prerender;
ShowProgressIndicator();

View File

@ -50,24 +50,6 @@
</TabPanel>
<TabPanel Name="Options" Heading="Options" ResourceKey="Options">
<div class="container">
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="runtime" HelpText="Blazor Runtime (Server or WebAssembly)" ResourceKey="BlazorRuntime">Blazor Runtime: </Label>
<div class="col-sm-9">
<select id="runtime" class="form-select" @bind="@_runtime">
<option value="Server">@Localizer["Server"]</option>
<option value="WebAssembly">@Localizer["WebAssembly"]</option>
</select>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="rendermode" HelpText="Blazor Server Render Mode" ResourceKey="RenderMode">Render Mode: </Label>
<div class="col-sm-9">
<select id="rendermode" class="form-select" @bind="@_rendermode">
<option value="Server">@Localizer["Server"]</option>
<option value="ServerPrerendered">@Localizer["ServerPrerendered"]</option>
</select>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="detailederrors" HelpText="Specify If Detailed Errors Are Enabled For Blazor. This Option Should Not Not Be Enabled In Production." ResourceKey="DetailedErrors">Detailed Errors? </Label>
<div class="col-sm-9">
@ -126,8 +108,6 @@
private string _servertime = string.Empty;
private string _installationid = string.Empty;
private string _runtime = string.Empty;
private string _rendermode = string.Empty;
private string _detailederrors = string.Empty;
private string _logginglevel = string.Empty;
private string _swagger = string.Empty;
@ -146,8 +126,6 @@
_servertime = systeminfo["servertime"];
_installationid = systeminfo["installationid"];
_runtime = systeminfo["runtime"];
_rendermode = systeminfo["rendermode"];
_detailederrors = systeminfo["detailederrors"];
_logginglevel = systeminfo["logginglevel"];
_swagger = systeminfo["swagger"];
@ -160,8 +138,6 @@
try
{
var settings = new Dictionary<string, string>();
settings.Add("runtime", _runtime);
settings.Add("rendermode", _rendermode);
settings.Add("detailederrors", _detailederrors);
settings.Add("logginglevel", _logginglevel);
settings.Add("swagger", _swagger);

View File

@ -70,8 +70,7 @@
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" HelpText="Upload one or more theme packages. Once they are uploaded click Install to complete the installation." ResourceKey="Theme">Theme: </Label>
<div class="col-sm-9">
<FileManager Filter="nupkg" ShowFiles="false" Folder="Packages" UploadMultiple="@true" />
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" />
</div>
</div>
</div>
@ -230,7 +229,7 @@
{
try
{
await PackageService.DownloadPackageAsync(_packageid, _version, "Packages");
await PackageService.DownloadPackageAsync(_packageid, _version, Constants.PackagesFolder);
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _version);
AddModuleMessage(Localizer["Success.Theme.Download"], MessageType.Success);
_productname = "";

View File

@ -51,7 +51,8 @@
</select>
</div>
</div>
@if (!string.IsNullOrEmpty(_location)) {
@if (!string.IsNullOrEmpty(_location))
{
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="location" HelpText="Location where the theme will be created" ResourceKey="Location">Location: </Label>
<div class="col-sm-9">
@ -77,13 +78,17 @@
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
protected override void OnInitialized()
{
AddModuleMessage(Localizer["Info.Theme.CreatorIntent"], MessageType.Info);
}
protected override async Task OnParametersSetAsync()
{
try
{
_templates = await ThemeService.GetThemeTemplatesAsync();
_versions = Constants.ReleaseVersions.Split(',').Where(item => Version.Parse(item).CompareTo(Version.Parse("2.0.0")) >= 0).ToArray();
AddModuleMessage(Localizer["Info.Theme.CreatorIntent"], MessageType.Info);
}
catch (Exception ex)
{

View File

@ -112,7 +112,7 @@ else
{
try
{
await PackageService.DownloadPackageAsync(packagename, version, "Packages");
await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder);
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", packagename, version);
await ThemeService.InstallThemesAsync();
AddModuleMessage(string.Format(Localizer["Success.Theme.Install"], NavigateUrl("admin/system")), MessageType.Success);

View File

@ -26,7 +26,7 @@
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" HelpText="Upload A Framework Package And Then Select Upgrade" ResourceKey="Framework">Framework: </Label>
<div class="col-sm-9">
<FileManager Filter="nupkg" ShowFiles="false" Folder="Packages" />
<FileManager Folder="@Constants.PackagesFolder" />
</div>
</div>
</div>
@ -85,8 +85,8 @@
{
try
{
await PackageService.DownloadPackageAsync(packageid, version, "Packages");
await PackageService.DownloadPackageAsync(Constants.UpdaterPackageId, version, "Packages");
await PackageService.DownloadPackageAsync(packageid, version, Constants.PackagesFolder);
await PackageService.DownloadPackageAsync(Constants.UpdaterPackageId, version, Constants.PackagesFolder);
AddModuleMessage(Localizer["Success.Framework.Download"], MessageType.Success);
}
catch (Exception ex)

View File

@ -35,6 +35,9 @@
[Parameter]
public string Style { get; set; }
[Parameter]
public string DateTimeFormat { get; set; } = "MMM dd yyyy HH:mm:ss";
protected override void OnParametersSet()
{
_text = string.Empty;
@ -49,7 +52,7 @@
if (CreatedOn != null)
{
_text += $" {Localizer["On"]} <b>{CreatedOn.Value.ToString("MMM dd yyyy HH:mm:ss")}</b>";
_text += $" {Localizer["On"]} <b>{CreatedOn.Value.ToString(DateTimeFormat)}</b>";
}
_text += "</p>";
@ -66,7 +69,7 @@
if (ModifiedOn != null)
{
_text += $" {Localizer["on"]} <b>{ModifiedOn.Value.ToString("MMM dd yyyy HH:mm:ss")}</b>";
_text += $" {Localizer["on"]} <b>{ModifiedOn.Value.ToString(DateTimeFormat)}</b>";
}
_text += "</p>";
@ -83,7 +86,7 @@
if (DeletedOn != null)
{
_text += $" {Localizer["On"]} <b>{DeletedOn.Value.ToString("MMM dd yyyy HH:mm:ss")}</b>";
_text += $" {Localizer["On"]} <b>{DeletedOn.Value.ToString(DateTimeFormat)}</b>";
}
_text += "</p>";

View File

@ -10,24 +10,25 @@
<div id="@Id" class="container-fluid px-0">
<div class="row">
<div class="col">
@if (ShowFolders || FolderId <= 0)
<div class="container-fluid px-0">
@if (ShowFolders)
{
<div>
<div class="row">
<div class="col">
<select class="form-select" value="@FolderId" @onchange="(e => FolderChanged(e))">
@if (string.IsNullOrEmpty(Folder))
{
<option value="-1">&lt;@Localizer["Folder.Select"]&gt;</option>
}
@foreach (Folder folder in _folders)
{
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
}
</select>
</div>
</div>
}
@if (ShowFiles)
{
<div>
<div class="row mt-1">
<div class="col">
<select class="form-select" value="@FileId" @onchange="(e => FileChanged(e))">
<option value="-1">&lt;@Localizer["File.Select"]&gt;</option>
@foreach (File file in _files)
@ -36,10 +37,12 @@
}
</select>
</div>
</div>
}
@if (ShowUpload && _haseditpermission)
{
<div>
<div class="row">
<div class="col mt-2">
@if (UploadMultiple)
{
<input type="file" id="@_fileinputid" name="file" accept="@_filter" multiple />
@ -48,17 +51,22 @@
{
<input type="file" id="@_fileinputid" name="file" accept="@_filter" />
}
<span id="@_progressinfoid"></span><progress id="@_progressbarid" style="width: 150px; visibility: hidden;"></progress>
<span class="float-end">
</div>
<div class="col mt-2 text-center">
<button type="button" class="btn btn-success" @onclick="UploadFile">@SharedLocalizer["Upload"]</button>
@if (ShowFiles && GetFileId() != -1)
{
<button type="button" class="btn btn-danger" @onclick="DeleteFile">@SharedLocalizer["Delete"]</button>
<button type="button" class="btn btn-danger mx-1" @onclick="DeleteFile">@SharedLocalizer["Delete"]</button>
}
</span>
</div>
</div>
<div class="row">
<div class="col mt-1"><span id="@_progressinfoid" style="display: none;"></span></div>
<div class="col text-center mt-1"><progress id="@_progressbarid" class="mt-1" style="display: none;"></progress></div>
</div>
}
</div>
</div>
@if (_image != string.Empty)
{
<div class="col-auto">
@ -68,8 +76,8 @@
</div>
@if (!string.IsNullOrEmpty(_message))
{
<div class="row">
<div class="col mt-2">
<div class="row mt-1">
<div class="col">
<ModuleMessage Message="@_message" Type="@_messagetype" />
</div>
</div>
@ -96,10 +104,16 @@
public string Id { get; set; } // optional - for setting the id of the FileManager component for accessibility
[Parameter]
public string Folder { get; set; } // optional - for setting a specific folder by default ( only relevant for host functions )
public int FolderId { get; set; } = -1; // optional - for setting a specific default folder by folderid
[Parameter]
public int FolderId { get; set; } = -1; // optional - for setting a specific folderid by default
public string Folder { get; set; } = ""; // optional - for setting a specific default folder by folder path
[Parameter]
public int FileId { get; set; } = -1; // optional - for selecting a specific file by default
[Parameter]
public string Filter { get; set; } // optional - comma delimited list of file types that can be selected or uploaded ie. "jpg,gif"
[Parameter]
public bool ShowFiles { get; set; } = true; // optional - for indicating whether a list of files should be displayed - default is true
@ -114,10 +128,7 @@
public bool ShowImage { get; set; } = true; // optional - for indicating whether an image thumbnail should be displayed - default is true
[Parameter]
public int FileId { get; set; } = -1; // optional - for selecting a specific file by default
[Parameter]
public string Filter { get; set; } // optional - comma delimited list of file types that can be selected or uploaded ie. "jpg,gif"
public bool ShowSuccess { get; set; } = false; // optional - for indicating whether a success message should be displayed upon successful upload - default is false
[Parameter]
public bool UploadMultiple { get; set; } = false; // optional - enable multiple file uploads - default false
@ -138,19 +149,35 @@
_id = Id;
}
// packages folder is a framework folder for uploading installable nuget packages
if (Folder == Constants.PackagesFolder)
{
ShowFiles = false;
ShowFolders = false;
Filter = "nupkg";
ShowSuccess = true;
}
if (!ShowFiles)
{
ShowImage = false;
}
if (!string.IsNullOrEmpty(Folder))
_folders = await FolderService.GetFoldersAsync(ModuleState.SiteId);
if (!string.IsNullOrEmpty(Folder) && Folder != Constants.PackagesFolder)
{
_folders = new List<Folder> { new Folder { FolderId = -1, Name = Folder } };
FolderId = -1;
Folder folder = await FolderService.GetFolderAsync(ModuleState.SiteId, Folder);
if (folder != null)
{
FolderId = folder.FolderId;
}
else
{
_folders = await FolderService.GetFoldersAsync(ModuleState.SiteId);
FolderId = -1;
_message = "Folder Path " + Folder + "Does Not Exist";
_messagetype = MessageType.Error;
}
}
if (FileId != -1)
@ -164,6 +191,8 @@
else
{
FileId = -1; // file does not exist
_message = "FileId " + FileId.ToString() + "Does Not Exist";
_messagetype = MessageType.Error;
}
}
@ -186,10 +215,10 @@
private async Task GetFiles()
{
_haseditpermission = false;
if (!string.IsNullOrEmpty(Folder))
if (Folder == Constants.PackagesFolder)
{
_haseditpermission = UserSecurity.IsAuthorized(PageState.User, RoleNames.Host);
_files = await FileService.GetFilesAsync(Folder);
_files = new List<File>();
}
else
{
@ -234,7 +263,6 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Files {Error}", ex.Message);
_message = Localizer["Error.File.Load"];
_messagetype = MessageType.Error;
}
@ -286,7 +314,7 @@
try
{
string result;
if (!string.IsNullOrEmpty(Folder))
if (Folder == Constants.PackagesFolder)
{
result = await FileService.UploadFilesAsync(Folder, upload, _guid);
}
@ -298,9 +326,11 @@
if (result == string.Empty)
{
await logger.LogInformation("File Upload Succeeded {Files}", upload);
if (ShowSuccess)
{
_message = Localizer["Success.File.Upload"];
_messagetype = MessageType.Success;
}
// set FileId to first file in upload collection
await GetFiles();
@ -364,5 +394,7 @@
public int GetFileId() => FileId;
public int GetFolderId() => FolderId;
public File GetFile() => _file;
}

View File

@ -10,7 +10,7 @@
<li class="page-item@((_page > 1) ? "" : " disabled")">
<a class="page-link" @onclick=@(async () => UpdateList(1))><span class="oi oi-media-step-backward" title="start" aria-hidden="true"></span></a>
</li>
@if (_pages > _displayPages)
@if (_pages > _displayPages && _displayPages > 1)
{
<li class="page-item@((_page > _displayPages) ? "" : " disabled")">
<a class="page-link" @onclick=@(async () => SkipPages("back"))><span class="oi oi-media-skip-backward" title="skip back" aria-hidden="true"></span></a>
@ -38,7 +38,7 @@
<li class="page-item@((_page < _pages) ? "" : " disabled")">
<a class="page-link" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></a>
</li>
@if (_pages > _displayPages)
@if (_pages > _displayPages && _displayPages > 1)
{
<li class="page-item@((_endPage < _pages) ? "" : " disabled")">
<a class="page-link" @onclick=@(async () => SkipPages("forward"))><span class="oi oi-media-skip-forward" title="skip forward" aria-hidden="true"></span></a>
@ -48,7 +48,7 @@
<a class="page-link" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="end" aria-hidden="true"></span></a>
</li>
<li class="page-item disabled">
<a class="page-link">Page @_page of @_pages</a>
<a class="page-link" style="white-space: nowrap;">Page @_page of @_pages</a>
</li>
</ul>
}
@ -215,7 +215,7 @@
}
else
{
Class = "container";
Class = "container-fluid px-0";
}
}

View File

@ -38,11 +38,7 @@ else
if (string.IsNullOrEmpty(Heading))
{
Name = Localize(nameof(Name), Name);
}
else
{
Heading = Localize(nameof(Heading), Heading);
Heading = Localize(nameof(Name), Name);
}
}

View File

@ -30,8 +30,8 @@ namespace Oqtane.Modules
[CascadingParameter]
protected Module ModuleState { get; set; }
[CascadingParameter]
protected ModuleInstance ModuleInstance { get; set; }
[Parameter]
public ModuleInstance ModuleInstance { get; set; }
// optional interface properties
public virtual SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.View; } set { } } // default security

View File

@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Exe</OutputType>
<RazorLangVersion>3.0</RazorLangVersion>
<Configurations>Debug;Release</Configurations>
<Version>2.3.1</Version>
<Version>3.0.0</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
@ -13,7 +13,7 @@
<Copyright>.NET Foundation</Copyright>
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<RootNamespace>Oqtane</RootNamespace>
@ -22,12 +22,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.4" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="5.0.4" />
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="6.0.0" />
<PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -24,7 +24,6 @@ namespace Oqtane.Client
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
var httpClient = new HttpClient {BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)};

View File

@ -153,4 +153,22 @@
<data name="Integrated" xml:space="preserve">
<value>Integrated</value>
</data>
<data name="Encryption,Text" xml:space="preserve">
<value>Encryption:</value>
</data>
<data name="Encryption.HelpText" xml:space="preserve">
<value>Specify if you are using an encrypted database connection. It is highly recommended to use encryption in a production environment.</value>
</data>
<data name="Self Signed" xml:space="preserve">
<value>Self Signed</value>
</data>
<data name="TrustServerCertificate.HelpText" xml:space="preserve">
<value>Specify the type of certificate you are using for encryption</value>
</data>
<data name="TrustServerCertificate.Text" xml:space="preserve">
<value>Trust Server Certificate:</value>
</data>
<data name="Verifiable" xml:space="preserve">
<value>Verifiable</value>
</data>
</root>

View File

@ -181,7 +181,7 @@
<value>Select whether the page is part of the site navigation or hidden</value>
</data>
<data name="UrlPath.HelpText" xml:space="preserve">
<value>Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used.</value>
<value>Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used. If the page is intended to be the root path specify '/'.</value>
</data>
<data name="Redirect.HelpText" xml:space="preserve">
<value>Optionally enter a url which this page should redirect to when a user navigates to it</value>

View File

@ -169,7 +169,7 @@
<value>Select whether the page is part of the site navigation or hidden</value>
</data>
<data name="UrlPath.HelpText" xml:space="preserve">
<value>Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used.</value>
<value>Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used. If the page is intended to be the root path specify '/'.</value>
</data>
<data name="Redirect.HelpText" xml:space="preserve">
<value>Optionally enter a url which this page should redirect to when a user navigates to it</value>

View File

@ -129,4 +129,7 @@
<data name="DeletePage.Header" xml:space="preserve">
<value>Delete Page</value>
</data>
<data name="Browse" xml:space="preserve">
<value>Browse</value>
</data>
</root>

View File

@ -169,7 +169,7 @@
<value>Enter the tenant for the site</value>
</data>
<data name="Aliases.HelpText" xml:space="preserve">
<value>Enter the alias for the server</value>
<value>The aliases for the site. An alias can be a domain name (www.site.com) or a virtual folder (ie. www.site.com/folder). If a site has multiple aliases they should be separated by commas.</value>
</data>
<data name="AllowRegistration.HelpText" xml:space="preserve">
<value>Do you want the users to be able to register for an account on the site</value>
@ -282,4 +282,22 @@
<data name="Theme.Select" xml:space="preserve">
<value>Select Theme</value>
</data>
<data name="Hosting" xml:space="preserve">
<value>Hosting Model</value>
</data>
<data name="Prerender.HelpText" xml:space="preserve">
<value>Specifies if the site should be prerendered (for search crawlers, etc...)</value>
</data>
<data name="Prerender.Text" xml:space="preserve">
<value>Prerender? </value>
</data>
<data name="Runtime.HelpText" xml:space="preserve">
<value>The Blazor runtime hosting model</value>
</data>
<data name="Runtime.Text" xml:space="preserve">
<value>Runtime: </value>
</data>
<data name="Browse" xml:space="preserve">
<value>Browse</value>
</data>
</root>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
@ -217,10 +217,10 @@
<value>Enter the password for the integrated security</value>
</data>
<data name="HostUsername.HelpText" xml:space="preserve">
<value>Enter a valid host username</value>
<value>Enter the username of an existing host user</value>
</data>
<data name="HostPassword.HelpText" xml:space="preserve">
<value>Enter a valid host password</value>
<value>Enter the password of an existing host user</value>
</data>
<data name="Name.Text" xml:space="preserve">
<value>Site Name: </value>
@ -258,4 +258,16 @@
<data name="Error.Database.LoadConfig" xml:space="preserve">
<value>Error loading Database Configuration Control</value>
</data>
<data name="Prerender.HelpText" xml:space="preserve">
<value>Specifies if the site should be prerendered (for search crawlers, etc...)</value>
</data>
<data name="Prerender.Text" xml:space="preserve">
<value>Prerender? </value>
</data>
<data name="Runtime.HelpText" xml:space="preserve">
<value>The Blazor runtime hosting model</value>
</data>
<data name="Runtime.Text" xml:space="preserve">
<value>Runtime: </value>
</data>
</root>

View File

@ -123,9 +123,6 @@
<data name="FrameworkVersion.HelpText" xml:space="preserve">
<value>Framework Version</value>
</data>
<data name="BlazorRuntime.HelpText" xml:space="preserve">
<value>Blazor Runtime (Server or WebAssembly)</value>
</data>
<data name="CLRVersion.HelpText" xml:space="preserve">
<value>Common Language Runtime Version</value>
</data>
@ -141,9 +138,6 @@
<data name="FrameworkVersion.Text" xml:space="preserve">
<value>Framework Version: </value>
</data>
<data name="BlazorRuntime.Text" xml:space="preserve">
<value>Blazor Runtime: </value>
</data>
<data name="CLRVersion.Text" xml:space="preserve">
<value>CLR Version: </value>
</data>
@ -165,18 +159,9 @@
<data name="Error.UpdateConfig" xml:space="preserve">
<value>An Error Occurred Updating The Configuration</value>
</data>
<data name="Server" xml:space="preserve">
<value>Server</value>
</data>
<data name="ServerPrerendered" xml:space="preserve">
<value>ServerPrerendered</value>
</data>
<data name="Success.UpdateConfig.Restart" xml:space="preserve">
<value>Configuration Updated. Please Select Restart Application For These Changes To Be Activated.</value>
</data>
<data name="WebAssembly" xml:space="preserve">
<value>WebAssembly</value>
</data>
<data name="InstallationId.Text" xml:space="preserve">
<value>Installation ID: </value>
</data>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
@ -126,9 +126,6 @@
<data name="Error.File.Load" xml:space="preserve">
<value>Error Loading Files</value>
</data>
<data name="Success.File.Upload" xml:space="preserve">
<value>File Upload Succeeded</value>
</data>
<data name="Error.File.Upload" xml:space="preserve">
<value>File Upload Failed</value>
</data>
@ -141,4 +138,7 @@
<data name="Error.File.Delete" xml:space="preserve">
<value>Error Deleting File</value>
</data>
<data name="Success.File.Upload" xml:space="preserve">
<value>File Upload Succeeded</value>
</data>
</root>

View File

@ -312,4 +312,10 @@
<data name="Not Specified" xml:space="preserve">
<value>Not Specified</value>
</data>
<data name="BlazorServer" xml:space="preserve">
<value>Blazor Server</value>
</data>
<data name="BlazorWebAssembly" xml:space="preserve">
<value>Blazor WebAssembly</value>
</data>
</root>

View File

@ -109,6 +109,9 @@ namespace Oqtane.Services
attempts += 1;
}
await interop.SetElementAttribute(id + "ProgressInfo", "style", "display: none;");
await interop.SetElementAttribute(id + "ProgressBar", "style", "display: none;");
if (!success)
{
result = result.Substring(0, result.Length - 1);

View File

@ -1,7 +1,7 @@
@namespace Oqtane.Themes.BlazorTheme
@namespace Oqtane.Themes.BlazorTheme
@inherits ContainerBase
<div class="container">
<div class="row px-4">
<div class="row p-4">
<div class="d-flex flex-nowrap">
<ModuleActions /><h2><ModuleTitle /></h2>
</div>

View File

@ -1,17 +1,19 @@
@namespace Oqtane.Themes.BlazorTheme
@inherits ThemeBase
<div class="breadcrumbs">
<Breadcrumbs />
</div>
<div class="row flex-xl-nowrap gx-0">
<div class="sidebar">
<nav class="navbar">
<Logo /><Menu Orientation="Vertical" />
</nav>
</div>
<div class="main">
<div class="main g-0">
<div class="top-row px-4">
<div class="ms-auto"><UserProfile /> <Login /> <ControlPanel /></div>
</div>
@ -21,15 +23,17 @@
</div>
</div>
</div>
</div>
@code {
public override string Panes => PaneNames.Admin;
public override List<Resource> Resources => new List<Resource>()
{
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css", Integrity = "sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC", CrossOrigin = "anonymous" },
// obtained from https://cdnjs.com/libraries
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css", Integrity = "sha512-usVBAd66/NpVNfBge19gws2j6JZinnca12rAe2l+d+QkLU9fiG02O1X8Q6hepIpr/EYKZvKx/I9WsnujJuOmBA==", CrossOrigin = "anonymous" },
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js", Integrity = "sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM", CrossOrigin = "anonymous" }
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.bundle.min.js", Integrity = "sha512-pax4MlgXjHEPfCwcJLQhigY7+N8rt6bVvWLFyUMuxShv170X53TRzGPmPkZmGBhk+jikR8WBM4yl7A9WMHHqvg==", CrossOrigin = "anonymous" }
};
}

View File

@ -12,14 +12,40 @@
@inject IStringLocalizer<ControlPanel> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_moduleDefinitions != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
@if (ShowLanguageSwitcher)
{
<LanguageSwitcher />
}
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) || (PageState.Page.IsPersonalizable && PageState.User != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Registered)))
{
if (PageState.EditMode)
{
<button type="button" class="btn @ButtonClass active" data-bs-toggle="button" aria-pressed="true" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
<span class="oi oi-pencil"></span>
</button>
}
else
{
<button type="button" class="btn @ButtonClass" data-bs-toggle="button" aria-pressed="false" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
<span class="oi oi-pencil"></span>
</button>
}
}
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
{
<button class="btn @ButtonClass" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasControlPanel" aria-controls="offcanvasControlPanel">
<span class="oi oi-cog"></span>
</button>
<div class="@ContainerClass" tabindex="-1" data-bs-scroll="true" data-bs-backdrop="true" id="offcanvasControlPanel" aria-labelledby="offcanvasScrollingLabel">
<div class="@HeaderClass">
<h5 id="offcanvasScrollingLabel">@Localizer["ControlPanel"]</h5>
<h5 id="offcanvasScrollingLabel" class="offcanvas-title">@Localizer["ControlPanel"]</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="@BodyClass">
<div class="container-fluid">
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
{
<div class="row d-flex">
@ -187,35 +213,7 @@
}
</div>
</div>
}
@if (ShowLanguageSwitcher)
{
<LanguageSwitcher />
}
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) || (PageState.Page.IsPersonalizable && PageState.User != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Registered)))
{
if (PageState.EditMode)
{
<button type="button" class="btn @ButtonClass active" data-bs-toggle="button" aria-pressed="true" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
<span class="oi oi-pencil"></span>
</button>
}
else
{
<button type="button" class="btn @ButtonClass" data-bs-toggle="button" aria-pressed="false" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
<span class="oi oi-pencil"></span>
</button>
}
}
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
{
<button class="btn @ButtonClass" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasControlPanel" aria-controls="offcanvasControlPanel">
<span class="oi oi-cog"></span>
</button>
</div>
}
@code{

View File

@ -23,5 +23,5 @@
@code
{
[Parameter]
public bool ShowLogin { get; set; }
public bool ShowLogin { get; set; } = true;
}

View File

@ -4,12 +4,12 @@
@if (MenuPages.Any())
{
<span class="app-menu-toggler">
<span class="app-menu-toggler navbar-expand-md">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#Menu" aria-controls="Menu" aria-expanded="false" aria-label="Toggle Navigation">
<span class="navbar-toggler-icon"></span>
</button>
</span>
<div class="app-menu">
<div class="app-menu navbar-expand-md">
<div class="collapse navbar-collapse" id="Menu">
<MenuItemsHorizontal ParentPage="null" Pages="MenuPages" />
</div>

View File

@ -3,7 +3,7 @@
@inject ISettingService SettingService
<main role="main">
<nav class="navbar navbar-expand-md navbar-dark bg-primary fixed-top">
<nav class="navbar navbar-dark bg-primary fixed-top">
<Logo /><Menu Orientation="Horizontal" />
<div class="controls ms-auto">
<div class="controls-group"><UserProfile ShowRegister="@_register" /> <Login ShowLogin="@_login" /> <ControlPanel /></div>
@ -112,9 +112,10 @@
public override List<Resource> Resources => new List<Resource>()
{
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.0.2/cyborg/bootstrap.min.css", Integrity = "sha512-X2u8dAWrVfvanPTlHwLh0fXttDDhkdV79q7cOibXR7hm9R3pRMFi53OwpGMdcbUiRk97isaXCRqFbm5LX1MiYw==", CrossOrigin = "anonymous" },
// obtained from https://cdnjs.com/libraries
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.1.3/cyborg/bootstrap.min.css", Integrity = "sha512-/in5IWTUhb7wOUd6iHotlyrLrZ7+2utJJR8ySzSxeeOMJ9fanjCr4fmyWzDW/ziw56shUNTVClBMWZaA677VhA==", CrossOrigin = "anonymous" },
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js", Integrity = "sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM", CrossOrigin = "anonymous" }
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.bundle.min.js", Integrity = "sha512-pax4MlgXjHEPfCwcJLQhigY7+N8rt6bVvWLFyUMuxShv170X53TRzGPmPkZmGBhk+jikR8WBM4yl7A9WMHHqvg==", CrossOrigin = "anonymous" }
};
private bool _login = true;

View File

@ -1,6 +1,6 @@
@namespace Oqtane.UI
<CascadingValue Value="@ModuleState" IsFixed="@(!PageState.EditMode)">
<CascadingValue Value="@ModuleState">
@if (_useadminborder)
{
<div class="app-pane-admin-border">

View File

@ -247,5 +247,20 @@ namespace Oqtane.UI
return new ValueTask<bool>(Task.FromResult(false));
}
}
public Task SetElementAttribute(string id, string attribute, string value)
{
try
{
_jsRuntime.InvokeVoidAsync(
"Oqtane.Interop.setElementAttribute",
id, attribute, value);
return Task.CompletedTask;
}
catch
{
return Task.CompletedTask;
}
}
}
}

View File

@ -2,9 +2,7 @@
@inject IStringLocalizer<ModuleInstance> Localizer
<ModuleMessage Message="@_message" Type="@_messagetype" />
<CascadingValue Value="this" IsFixed="true">
@DynamicComponent
</CascadingValue>
@if (_progressindicator)
{
<div class="app-progress-indicator"></div>
@ -39,6 +37,7 @@
if (moduleType != null)
{
builder.OpenComponent(0, moduleType);
builder.AddAttribute(1, "ModuleInstance", this);
builder.CloseComponent();
}
else

View File

@ -85,19 +85,19 @@
// parse querystring
var querystring = ParseQueryString(uri.Query);
// reload the client application if there is a forced reload or the user navigated to a site with a different alias
if (querystring.ContainsKey("reload") || (!path.ToLower().StartsWith(SiteState.Alias.Path.ToLower()) && !string.IsNullOrEmpty(SiteState.Alias.Path)))
{
NavigationManager.NavigateTo(_absoluteUri.Replace("?reload", ""), true);
return;
}
else
{
// the refresh parameter is used to refresh the PageState
if (querystring.ContainsKey("refresh"))
{
refresh = UI.Refresh.Site;
}
else
{
// reload the client application if the user navigated to a site with a different alias or there is a forced reload
if ((!path.ToLower().StartsWith(SiteState.Alias.Path.ToLower()) && !string.IsNullOrEmpty(SiteState.Alias.Path)) || querystring.ContainsKey("reload"))
{
NavigationManager.NavigateTo(_absoluteUri.Replace("?reload", ""), true);
return;
}
}
if (PageState != null)
@ -109,10 +109,10 @@
// process any sync events
var sync = await SyncService.GetSyncAsync(lastsyncdate);
lastsyncdate = sync.SyncDate;
if (refresh != UI.Refresh.Site && sync.SyncEvents.Any())
if (sync.SyncEvents.Any())
{
// if running on WebAssembly reload the client application if the server application was restarted
if (runtime == Shared.Runtime.WebAssembly && PageState != null && sync.SyncEvents.Exists(item => item.TenantId == -1))
// reload client application if server was restarted or site runtime/rendermode was modified
if (PageState != null && sync.SyncEvents.Exists(item => (item.TenantId == -1 || item.EntityName == EntityNames.Site && item.EntityId == SiteState.Alias.SiteId) && item.Reload))
{
NavigationManager.NavigateTo(_absoluteUri, true);
return;
@ -240,17 +240,16 @@
page = PageState.Page;
}
// failsafe in case router cannot locate the home page for the site
// get the page if the path has changed
if (page == null || page.Path != path)
{
page = pages.FirstOrDefault(item => item.Path.Equals(path, StringComparison.OrdinalIgnoreCase));
// if the home page path does not exist then use the first page in the collection (a future enhancement would allow the admin to specify a home page)
if (page == null && path == "")
{
page = pages.FirstOrDefault();
path = page.Path;
}
// check if page has changed
if (page != null && page.Path != path)
{
page = pages.Where(item => item.Path == path).FirstOrDefault();
editmode = false;
}

View File

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Version>2.3.1</Version>
<TargetFramework>net6.0</TargetFramework>
<Version>3.0.0</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
@ -10,7 +10,7 @@
<Copyright>.NET Foundation</Copyright>
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
@ -29,7 +29,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MySql.EntityFrameworkCore" Version="5.0.0" />
<PackageReference Include="MySql.EntityFrameworkCore" Version="6.0.0-preview3.1" />
</ItemGroup>
<ItemGroup>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Database.MySQL</id>
<version>2.3.1</version>
<version>3.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane MySQL Provider</title>
@ -12,15 +12,15 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="bin\net5.0\Oqtane.Database.MySQL.dll" target="lib\net5.0" />
<file src="bin\net5.0\Oqtane.Database.MySQL.pdb" target="lib\net5.0" />
<file src="bin\net5.0\Mysql.EntityFrameworkCore.dll" target="lib\net5.0" />
<file src="bin\net5.0\Mysql.Data.dll" target="lib\net5.0" />
<file src="bin\net6.0\Oqtane.Database.MySQL.dll" target="lib\net6.0" />
<file src="bin\net6.0\Oqtane.Database.MySQL.pdb" target="lib\net6.0" />
<file src="bin\net6.0\Mysql.EntityFrameworkCore.dll" target="lib\net6.0" />
<file src="bin\net6.0\Mysql.Data.dll" target="lib\net6.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Version>2.3.1</Version>
<TargetFramework>net6.0</TargetFramework>
<Version>3.0.0</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
@ -10,7 +10,7 @@
<Copyright>.NET Foundation</Copyright>
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
@ -29,9 +29,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="EFCore.NamingConventions" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.4" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.2" />
<PackageReference Include="EFCore.NamingConventions" Version="6.0.0-rc.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Database.PostgreSQL</id>
<version>2.3.1</version>
<version>3.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane PostgreSQL Provider</title>
@ -12,16 +12,16 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="bin\net5.0\Oqtane.Database.PostgreSQL.dll" target="lib\net5.0" />
<file src="bin\net5.0\Oqtane.Database.PostgreSQL.pdb" target="lib\net5.0" />
<file src="bin\net5.0\EFCore.NamingConventions.dll" target="lib\net5.0" />
<file src="bin\net5.0\Npgsql.EntityFrameworkCore.PostgreSQL.dll" target="lib\net5.0" />
<file src="bin\net5.0\Npgsql.dll" target="lib\net5.0" />
<file src="bin\net6.0\Oqtane.Database.PostgreSQL.dll" target="lib\net6.0" />
<file src="bin\net6.0\Oqtane.Database.PostgreSQL.pdb" target="lib\net6.0" />
<file src="bin\net6.0\EFCore.NamingConventions.dll" target="lib\net6.0" />
<file src="bin\net6.0\Npgsql.EntityFrameworkCore.PostgreSQL.dll" target="lib\net6.0" />
<file src="bin\net6.0\Npgsql.dll" target="lib\net6.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -104,23 +104,31 @@ namespace Oqtane.Database.PostgreSQL
var tableName = entity.GetTableName();
if (tableName.StartsWith("AspNetUser"))
{
// Replace table names
// replace table name
entity.SetTableName(RewriteName(entity.GetTableName()));
// Replace column names
// replace column names
foreach(var property in entity.GetProperties())
{
property.SetColumnName(RewriteName(property.GetColumnName()));
property.SetColumnName(RewriteName(property.Name));
}
// replace key names
foreach(var key in entity.GetKeys())
{
key.SetName(RewriteName(key.GetName()));
}
// replace foreign key names
foreach (var key in entity.GetForeignKeys())
{
key.PrincipalKey.SetName(RewriteName(key.PrincipalKey.GetName()));
}
// replace index names
foreach (var index in entity.GetIndexes())
{
index.SetName(RewriteName(index.GetName()));
index.SetDatabaseName(RewriteName(index.GetDatabaseName()));
}
}
}

View File

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Version>2.3.1</Version>
<TargetFramework>net6.0</TargetFramework>
<Version>3.0.0</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
@ -10,7 +10,7 @@
<Copyright>.NET Foundation</Copyright>
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
@ -29,7 +29,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Database.SqlServer</id>
<version>2.3.1</version>
<version>3.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane SQL Server Provider</title>
@ -12,14 +12,14 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="bin\net5.0\Oqtane.Database.SqlServer.dll" target="lib\net5.0" />
<file src="bin\net5.0\Oqtane.Database.SqlServer.pdb" target="lib\net5.0" />
<file src="bin\net5.0\Microsoft.EntityFrameworkCore.SqlServer.dll" target="lib\net5.0" />
<file src="bin\net6.0\Oqtane.Database.SqlServer.dll" target="lib\net6.0" />
<file src="bin\net6.0\Oqtane.Database.SqlServer.pdb" target="lib\net6.0" />
<file src="bin\net6.0\Microsoft.EntityFrameworkCore.SqlServer.dll" target="lib\net6.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Version>2.3.1</Version>
<TargetFramework>net6.0</TargetFramework>
<Version>3.0.0</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
@ -10,7 +10,7 @@
<Copyright>.NET Foundation</Copyright>
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
@ -29,7 +29,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Database.Sqlite</id>
<version>2.3.1</version>
<version>3.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane SQLite Provider</title>
@ -12,14 +12,14 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="bin\net5.0\Oqtane.Database.Sqlite.dll" target="lib\net5.0" />
<file src="bin\net5.0\Oqtane.Database.Sqlite.pdb" target="lib\net5.0" />
<file src="bin\net5.0\Microsoft.EntityFrameworkCore.Sqlite.dll" target="lib\net5.0" />
<file src="bin\net6.0\Oqtane.Database.Sqlite.dll" target="lib\net6.0" />
<file src="bin\net6.0\Oqtane.Database.Sqlite.pdb" target="lib\net6.0" />
<file src="bin\net6.0\Microsoft.EntityFrameworkCore.Sqlite.dll" target="lib\net6.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Client</id>
<version>2.3.1</version>
<version>3.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane Framework</title>
@ -12,13 +12,13 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="..\Oqtane.Client\bin\Release\net5.0\Oqtane.Client.dll" target="lib\net5.0" />
<file src="..\Oqtane.Client\bin\Release\net5.0\Oqtane.Client.pdb" target="lib\net5.0" />
<file src="..\Oqtane.Client\bin\Release\net6.0\Oqtane.Client.dll" target="lib\net6.0" />
<file src="..\Oqtane.Client\bin\Release\net6.0\Oqtane.Client.pdb" target="lib\net6.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Framework</id>
<version>2.3.1</version>
<version>3.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane Framework</title>
@ -11,8 +11,8 @@
<copyright>.NET Foundation</copyright>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v2.3.1/Oqtane.Framework.2.3.1.Upgrade.zip</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</releaseNotes>
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v3.0.0/Oqtane.Framework.3.0.0.Upgrade.zip</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane framework</tags>
</metadata>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Server</id>
<version>2.3.1</version>
<version>3.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane Framework</title>
@ -12,13 +12,13 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="..\Oqtane.Server\bin\Release\net5.0\Oqtane.Server.dll" target="lib\net5.0" />
<file src="..\Oqtane.Server\bin\Release\net5.0\Oqtane.Server.pdb" target="lib\net5.0" />
<file src="..\Oqtane.Server\bin\Release\net6.0\Oqtane.Server.dll" target="lib\net6.0" />
<file src="..\Oqtane.Server\bin\Release\net6.0\Oqtane.Server.pdb" target="lib\net6.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Shared</id>
<version>2.3.1</version>
<version>3.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane Framework</title>
@ -12,13 +12,13 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="..\Oqtane.Shared\bin\Release\net5.0\Oqtane.Shared.dll" target="lib\net5.0" />
<file src="..\Oqtane.Shared\bin\Release\net5.0\Oqtane.Shared.pdb" target="lib\net5.0" />
<file src="..\Oqtane.Shared\bin\Release\net6.0\Oqtane.Shared.dll" target="lib\net6.0" />
<file src="..\Oqtane.Shared\bin\Release\net6.0\Oqtane.Shared.pdb" target="lib\net6.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Updater</id>
<version>2.3.1</version>
<version>3.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane Framework</title>
@ -12,12 +12,12 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="..\Oqtane.Updater\bin\Release\net5.0\publish\*.*" target="lib\net5.0" />
<file src="..\Oqtane.Updater\bin\Release\net6.0\publish\*.*" target="lib\net6.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -1 +1 @@
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "Oqtane.Framework.2.3.1.Install.zip" -Force
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.0.0.Install.zip" -Force

View File

@ -8,15 +8,16 @@ nuget.exe pack Oqtane.Client.nuspec
nuget.exe pack Oqtane.Server.nuspec
nuget.exe pack Oqtane.Shared.nuspec
nuget.exe pack Oqtane.Framework.nuspec
del /F/Q/S "..\Oqtane.Server\bin\Release\net5.0\publish" > NUL
rmdir /Q/S "..\Oqtane.Server\bin\Release\net5.0\publish"
del /F/Q/S "..\Oqtane.Server\bin\Release\net6.0\publish" > NUL
rmdir /Q/S "..\Oqtane.Server\bin\Release\net6.0\publish"
dotnet publish ..\Oqtane.Server\Oqtane.Server.csproj /p:Configuration=Release
del /F/Q/S "..\Oqtane.Server\bin\Release\net5.0\publish\wwwroot\Content" > NUL
rmdir /Q/S "..\Oqtane.Server\bin\Release\net5.0\publish\wwwroot\Content"
del "..\Oqtane.Server\bin\Release\net5.0\publish\appsettings.json"
ren "..\Oqtane.Server\bin\Release\net5.0\publish\appsettings.release.json" "appsettings.json"
del /F/Q/S "..\Oqtane.Server\bin\Release\net6.0\publish\wwwroot\Content" > NUL
rmdir /Q/S "..\Oqtane.Server\bin\Release\net6.0\publish\wwwroot\Content"
del "..\Oqtane.Server\bin\Release\net6.0\publish\appsettings.json"
ren "..\Oqtane.Server\bin\Release\net6.0\publish\appsettings.release.json" "appsettings.json"
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\install.ps1"
del "..\Oqtane.Server\bin\Release\net5.0\publish\appsettings.json"
del "..\Oqtane.Server\bin\Release\net6.0\publish\appsettings.json"
del "..\Oqtane.Server\bin\Release\net6.0\publish\web.config"
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\upgrade.ps1"
dotnet clean -c Release ..\Oqtane.Updater.sln
dotnet build -c Release ..\Oqtane.Updater.sln

View File

@ -1 +1 @@
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "Oqtane.Framework.2.3.1.Upgrade.zip" -Force
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.0.0.Upgrade.zip" -Force

View File

@ -20,6 +20,7 @@ using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using System.Net.Http;
// ReSharper disable StringIndexOfIsCultureSpecific.1
@ -190,7 +191,7 @@ namespace Oqtane.Controllers
// GET api/<controller>/upload?url=x&folderid=y&name=z
[HttpGet("upload")]
public Models.File UploadFile(string url, string folderid, string name)
public async Task<Models.File> UploadFile(string url, string folderid, string name)
{
Models.File file = null;
@ -227,15 +228,25 @@ namespace Oqtane.Controllers
try
{
var client = new WebClient();
string targetPath = Path.Combine(folderPath, name);
// remove file if it already exists
if (System.IO.File.Exists(targetPath))
{
System.IO.File.Delete(targetPath);
}
client.DownloadFile(url, targetPath);
using (var client = new HttpClient())
{
using (var stream = await client.GetStreamAsync(url))
{
using (var fileStream = new FileStream(targetPath, FileMode.CreateNew))
{
await stream.CopyToAsync(fileStream);
}
}
}
file = CreateFile(name, folder.FolderId, targetPath);
if (file != null)
{

View File

@ -101,17 +101,9 @@ namespace Oqtane.Controllers
// GET api/<controller>/load
[HttpGet("load")]
public IActionResult Load()
{
if (_configManager.GetSection("Runtime").Value == "WebAssembly")
{
return File(GetAssemblies(), System.Net.Mime.MediaTypeNames.Application.Octet, "oqtane.dll");
}
else
{
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
return null;
}
}
private byte[] GetAssemblies()
{

View File

@ -307,9 +307,9 @@ namespace Oqtane.Controllers
if (moduleDefinition.Version == "local")
{
text = text.Replace("[FrameworkVersion]", Constants.Version);
text = text.Replace("[ClientReference]", "<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Client.dll</HintPath></Reference>");
text = text.Replace("[ServerReference]", "<Reference Include=\"Oqtane.Server\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Server.dll</HintPath></Reference>");
text = text.Replace("[SharedReference]", "<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Shared.dll</HintPath></Reference>");
text = text.Replace("[ClientReference]", "<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net6.0\\Oqtane.Client.dll</HintPath></Reference>");
text = text.Replace("[ServerReference]", "<Reference Include=\"Oqtane.Server\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net6.0\\Oqtane.Server.dll</HintPath></Reference>");
text = text.Replace("[SharedReference]", "<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net6.0\\Oqtane.Shared.dll</HintPath></Reference>");
}
else
{

View File

@ -84,10 +84,16 @@ namespace Oqtane.Controllers
[Authorize(Roles = RoleNames.Admin)]
public Site Put(int id, [FromBody] Site site)
{
if (ModelState.IsValid && site.SiteId == _alias.SiteId && site.TenantId == _alias.TenantId && _sites.GetSite(site.SiteId, false) != null)
var current = _sites.GetSite(site.SiteId, false);
if (ModelState.IsValid && site.SiteId == _alias.SiteId && site.TenantId == _alias.TenantId && current != null)
{
site = _sites.UpdateSite(site);
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId);
bool reload = false;
if (current.Runtime != site.Runtime || current.RenderMode != site.RenderMode)
{
reload = true;
}
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, reload);
_logger.Log(site.SiteId, LogLevel.Information, this, LogFunction.Update, "Site Updated {Site}", site);
}
else

View File

@ -188,8 +188,8 @@ namespace Oqtane.Controllers
if (theme.Version == "local")
{
text = text.Replace("[FrameworkVersion]", Constants.Version);
text = text.Replace("[ClientReference]", "<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Client.dll</HintPath></Reference>");
text = text.Replace("[SharedReference]", "<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Shared.dll</HintPath></Reference>");
text = text.Replace("[ClientReference]", "<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net6.0\\Oqtane.Client.dll</HintPath></Reference>");
text = text.Replace("[SharedReference]", "<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net6.0\\Oqtane.Shared.dll</HintPath></Reference>");
}
else
{

View File

@ -209,7 +209,7 @@ namespace Oqtane.Infrastructure
bool installPackages = false;
// iterate database packages in installation folder
var packagesFolder = new DirectoryInfo(Path.Combine(_environment.ContentRootPath, "Packages"));
var packagesFolder = new DirectoryInfo(Path.Combine(_environment.ContentRootPath, Constants.PackagesFolder));
foreach (var package in packagesFolder.GetFiles("*.nupkg.bak"))
{
// determine if package needs to be upgraded or installed
@ -585,7 +585,9 @@ namespace Oqtane.Infrastructure
DefaultThemeType = (!string.IsNullOrEmpty(install.DefaultTheme)) ? install.DefaultTheme : Constants.DefaultTheme,
DefaultContainerType = (!string.IsNullOrEmpty(install.DefaultContainer)) ? install.DefaultContainer : Constants.DefaultContainer,
AdminContainerType = (!string.IsNullOrEmpty(install.DefaultAdminContainer)) ? install.DefaultAdminContainer : Constants.DefaultAdminContainer,
SiteTemplateType = install.SiteTemplate
SiteTemplateType = install.SiteTemplate,
Runtime = (!string.IsNullOrEmpty(install.Runtime)) ? install.Runtime : _configManager.GetSection("Runtime").Value,
RenderMode = (!string.IsNullOrEmpty(install.RenderMode)) ? install.RenderMode : _configManager.GetSection("RenderMode").Value
};
site = sites.AddSite(site);

View File

@ -4,10 +4,11 @@ using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
@ -112,7 +113,7 @@ namespace Oqtane.Infrastructure
// evaluate entry root folder
switch (entry.FullName.Split('/')[0])
{
case "lib": // lib/net5.0/...
case "lib": // lib/net*/...
filename = ExtractFile(entry, binPath, 2);
break;
case "wwwroot": // wwwroot/...
@ -121,7 +122,7 @@ namespace Oqtane.Infrastructure
case "runtimes": // runtimes/name/...
filename = ExtractFile(entry, binPath, 0);
break;
case "ref": // ref/net5.0/...
case "ref": // ref/net*/...
filename = ExtractFile(entry, Path.Combine(binPath, "ref"), 2);
break;
}
@ -190,7 +191,7 @@ namespace Oqtane.Infrastructure
{
// get manifest with highest version
string packagename = "";
string[] packages = Directory.GetFiles(Path.Combine(_environment.ContentRootPath, "Packages"), PackageName + "*.log");
string[] packages = Directory.GetFiles(Path.Combine(_environment.ContentRootPath, Constants.PackagesFolder), PackageName + "*.log");
if (packages.Length > 0)
{
packagename = packages[packages.Length - 1]; // use highest version
@ -228,9 +229,9 @@ namespace Oqtane.Infrastructure
return false;
}
public void UpgradeFramework()
public async Task UpgradeFramework()
{
string folder = Path.Combine(_environment.ContentRootPath, "Packages");
string folder = Path.Combine(_environment.ContentRootPath, Constants.PackagesFolder);
if (Directory.Exists(folder))
{
// get package with highest version
@ -281,10 +282,18 @@ namespace Oqtane.Infrastructure
// install Oqtane.Framework and Oqtane.Updater nuget packages
InstallPackages();
// download upgrade zip package
var client = new WebClient();
Uri uri = new Uri(packageurl);
string upgradepackage = Path.Combine(folder, uri.Segments[uri.Segments.Length - 1]);
client.DownloadFile(packageurl, upgradepackage);
using (var client = new HttpClient())
{
using (var stream = await client.GetStreamAsync(packageurl))
{
using (var fileStream = new FileStream(upgradepackage, FileMode.CreateNew))
{
await stream.CopyToAsync(fileStream);
}
}
}
// install Oqtane.Upgrade zip package
if (File.Exists(upgradepackage))
{

View File

@ -1,10 +1,12 @@
using System.Threading.Tasks;
namespace Oqtane.Infrastructure
{
public interface IInstallationManager
{
void InstallPackages();
bool UninstallPackage(string PackageName);
void UpgradeFramework();
Task UpgradeFramework();
void RestartApplication();
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using Oqtane.Models;
@ -8,5 +8,6 @@ namespace Oqtane.Infrastructure
{
List<SyncEvent> GetSyncEvents(int tenantId, DateTime lastSyncDate);
void AddSyncEvent(int tenantId, string entityName, int entityId);
void AddSyncEvent(int tenantId, string entityName, int entityId, bool reload);
}
}

View File

@ -38,6 +38,7 @@ namespace Oqtane.SiteTemplates
{
Name = "Home",
Parent = "",
Order = 1,
Path = "",
Icon = "oi oi-home",
IsNavigation = true,
@ -84,6 +85,7 @@ namespace Oqtane.SiteTemplates
{
Name = "Private",
Parent = "",
Order = 3,
Path = "private",
Icon = "oi oi-lock-locked",
IsNavigation = true,
@ -108,6 +110,7 @@ namespace Oqtane.SiteTemplates
{
Name = "My Page",
Parent = "",
Order = 5,
Path = "mypage",
Icon = "oi oi-target",
IsNavigation = true,

View File

@ -22,7 +22,12 @@ namespace Oqtane.Infrastructure
public void AddSyncEvent(int tenantId, string entityName, int entityId)
{
SyncEvents.Add(new SyncEvent { TenantId = tenantId, EntityName = entityName, EntityId = entityId, ModifiedOn = DateTime.UtcNow });
AddSyncEvent(tenantId, entityName, entityId, false);
}
public void AddSyncEvent(int tenantId, string entityName, int entityId, bool reload)
{
SyncEvents.Add(new SyncEvent { TenantId = tenantId, EntityName = entityName, EntityId = entityId, Reload = reload, ModifiedOn = DateTime.UtcNow });
// trim sync events
SyncEvents.RemoveAll(item => item.ModifiedOn < DateTime.UtcNow.AddHours(-1));
}

View File

@ -1,8 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Databases.Interfaces;
using Oqtane.Interfaces;
namespace Oqtane.Migrations
{

View File

@ -0,0 +1,33 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Databases.Interfaces;
using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository;
namespace Oqtane.Migrations.Tenant
{
[DbContext(typeof(TenantDBContext))]
[Migration("Tenant.03.00.00.01")]
public class AddSiteRuntime : MultiDatabaseMigration
{
public AddSiteRuntime(IDatabase database) : base(database)
{
}
protected override void Up(MigrationBuilder migrationBuilder)
{
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
siteEntityBuilder.AddStringColumn("Runtime", 50, true, true);
siteEntityBuilder.UpdateColumn("Runtime", "'Server'");
siteEntityBuilder.AddStringColumn("RenderMode", 50, true, true);
siteEntityBuilder.UpdateColumn("RenderMode", "'ServerPrerendered'");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
siteEntityBuilder.DropColumn("Runtime");
siteEntityBuilder.DropColumn("RenderMode");
}
}
}

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<Configurations>Debug;Release</Configurations>
<Version>2.3.1</Version>
<Version>3.0.0</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
@ -11,7 +11,7 @@
<Copyright>.NET Foundation</Copyright>
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.3.1</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<RootNamespace>Oqtane</RootNamespace>
@ -30,20 +30,20 @@
<EmbeddedResource Include="Scripts\MigrateTenant.sql" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.4" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="2.0.1" />
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="5.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.4">
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="4.0.0-preview3.21293.2" />
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Localization" Version="5.0.4" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.3" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="6.0.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.0.7" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Oqtane.Client\Oqtane.Client.csproj" />

View File

@ -44,8 +44,6 @@
{
<script src="_framework/blazor.server.js"></script>
}
<input name="app_runtime" type="hidden" value="@Model.Runtime">
<input name="app_rendermode" type="hidden" value="@Model.RenderMode">
@Html.Raw(@Model.BodyResources)
</body>
</html>

View File

@ -23,14 +23,16 @@ namespace Oqtane.Pages
private readonly ILocalizationManager _localizationManager;
private readonly ILanguageRepository _languages;
private readonly IAntiforgery _antiforgery;
private readonly ISiteRepository _sites;
public HostModel(IConfiguration configuration, ITenantManager tenantManager, ILocalizationManager localizationManager, ILanguageRepository languages, IAntiforgery antiforgery)
public HostModel(IConfiguration configuration, ITenantManager tenantManager, ILocalizationManager localizationManager, ILanguageRepository languages, IAntiforgery antiforgery, ISiteRepository sites)
{
_configuration = configuration;
_tenantManager = tenantManager;
_localizationManager = localizationManager;
_languages = languages;
_antiforgery = antiforgery;
_sites = sites;
}
public string AntiForgeryToken = "";
@ -48,7 +50,7 @@ namespace Oqtane.Pages
Runtime = _configuration.GetSection("Runtime").Value;
}
if (Runtime != "WebAssembly" && _configuration.GetSection("RenderMode").Exists())
if (_configuration.GetSection("RenderMode").Exists())
{
RenderMode = (RenderMode)Enum.Parse(typeof(RenderMode), _configuration.GetSection("RenderMode").Value, true);
}
@ -67,6 +69,19 @@ namespace Oqtane.Pages
var alias = _tenantManager.GetAlias();
if (alias != null)
{
var site = _sites.GetSite(alias.SiteId);
if (site != null)
{
if (!string.IsNullOrEmpty(site.Runtime))
{
Runtime = site.Runtime;
}
if (!string.IsNullOrEmpty(site.RenderMode))
{
RenderMode = (RenderMode)Enum.Parse(typeof(RenderMode), site.RenderMode, true);
}
}
// if culture not specified
if (HttpContext.Request.Cookies[CookieRequestCultureProvider.DefaultCookieName] == null)
{
@ -142,7 +157,6 @@ namespace Oqtane.Pages
}
}
}
private void ProcessResource(Resource resource)
{
switch (resource.ResourceType)
@ -171,7 +185,6 @@ namespace Oqtane.Pages
break;
}
}
private string CrossOrigin(string crossorigin)
{
if (!string.IsNullOrEmpty(crossorigin))

View File

@ -163,8 +163,8 @@ namespace Oqtane
endpoints.MapFallbackToPage("/_Host");
});
// create a sync event to identify server application startup
sync.AddSyncEvent(-1, "Application", -1);
// create a global sync event to identify server application startup
sync.AddSyncEvent(-1, "Application", -1, true);
}
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<RazorLangVersion>3.0</RazorLangVersion>
<Version>1.0.0</Version>
<Authors>[Owner]</Authors>
@ -13,11 +13,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.4" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="5.0.4" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="5.0.4" />
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="6.0.0" />
<PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
</PropertyGroup>

View File

@ -20,12 +20,12 @@
</dependencies>
</metadata>
<files>
<file src="..\Client\bin\Release\net5.0\[Owner].[Module].Client.Oqtane.dll" target="lib\net5.0" />
<file src="..\Client\bin\Release\net5.0\[Owner].[Module].Client.Oqtane.pdb" target="lib\net5.0" />
<file src="..\Server\bin\Release\net5.0\[Owner].[Module].Server.Oqtane.dll" target="lib\net5.0" />
<file src="..\Server\bin\Release\net5.0\[Owner].[Module].Server.Oqtane.pdb" target="lib\net5.0" />
<file src="..\Shared\bin\Release\net5.0\[Owner].[Module].Shared.Oqtane.dll" target="lib\net5.0" />
<file src="..\Shared\bin\Release\net5.0\[Owner].[Module].Shared.Oqtane.pdb" target="lib\net5.0" />
<file src="..\Client\bin\Release\net6.0\[Owner].[Module].Client.Oqtane.dll" target="lib\net6.0" />
<file src="..\Client\bin\Release\net6.0\[Owner].[Module].Client.Oqtane.pdb" target="lib\net6.0" />
<file src="..\Server\bin\Release\net6.0\[Owner].[Module].Server.Oqtane.dll" target="lib\net6.0" />
<file src="..\Server\bin\Release\net6.0\[Owner].[Module].Server.Oqtane.pdb" target="lib\net6.0" />
<file src="..\Shared\bin\Release\net6.0\[Owner].[Module].Shared.Oqtane.dll" target="lib\net6.0" />
<file src="..\Shared\bin\Release\net6.0\[Owner].[Module].Shared.Oqtane.pdb" target="lib\net6.0" />
<file src="..\Server\wwwroot\**\*.*" target="wwwroot" />
<file src="icon.png" target="" />
</files>

View File

@ -1,7 +1,7 @@
XCOPY "..\Client\bin\Debug\net5.0\[Owner].[Module].Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net5.0\" /Y
XCOPY "..\Client\bin\Debug\net5.0\[Owner].[Module].Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net5.0\" /Y
XCOPY "..\Server\bin\Debug\net5.0\[Owner].[Module].Server.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net5.0\" /Y
XCOPY "..\Server\bin\Debug\net5.0\[Owner].[Module].Server.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net5.0\" /Y
XCOPY "..\Shared\bin\Debug\net5.0\[Owner].[Module].Shared.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net5.0\" /Y
XCOPY "..\Shared\bin\Debug\net5.0\[Owner].[Module].Shared.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net5.0\" /Y
XCOPY "..\Client\bin\Debug\net6.0\[Owner].[Module].Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net6.0\" /Y
XCOPY "..\Client\bin\Debug\net6.0\[Owner].[Module].Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net6.0\" /Y
XCOPY "..\Server\bin\Debug\net6.0\[Owner].[Module].Server.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net6.0\" /Y
XCOPY "..\Server\bin\Debug\net6.0\[Owner].[Module].Server.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net6.0\" /Y
XCOPY "..\Shared\bin\Debug\net6.0\[Owner].[Module].Shared.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net6.0\" /Y
XCOPY "..\Shared\bin\Debug\net6.0\[Owner].[Module].Shared.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net6.0\" /Y
XCOPY "..\Server\wwwroot\*" "..\..\[RootFolder]\Oqtane.Server\wwwroot\" /Y /S /I

View File

@ -1,3 +1,3 @@
"..\..\[RootFolder]\oqtane.package\nuget.exe" pack [Owner].[Module].nuspec
XCOPY "*.nupkg" "..\..\oqtane.framework\Oqtane.Server\Packages\" /Y
XCOPY "*.nupkg" "..\..\[RootFolder]\Oqtane.Server\Packages\" /Y

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<Version>1.0.0</Version>
<Product>[Owner].[Module]</Product>
@ -19,12 +19,11 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.4" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<Version>1.0.0</Version>
<Product>[Owner].[Module]</Product>
<Authors>[Owner]</Authors>
@ -12,7 +12,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="6.0.0-preview.4.21253.7" />
</ItemGroup>
<ItemGroup>

View File

@ -1,5 +1,5 @@
{
"Title": "Default Module Template",
"Type": "External",
"Version": "2.2.0"
"Version": "3.0.0"
}

View File

@ -124,6 +124,7 @@
@media (min-width: 768px) {
app {
flex-direction: row;
display: block;
}
.app-logo {

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<RazorLangVersion>3.0</RazorLangVersion>
<Version>1.0.0</Version>
<Authors>[Owner]</Authors>
@ -13,11 +13,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="5.0.0" />
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="6.0.0" />
<PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
</PropertyGroup>

View File

@ -20,8 +20,8 @@
</dependencies>
</metadata>
<files>
<file src="..\Client\bin\Release\net5.0\[Owner].[Theme].Client.Oqtane.dll" target="lib\net5.0" />
<file src="..\Client\bin\Release\net5.0\[Owner].[Theme].Client.Oqtane.pdb" target="lib\net5.0" />
<file src="..\Client\bin\Release\net6.0\[Owner].[Theme].Client.Oqtane.dll" target="lib\net6.0" />
<file src="..\Client\bin\Release\net6.0\[Owner].[Theme].Client.Oqtane.pdb" target="lib\net6.0" />
<file src="..\Client\wwwroot\**\*.*" target="wwwroot" />
<file src="icon.png" target="" />
</files>

Some files were not shown because too many files have changed in this diff Show More