9
Oqtane.Application/.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
.vs/
|
||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
*.user
|
||||||
|
artifacts/
|
||||||
|
msbuild.binlog
|
||||||
|
.vscode/
|
||||||
|
*.binlog
|
||||||
|
*.nupkg
|
@ -1,47 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net9.0</TargetFramework>
|
|
||||||
<Version>6.1.5</Version>
|
|
||||||
<AssemblyName>Oqtane.Application.AppHost</AssemblyName>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.8" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.8" />
|
|
||||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.1" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.8" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.8">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.8" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.8" />
|
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
|
|
||||||
<PackageReference Include="HtmlAgilityPack" Version="1.12.2" />
|
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3" />
|
|
||||||
<PackageReference Include="MailKit" Version="4.13.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<!-- MySQL Database Provider Dependencies -->
|
|
||||||
<PackageReference Include="MySql.Data" Version="9.4.0" />
|
|
||||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0-preview.3.efcore.9.0.0" />
|
|
||||||
<!-- PostgreSQL Database Provider Dependencies -->
|
|
||||||
<PackageReference Include="EFCore.NamingConventions" Version="9.0.0" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.8" />
|
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
|
|
||||||
<!-- SQLite Database Provider Dependencies -->
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.8" />
|
|
||||||
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="9.0.8" />
|
|
||||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.1" />
|
|
||||||
<!-- SQL Server Database Provider Dependencies -->
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.8" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Oqtane.Client" Version="6.1.5" />
|
|
||||||
<PackageReference Include="Oqtane.Server" Version="6.1.5" />
|
|
||||||
<PackageReference Include="Oqtane.Shared" Version="6.1.5" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
@ -1,29 +0,0 @@
|
|||||||
{
|
|
||||||
"iisSettings": {
|
|
||||||
"windowsAuthentication": false,
|
|
||||||
"anonymousAuthentication": true,
|
|
||||||
"iisExpress": {
|
|
||||||
"applicationUrl": "http://localhost:44358/",
|
|
||||||
"sslPort": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"profiles": {
|
|
||||||
"IIS Express": {
|
|
||||||
"commandName": "IISExpress",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Oqtane.AppHost": {
|
|
||||||
"commandName": "Project",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
},
|
|
||||||
"applicationUrl": "http://localhost:44358/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
# Oqtane Application Template
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Oqtane is an open source CMS and Application Framework that provides advanced functionality for developing web, mobile, and desktop applications on .NET. It leverages Blazor to compose a fully dynamic digital experience which can be hosted on Static Blazor, Blazor Server, Blazor WebAssembly, or Blazor Hybrid (via .NET MAUI).
|
|
||||||
|
|
||||||
More information about Oqtane can be found at: [https://www.oqtane.org](https://www.oqtane.org)
|
|
@ -1,11 +0,0 @@
|
|||||||
The _content folder should only contain static resources from shared razor component libraries (RCLs). Static resources can be extracted from shared RCL Nuget packages by executing a Publish task on the module's Server project to a local folder and copying the files from the _content folder which is created. Each shared RCL would have its own appropriately named subfolder within the module's _content folder.
|
|
||||||
|
|
||||||
ie.
|
|
||||||
|
|
||||||
/_content
|
|
||||||
/Radzen.Blazor
|
|
||||||
/css
|
|
||||||
/fonts
|
|
||||||
/syncfusion.blazor
|
|
||||||
/scripts
|
|
||||||
/styles
|
|
@ -1 +0,0 @@
|
|||||||
This is the location where static resources such as images or style sheets should be located
|
|
@ -1,27 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net9.0</TargetFramework>
|
|
||||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
|
||||||
<AccelerateBuildsInVisualStudio>false</AccelerateBuildsInVisualStudio>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="icon.png">
|
|
||||||
<Pack>True</Pack>
|
|
||||||
<PackagePath></PackagePath>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Client\Oqtane.Application.Client.csproj" />
|
|
||||||
<ProjectReference Include="..\Server\Oqtane.Application.Server.csproj" />
|
|
||||||
<ProjectReference Include="..\Shared\Oqtane.Application.Shared.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
|
||||||
<Exec Condition="'$(OS)' == 'Windows_NT' And '$(Configuration)' == 'Debug'" Command="debug.cmd $(TargetFramework) $([System.String]::Copy('$(MSBuildProjectName)').Replace('.Build',''))" />
|
|
||||||
<Exec Condition="'$(OS)' != 'Windows_NT' And '$(Configuration)' == 'Debug'" Command="bash $(ProjectDir)debug.sh $(TargetFramework) $([System.String]::Copy('$(MSBuildProjectName)').Replace('.Build',''))" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
</Project>
|
|
@ -1,32 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
|
||||||
<metadata>
|
|
||||||
<id>$projectname$</id>
|
|
||||||
<version>1.0.0</version>
|
|
||||||
<authors>Oqtane.Application</authors>
|
|
||||||
<owners>Oqtane.Application</owners>
|
|
||||||
<title>Oqtane.Application</title>
|
|
||||||
<description>Oqtane.Application</description>
|
|
||||||
<copyright>Oqtane.Application</copyright>
|
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
|
||||||
<license type="expression">MIT</license>
|
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
|
||||||
<icon>icon.png</icon>
|
|
||||||
<tags>oqtane module</tags>
|
|
||||||
<releaseNotes></releaseNotes>
|
|
||||||
<summary></summary>
|
|
||||||
<dependencies>
|
|
||||||
<dependency id="Oqtane.Framework" version="6.1.4" />
|
|
||||||
</dependencies>
|
|
||||||
</metadata>
|
|
||||||
<files>
|
|
||||||
<file src="..\Client\bin\Release\$targetframework$\$ProjectName$.Client.Oqtane.dll" target="lib\$targetframework$" />
|
|
||||||
<file src="..\Client\bin\Release\$targetframework$\$ProjectName$.Client.Oqtane.pdb" target="lib\$targetframework$" />
|
|
||||||
<file src="..\Server\bin\Release\$targetframework$\$ProjectName$.Server.Oqtane.dll" target="lib\$targetframework$" />
|
|
||||||
<file src="..\Server\bin\Release\$targetframework$\$ProjectName$.Server.Oqtane.pdb" target="lib\$targetframework$" />
|
|
||||||
<file src="..\Shared\bin\Release\$targetframework$\$ProjectName$.Shared.Oqtane.dll" target="lib\$targetframework$" />
|
|
||||||
<file src="..\Shared\bin\Release\$targetframework$\$ProjectName$.Shared.Oqtane.pdb" target="lib\$targetframework$" />
|
|
||||||
<file src="..\Server\wwwroot\**\*.*" target="wwwroot" />
|
|
||||||
<file src="icon.png" target="" />
|
|
||||||
</files>
|
|
||||||
</package>
|
|
@ -1,11 +0,0 @@
|
|||||||
@echo off
|
|
||||||
set TargetFramework=%1
|
|
||||||
set ProjectName=%2
|
|
||||||
|
|
||||||
XCOPY "..\Client\bin\Debug\%TargetFramework%\%ProjectName%.Client.Oqtane.dll" "..\AppHost\bin\Debug\%TargetFramework%\" /Y
|
|
||||||
XCOPY "..\Client\bin\Debug\%TargetFramework%\%ProjectName%.Client.Oqtane.pdb" "..\AppHost\bin\Debug\%TargetFramework%\" /Y
|
|
||||||
XCOPY "..\Server\bin\Debug\%TargetFramework%\%ProjectName%.Server.Oqtane.dll" "..\AppHost\bin\Debug\%TargetFramework%\" /Y
|
|
||||||
XCOPY "..\Server\bin\Debug\%TargetFramework%\%ProjectName%.Server.Oqtane.pdb" "..\AppHost\bin\Debug\%TargetFramework%\" /Y
|
|
||||||
XCOPY "..\Shared\bin\Debug\%TargetFramework%\%ProjectName%.Shared.Oqtane.dll" "..\AppHost\bin\Debug\%TargetFramework%\" /Y
|
|
||||||
XCOPY "..\Shared\bin\Debug\%TargetFramework%\%ProjectName%.Shared.Oqtane.pdb" "..\AppHost\bin\Debug\%TargetFramework%\" /Y
|
|
||||||
XCOPY "..\Server\wwwroot\*" "..\AppHost\wwwroot\" /Y /S /I
|
|
@ -1,12 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
TargetFramework=$1
|
|
||||||
ProjectName=$2
|
|
||||||
|
|
||||||
cp -f "../Client/bin/Debug/$TargetFramework/$ProjectName$.Client.Oqtane.dll" "../AppHost/bin/Debug/$TargetFramework/"
|
|
||||||
cp -f "../Client/bin/Debug/$TargetFramework/$ProjectName$.Client.Oqtane.pdb" "../AppHost/bin/Debug/$TargetFramework/"
|
|
||||||
cp -f "../Server/bin/Debug/$TargetFramework/$ProjectName$.Server.Oqtane.dll" "../AppHost/bin/Debug/$TargetFramework/"
|
|
||||||
cp -f "../Server/bin/Debug/$TargetFramework/$ProjectName$.Server.Oqtane.pdb" "../AppHost/bin/Debug/$TargetFramework/"
|
|
||||||
cp -f "../Shared/bin/Debug/$TargetFramework/$ProjectName$.Shared.Oqtane.dll" "../AppHost/bin/Debug/$TargetFramework/"
|
|
||||||
cp -f "../Shared/bin/Debug/$TargetFramework/$ProjectName$.Shared.Oqtane.pdb" "../AppHost/bin/Debug/$TargetFramework/"
|
|
||||||
cp -rf "../Server/wwwroot/"* "../AppHost/wwwroot/"
|
|
@ -1,2 +0,0 @@
|
|||||||
del "*.nupkg"
|
|
||||||
"nuget.exe" pack Oqtane.Application.nuspec -Properties projectname=Oqtane.Application
|
|
@ -1 +0,0 @@
|
|||||||
"nuget.exe" pack Oqtane.Application.nuspec -Properties projectname=Oqtane.Application
|
|
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
public override List<Resource> Resources => new List<Resource>()
|
public override List<Resource> Resources => new List<Resource>()
|
||||||
{
|
{
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
|
new Stylesheet(ModulePath() + "Module.css")
|
||||||
};
|
};
|
||||||
|
|
||||||
private ElementReference form;
|
private ElementReference form;
|
||||||
|
@ -38,12 +38,10 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
public override string RenderMode => RenderModes.Static;
|
|
||||||
|
|
||||||
public override List<Resource> Resources => new List<Resource>()
|
public override List<Resource> Resources => new List<Resource>()
|
||||||
{
|
{
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" },
|
new Stylesheet(ModulePath() + "Module.css"),
|
||||||
new Resource { ResourceType = ResourceType.Script, Url = ModulePath() + "Module.js" }
|
new Script(ModulePath() + "Module.js")
|
||||||
};
|
};
|
||||||
|
|
||||||
List<Models.MyModule> _MyModules;
|
List<Models.MyModule> _MyModules;
|
||||||
|
@ -1,33 +1,21 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net9.0</TargetFramework>
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
<Version>1.0.0</Version>
|
<Version>1.0.0</Version>
|
||||||
<AssemblyName>Oqtane.Application.Client.Oqtane</AssemblyName>
|
<AssemblyName>Oqtane.Application.Client.Oqtane</AssemblyName>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
|
||||||
</PropertyGroup>
|
<StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>
|
||||||
|
<BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking>
|
||||||
|
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.8" />
|
<ProjectReference Include="..\Shared\Oqtane.Application.Shared.csproj" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="9.0.8" />
|
</ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.8" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.8" />
|
|
||||||
<PackageReference Include="System.Net.Http.Json" Version="9.0.8" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Shared\Oqtane.Application.Shared.csproj" />
|
<PackageReference Include="Oqtane.Client" Version="6.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Oqtane.Client" Version="6.1.4" />
|
|
||||||
<PackageReference Include="Oqtane.Shared" Version="6.1.4" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<!-- there may be other elements here -->
|
|
||||||
<BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking>
|
|
||||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
13
Oqtane.Application/Client/Program.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Oqtane.Application.Client
|
||||||
|
{
|
||||||
|
internal class Program
|
||||||
|
{
|
||||||
|
static async Task Main(string[] args)
|
||||||
|
{
|
||||||
|
// defer client startup to Oqtane - do not modify
|
||||||
|
await Oqtane.Client.Program.Main(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System.Linq;
|
||||||
using Oqtane.Services;
|
using Oqtane.Services;
|
||||||
using Oqtane.Application.Services;
|
using Oqtane.Application.Services;
|
||||||
|
|
||||||
@ -8,7 +9,10 @@ namespace Oqtane.Application.Startup
|
|||||||
{
|
{
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddScoped<IMyModuleService, MyModuleService>();
|
if (!services.Any(s => s.ServiceType == typeof(IMyModuleService)))
|
||||||
|
{
|
||||||
|
services.AddScoped<IMyModuleService, MyModuleService>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,8 @@ namespace Oqtane.Application.MyTheme
|
|||||||
ContainerSettingsType = "Oqtane.Application.MyTheme.ContainerSettings, Oqtane.Application.Client.Oqtane",
|
ContainerSettingsType = "Oqtane.Application.MyTheme.ContainerSettings, Oqtane.Application.Client.Oqtane",
|
||||||
Resources = new List<Resource>()
|
Resources = new List<Resource>()
|
||||||
{
|
{
|
||||||
new Script(Constants.BootstrapStylesheetUrl, Constants.BootstrapStylesheetIntegrity, "anonymous"),
|
new Stylesheet(Constants.BootstrapStylesheetUrl, Constants.BootstrapStylesheetIntegrity, "anonymous"),
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "~/Theme.css" },
|
new Stylesheet("~/Theme.css"),
|
||||||
new Script(Constants.BootstrapScriptUrl, Constants.BootstrapScriptIntegrity, "anonymous")
|
new Script(Constants.BootstrapScriptUrl, Constants.BootstrapScriptIntegrity, "anonymous")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2,18 +2,18 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Application.Template</id>
|
<id>Oqtane.Application.Template</id>
|
||||||
<version>6.1.5</version>
|
<version>6.2.0</version>
|
||||||
<title>Oqtane Application Solution For Blazor</title>
|
<title>Oqtane Application Template For Blazor</title>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<licenseUrl>https://licenses.nuget.org/MIT</licenseUrl>
|
<licenseUrl>https://licenses.nuget.org/MIT</licenseUrl>
|
||||||
<icon>Build/icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<description>Oqtane is an open source CMS and Application Framework that provides advanced functionality for developing web, mobile, and desktop applications on .NET. It leverages Blazor to compose a fully dynamic digital experience which can be hosted on Static Blazor, Blazor Server, Blazor WebAssembly, or Blazor Hybrid (via .NET MAUI).</description>
|
<description>Oqtane is an open source CMS and Application Framework that provides advanced functionality for developing web, mobile, and desktop applications on .NET. It leverages Blazor to compose a fully dynamic digital experience which can be hosted on Static Blazor, Blazor Server, Blazor WebAssembly, or Blazor Hybrid (via .NET MAUI).</description>
|
||||||
<language>en-US</language>
|
<language>en-US</language>
|
||||||
<tags>Web ASP.NET Blazor Oqtane Modular Multi-Tenant "Open Source" "SQL Server" MySQL PostgreSQL SQLite</tags>
|
<tags>Web ASP.NET Blazor Oqtane Modular Multi-Tenant "Open Source" "SQL Server" MySQL PostgreSQL SQLite</tags>
|
||||||
<readme>AppHost/README.md</readme>
|
<readme>README.md</readme>
|
||||||
<packageTypes>
|
<packageTypes>
|
||||||
<packageType name="Template" />
|
<packageType name="Template" />
|
||||||
</packageTypes>
|
</packageTypes>
|
||||||
|
@ -2,47 +2,32 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.12.35506.116 d17.12
|
VisualStudioVersion = 17.12.35506.116 d17.12
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Oqtane.Application.AppHost", "AppHost\Oqtane.Application.AppHost.csproj", "{5BDDA15B-05CF-41B2-BF12-D532D1A561D1}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Oqtane.Application.Server", "Server\Oqtane.Application.Server.csproj", "{04B05448-788F-433D-92C0-FED35122D45A}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Oqtane.Application.Client", "Client\Oqtane.Application.Client.csproj", "{AA8E58A1-CD09-4208-BF66-A8BB341FD669}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Oqtane.Application.Client", "Client\Oqtane.Application.Client.csproj", "{AA8E58A1-CD09-4208-BF66-A8BB341FD669}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Oqtane.Application.Server", "Server\Oqtane.Application.Server.csproj", "{04B05448-788F-433D-92C0-FED35122D45A}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Oqtane.Application.Shared", "Shared\Oqtane.Application.Shared.csproj", "{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Oqtane.Application.Shared", "Shared\Oqtane.Application.Shared.csproj", "{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Oqtane.Application.Build", "Build\Oqtane.Application.Build.csproj", "{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{5BDDA15B-05CF-41B2-BF12-D532D1A561D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{5BDDA15B-05CF-41B2-BF12-D532D1A561D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{5BDDA15B-05CF-41B2-BF12-D532D1A561D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{5BDDA15B-05CF-41B2-BF12-D532D1A561D1}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{04B05448-788F-433D-92C0-FED35122D45A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{04B05448-788F-433D-92C0-FED35122D45A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{04B05448-788F-433D-92C0-FED35122D45A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{04B05448-788F-433D-92C0-FED35122D45A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{04B05448-788F-433D-92C0-FED35122D45A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{04B05448-788F-433D-92C0-FED35122D45A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{04B05448-788F-433D-92C0-FED35122D45A}.Release|Any CPU.Build.0 = Release|Any CPU
|
{04B05448-788F-433D-92C0-FED35122D45A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Release|Any CPU.Build.0 = Release|Any CPU
|
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
SolutionGuid = {1D016F15-46FE-4726-8DFD-2E4FD4DC7668}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Oqtane Application Template
|
# Oqtane Application Template
|
||||||
|
|
||||||
This folder contains content files for a Visual Studio Project Template designed for Oqtane development projects. The template relies on the native templating capabilities of the .NET Command Line Interface (CLI):
|
This is a Visual Studio Project Template designed for Oqtane development projects. This template relies on the native templating capabilities of the .NET Command Line Interface (CLI):
|
||||||
|
|
||||||
```
|
```
|
||||||
dotnet new install Oqtane.Application.Template
|
dotnet new install Oqtane.Application.Template
|
||||||
@ -16,5 +16,4 @@ The solution also contains Build, Client, Server, and Shared folders which is wh
|
|||||||
*Known Issues*
|
*Known Issues*
|
||||||
|
|
||||||
- do not use the term "Oqtane" in your output name or else you will experience namespace conflicts
|
- do not use the term "Oqtane" in your output name or else you will experience namespace conflicts
|
||||||
- the application's Build project is missing the *.nuspec file as Nuget is excluding it from the template - not sure why
|
|
||||||
- when calling "dotnet new" the PostBuild section in the Oqtane.Application.Build.csproj is being modified incorrectly - not sure why
|
|
||||||
|
@ -1,36 +1,18 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net9.0</TargetFramework>
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
|
<Version>1.0.0</Version>
|
||||||
<Version>1.0.0</Version>
|
<AssemblyName>Oqtane.Application.Server.Oqtane</AssemblyName>
|
||||||
<AssemblyName>Oqtane.Application.Server.Oqtane</AssemblyName>
|
</PropertyGroup>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Remove="wwwroot\_content\**\*.*" />
|
<ProjectReference Include="..\Client\Oqtane.Application.Client.csproj" />
|
||||||
<None Include="wwwroot\_content\**\*.*" />
|
<ProjectReference Include="..\Shared\Oqtane.Application.Shared.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.8" />
|
<PackageReference Include="Oqtane.Server" Version="6.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.8" />
|
</ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.8" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.8" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Client\Oqtane.Application.Client.csproj" />
|
|
||||||
<ProjectReference Include="..\Shared\Oqtane.Application.Shared.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Oqtane.Server" Version="6.1.4" />
|
|
||||||
<PackageReference Include="Oqtane.Shared" Version="6.1.4" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="wwwroot\Themes\Oqtane.Application.MyTheme\" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.AspNetCore;
|
using Microsoft.AspNetCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Oqtane.Infrastructure;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Oqtane.Infrastructure;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Oqtane.Application.AppHost
|
namespace Oqtane.Application.Server
|
||||||
{
|
{
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
// defer server startup to Oqtane - do not modify
|
||||||
var host = BuildWebHost(args);
|
var host = BuildWebHost(args);
|
||||||
var databaseManager = host.Services.GetService<IDatabaseManager>();
|
var databaseManager = host.Services.GetService<IDatabaseManager>();
|
||||||
var install = databaseManager.Install();
|
var install = databaseManager.Install();
|
||||||
@ -20,7 +20,7 @@ namespace Oqtane.Application.AppHost
|
|||||||
var filelogger = host.Services.GetRequiredService<ILogger<Program>>();
|
var filelogger = host.Services.GetRequiredService<ILogger<Program>>();
|
||||||
if (filelogger != null)
|
if (filelogger != null)
|
||||||
{
|
{
|
||||||
filelogger.LogError($"[Oqtane.Application.AppHost.Program.Main] {install.Message}");
|
filelogger.LogError($"[Oqtane.Application.Server.Program.Main] {install.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -35,9 +35,8 @@ namespace Oqtane.Application.AppHost
|
|||||||
.AddCommandLine(args)
|
.AddCommandLine(args)
|
||||||
.AddEnvironmentVariables()
|
.AddEnvironmentVariables()
|
||||||
.Build())
|
.Build())
|
||||||
.UseStartup<Oqtane.Startup>()
|
.UseStartup<Startup>()
|
||||||
.ConfigureLocalizationSettings()
|
.ConfigureLocalizationSettings()
|
||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
25
Oqtane.Application/Server/Properties/launchSettings.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
|
||||||
|
"applicationUrl": "http://localhost:5000",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
|
||||||
|
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
45
Oqtane.Application/Server/Startup.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Oqtane.Extensions;
|
||||||
|
using Oqtane.Infrastructure;
|
||||||
|
using Oqtane.Shared;
|
||||||
|
using Microsoft.AspNetCore.Cors.Infrastructure;
|
||||||
|
|
||||||
|
namespace Oqtane.Application.Server
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
private readonly IConfigurationRoot _configuration;
|
||||||
|
private readonly IWebHostEnvironment _environment;
|
||||||
|
|
||||||
|
public Startup(IWebHostEnvironment environment)
|
||||||
|
{
|
||||||
|
AppDomain.CurrentDomain.SetData(Constants.DataDirectory, Path.Combine(environment.ContentRootPath, "Data"));
|
||||||
|
|
||||||
|
var builder = new ConfigurationBuilder()
|
||||||
|
.SetBasePath(environment.ContentRootPath)
|
||||||
|
.AddJsonFile("appsettings.json", false, true)
|
||||||
|
.AddJsonFile($"appsettings.{environment.EnvironmentName}.json", true, true)
|
||||||
|
.AddEnvironmentVariables();
|
||||||
|
|
||||||
|
_configuration = builder.Build();
|
||||||
|
_environment = environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
// defer server startup to Oqtane - do not modify
|
||||||
|
services.AddOqtane(_configuration, _environment);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Configure(IApplicationBuilder app, IConfigurationRoot configuration, IWebHostEnvironment environment, ICorsService corsService, ICorsPolicyProvider corsPolicyProvider, ISyncManager sync)
|
||||||
|
{
|
||||||
|
// defer server startup to Oqtane - do not modify
|
||||||
|
app.UseOqtane(configuration, environment, corsService, corsPolicyProvider, sync);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"RenderMode": "Interactive",
|
"RenderMode": "Static",
|
||||||
"Runtime": "Server",
|
"Runtime": "Server",
|
||||||
"Database": {
|
"Database": {
|
||||||
"DefaultDBType": "Oqtane.Database.SqlServer.SqlServerDatabase, Oqtane.Server"
|
"DefaultDBType": ""
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnection": ""
|
"DefaultConnection": ""
|
||||||
@ -57,8 +57,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Information",
|
"Default": "Information"
|
||||||
"Notify": "Error"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,11 +0,0 @@
|
|||||||
The _content folder should only contain static resources from shared razor component libraries (RCLs). Static resources can be extracted from shared RCL Nuget packages by executing a Publish task on the module's Server project to a local folder and copying the files from the _content folder which is created. Each shared RCL would have its own appropriately named subfolder within the module's _content folder.
|
|
||||||
|
|
||||||
ie.
|
|
||||||
|
|
||||||
/_content
|
|
||||||
/Radzen.Blazor
|
|
||||||
/css
|
|
||||||
/fonts
|
|
||||||
/syncfusion.blazor
|
|
||||||
/scripts
|
|
||||||
/styles
|
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
@ -0,0 +1,22 @@
|
|||||||
|
.rz-text-editor {
|
||||||
|
outline: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rz-html-editor-dropdown-items,
|
||||||
|
.rz-popup,
|
||||||
|
.rz-editor-dialog-wrapper {
|
||||||
|
z-index: 9999 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rz-html-editor-dropdown-items .rz-html-editor-dropdown-item,
|
||||||
|
.rz-html-editor-dropdown-items .rz-html-editor-dropdown-item > * {
|
||||||
|
color: var(--rz-editor-button-color);
|
||||||
|
}
|
||||||
|
.rz-text-editor .rz-html-editor-dropdown .rz-html-editor-dropdown-value,
|
||||||
|
.rz-text-editor .rz-html-editor-dropdown .rz-html-editor-dropdown-trigger,
|
||||||
|
.rz-text-editor .rz-html-editor-colorpicker .rz-html-editor-color {
|
||||||
|
color: var(--rz-editor-button-color);
|
||||||
|
}
|
||||||
|
.rz-text-editor .rz-colorpicker.rz-state-disabled {
|
||||||
|
border: none !important;
|
||||||
|
}
|
Before Width: | Height: | Size: 318 B After Width: | Height: | Size: 318 B |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 427 B |
Before Width: | Height: | Size: 875 B After Width: | Height: | Size: 875 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 801 B After Width: | Height: | Size: 801 B |
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 177 B After Width: | Height: | Size: 177 B |
Before Width: | Height: | Size: 438 B After Width: | Height: | Size: 438 B |
@ -0,0 +1,47 @@
|
|||||||
|
var Oqtane = Oqtane || {};
|
||||||
|
|
||||||
|
Oqtane.RadzenTextEditor = {
|
||||||
|
initialize: function (editor) {
|
||||||
|
if (typeof Radzen.openPopup === "function" && Radzen.openPopup !== Oqtane.RadzenTextEditor.openPopup) {
|
||||||
|
Oqtane.RadzenTextEditor.radzenOpenPopup = Radzen.openPopup;
|
||||||
|
Radzen.openPopup = Oqtane.RadzenTextEditor.openPopup;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openPopup: function () {
|
||||||
|
Oqtane.RadzenTextEditor.radzenOpenPopup.apply(this, arguments);
|
||||||
|
var id = arguments[1];
|
||||||
|
var popup = document.getElementById(id);
|
||||||
|
if (popup) {
|
||||||
|
Oqtane.RadzenTextEditor.updateButtonStyles(popup);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setBackgroundColor: function (editor, color) {
|
||||||
|
editor.getElementsByClassName("rz-html-editor-content")[0].style.backgroundColor = color;
|
||||||
|
},
|
||||||
|
updateDialogLayout: function (editor) {
|
||||||
|
var dialogs = editor.parentElement.getElementsByClassName('rz-dialog-wrapper');
|
||||||
|
for (var dialog of dialogs) {
|
||||||
|
document.body.appendChild(dialog);
|
||||||
|
dialog.classList.add('rz-editor-dialog-wrapper', 'text-dark');
|
||||||
|
|
||||||
|
this.updateButtonStyles(dialog);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateButtonStyles: function (parent) {
|
||||||
|
var primaryBtns = parent.getElementsByClassName('rz-primary');
|
||||||
|
if (primaryBtns) {
|
||||||
|
for (var btn of primaryBtns) {
|
||||||
|
btn.classList.remove('rz-button', 'rz-primary');
|
||||||
|
btn.classList.add('btn', 'btn-primary');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var secondaryBtns = parent.getElementsByClassName('rz-secondary');
|
||||||
|
if (secondaryBtns) {
|
||||||
|
for (var btn of secondaryBtns) {
|
||||||
|
btn.classList.remove('rz-button', 'rz-secondary');
|
||||||
|
btn.classList.add('btn', 'btn-secondary');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
@ -1,17 +1,13 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net9.0</TargetFramework>
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
<Version>1.0.0</Version>
|
<Version>1.0.0</Version>
|
||||||
<AssemblyName>Oqtane.Application.Shared.Oqtane</AssemblyName>
|
<AssemblyName>Oqtane.Application.Shared.Oqtane</AssemblyName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
<PackageReference Include="Oqtane.Shared" Version="6.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Oqtane.Shared" Version="6.1.4" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
BIN
Oqtane.Application/icon.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
@ -1,8 +1,10 @@
|
|||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
using Oqtane.Interfaces;
|
using Oqtane.Interfaces;
|
||||||
using Oqtane.Providers;
|
using Oqtane.Providers;
|
||||||
using Oqtane.Services;
|
using Oqtane.Services;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
|
using Radzen;
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyInjection
|
namespace Microsoft.Extensions.DependencyInjection
|
||||||
{
|
{
|
||||||
@ -23,7 +25,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||||||
services.AddScoped<SiteState>();
|
services.AddScoped<SiteState>();
|
||||||
services.AddScoped<IInstallationService, InstallationService>();
|
services.AddScoped<IInstallationService, InstallationService>();
|
||||||
services.AddScoped<IModuleDefinitionService, ModuleDefinitionService>();
|
services.AddScoped<IModuleDefinitionService, ModuleDefinitionService>();
|
||||||
services.AddScoped<IThemeService, ThemeService>();
|
services.AddScoped<IThemeService, Oqtane.Services.ThemeService>();
|
||||||
services.AddScoped<IAliasService, AliasService>();
|
services.AddScoped<IAliasService, AliasService>();
|
||||||
services.AddScoped<ITenantService, TenantService>();
|
services.AddScoped<ITenantService, TenantService>();
|
||||||
services.AddScoped<ISiteService, SiteService>();
|
services.AddScoped<ISiteService, SiteService>();
|
||||||
@ -39,7 +41,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||||||
services.AddScoped<ILogService, LogService>();
|
services.AddScoped<ILogService, LogService>();
|
||||||
services.AddScoped<IJobService, JobService>();
|
services.AddScoped<IJobService, JobService>();
|
||||||
services.AddScoped<IJobLogService, JobLogService>();
|
services.AddScoped<IJobLogService, JobLogService>();
|
||||||
services.AddScoped<INotificationService, NotificationService>();
|
services.AddScoped<INotificationService, Oqtane.Services.NotificationService>();
|
||||||
services.AddScoped<IFolderService, FolderService>();
|
services.AddScoped<IFolderService, FolderService>();
|
||||||
services.AddScoped<IFileService, FileService>();
|
services.AddScoped<IFileService, FileService>();
|
||||||
services.AddScoped<ISiteTemplateService, SiteTemplateService>();
|
services.AddScoped<ISiteTemplateService, SiteTemplateService>();
|
||||||
@ -59,6 +61,12 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||||||
// providers
|
// providers
|
||||||
services.AddScoped<ITextEditor, Oqtane.Modules.Controls.QuillJSTextEditor>();
|
services.AddScoped<ITextEditor, Oqtane.Modules.Controls.QuillJSTextEditor>();
|
||||||
services.AddScoped<ITextEditor, Oqtane.Modules.Controls.TextAreaTextEditor>();
|
services.AddScoped<ITextEditor, Oqtane.Modules.Controls.TextAreaTextEditor>();
|
||||||
|
services.AddScoped<ITextEditor, Oqtane.Modules.Controls.RadzenTextEditor>();
|
||||||
|
|
||||||
|
services.AddRadzenComponents();
|
||||||
|
|
||||||
|
var localizer = services.BuildServiceProvider().GetService<IStringLocalizer<Oqtane.Modules.Controls.RadzenTextEditor>>();
|
||||||
|
Oqtane.Modules.Controls.RadzenEditorDefinitions.Localizer = localizer;
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="mx-auto text-center">
|
<div class="mx-auto text-center">
|
||||||
<img src="oqtane-black.png" />
|
<img src="installer-logo.png" />
|
||||||
<div style="font-weight: bold">@SharedLocalizer["Version"] @Constants.Version (.NET @Environment.Version.Major)</div>
|
<div style="font-weight: bold">@SharedLocalizer["Version"] @Constants.Version (.NET @Environment.Version.Major)</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -182,7 +182,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_databaseName = "LocalDB";
|
_databaseName = Constants.DefaultDBName;
|
||||||
}
|
}
|
||||||
LoadDatabaseConfigComponent();
|
LoadDatabaseConfigComponent();
|
||||||
|
|
||||||
@ -269,8 +269,8 @@
|
|||||||
SiteName = Constants.DefaultSite,
|
SiteName = Constants.DefaultSite,
|
||||||
Register = _register,
|
Register = _register,
|
||||||
SiteTemplate = _template,
|
SiteTemplate = _template,
|
||||||
RenderMode = RenderModes.Static,
|
RenderMode = "", // provided by appsettings.json
|
||||||
Runtime = Runtimes.Server
|
Runtime = "" // provided by appsettings.json
|
||||||
};
|
};
|
||||||
|
|
||||||
var installation = await InstallationService.Install(config);
|
var installation = await InstallationService.Install(config);
|
||||||
|
@ -116,11 +116,19 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await JobService.StartJobAsync(jobId);
|
Job _job = await JobService.GetJobAsync(jobId);
|
||||||
await logger.LogInformation("Job Started {JobId}", jobId);
|
if (!_job.IsEnabled)
|
||||||
AddModuleMessage(Localizer["Message.Job.Start"], MessageType.Success);
|
{
|
||||||
_jobs = await JobService.GetJobsAsync();
|
AddModuleMessage(Localizer["Message.Job.Disabled"], MessageType.Warning);
|
||||||
StateHasChanged();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await JobService.StartJobAsync(jobId);
|
||||||
|
await logger.LogInformation("Job Started {JobId}", jobId);
|
||||||
|
AddModuleMessage(Localizer["Message.Job.Start"], MessageType.Success);
|
||||||
|
_jobs = await JobService.GetJobsAsync();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -310,6 +310,6 @@
|
|||||||
|
|
||||||
private void OnUpload()
|
private void OnUpload()
|
||||||
{
|
{
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Module.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Module.Upload"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="options" HelpText="A comma delimited list of options the user can select from" ResourceKey="Options">Options: </Label>
|
<Label Class="col-sm-3" For="options" HelpText="A comma delimited list of options. Options can contain a key and value if they are seperated by a colon (ie. key:value). You can also dynamically load your options from custom Settings (ie. 'EntityName:Countries')." ResourceKey="Options">Options: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="options" class="form-control" @bind="@_options" maxlength="2000" />
|
<input id="options" class="form-control" @bind="@_options" maxlength="2000" />
|
||||||
</div>
|
</div>
|
||||||
|
226
Oqtane.Client/Modules/Admin/Settings/Add.razor
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
@namespace Oqtane.Modules.Admin.Settings
|
||||||
|
@inherits ModuleBase
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
@inject ISettingService SettingService
|
||||||
|
@inject IStringLocalizer<Edit> Localizer
|
||||||
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="entityName" HelpText="Entity Name" ResourceKey="EntityName">Entity:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<div class="input-group">
|
||||||
|
@if (_entityNameElement == "input")
|
||||||
|
{
|
||||||
|
<input id="entityName" class="form-control" @bind="@_entityName" maxlength="256" required />
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<select class="form-select custom-select" value="@_entityName" @onchange="(e => EntityNameChanged(e))">
|
||||||
|
<option value="-"><@Localizer["Select Entity"]></option>
|
||||||
|
@foreach (var entityName in _entityNames)
|
||||||
|
{
|
||||||
|
<option value="@entityName">@entityName</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
}
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="@EntityNameClicked" tabindex="-1">@_entityNameTitle</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="entityId" HelpText="Entity Id" ResourceKey="EntityId">Id:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<div class="input-group">
|
||||||
|
@if (_entityIdElement == "input")
|
||||||
|
{
|
||||||
|
<input id="entityId" class="form-control" @bind="@_entityId" maxlength="256" required />
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<select class="form-select custom-select" @bind="@_entityId">
|
||||||
|
<option value="-"><@Localizer["Select Id"]></option>
|
||||||
|
@foreach (var entityId in _entityIds)
|
||||||
|
{
|
||||||
|
<option value="@entityId">@entityId</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
}
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="@EntityIdClicked" tabindex="-1">@_entityIdTitle</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="settingName" HelpText="Setting Name" ResourceKey="SettingName">Name:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="settingName" class="form-control" @bind="@_settingName" maxlength="256" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="settingValue" HelpText="Setting Value" ResourceKey="SettingValue">Value:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="SettingValue" class="form-control" @bind="@_settingValue" maxlength="256" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="isPrivate" HelpText="Private" ResourceKey="IsPrivate">Private?</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="isPrivate" class="form-select" @bind="@_isPrivate">
|
||||||
|
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||||
|
<option value="False">@SharedLocalizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br /><br />
|
||||||
|
<button type="button" class="btn btn-success" @onclick="SaveSetting">@SharedLocalizer["Save"]</button>
|
||||||
|
<NavLink class="btn btn-secondary" href="@PageState.ReturnUrl">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private ElementReference form;
|
||||||
|
private bool validated = false;
|
||||||
|
|
||||||
|
private string _entityName = "-";
|
||||||
|
private List<string> _entityNames = new List<string>();
|
||||||
|
private string _entityNameElement = "select";
|
||||||
|
private string _entityNameTitle = "";
|
||||||
|
private string _entityId = "-";
|
||||||
|
private List<int> _entityIds = new List<int>();
|
||||||
|
private string _entityIdElement = "select";
|
||||||
|
private string _entityIdTitle = "";
|
||||||
|
private string _settingName = "";
|
||||||
|
private string _settingValue = "";
|
||||||
|
private string _isPrivate = "True";
|
||||||
|
|
||||||
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_entityNameTitle = Localizer["Input"];
|
||||||
|
_entityIdTitle = Localizer["Input"];
|
||||||
|
|
||||||
|
// default entity names
|
||||||
|
_entityNames.Add(EntityNames.Host);
|
||||||
|
_entityNames.Add(EntityNames.Job);
|
||||||
|
_entityNames.Add(EntityNames.ModuleDefinition);
|
||||||
|
_entityNames.Add(EntityNames.Theme);
|
||||||
|
_entityNames.Add(EntityNames.Tenant);
|
||||||
|
_entityNames.Add(EntityNames.Site);
|
||||||
|
_entityNames.Add(EntityNames.Role);
|
||||||
|
_entityNames.Add(EntityNames.Page);
|
||||||
|
_entityNames.Add(EntityNames.Module);
|
||||||
|
_entityNames.Add(EntityNames.Folder);
|
||||||
|
_entityNames.Add(EntityNames.User);
|
||||||
|
_entityNames.Add(EntityNames.Visitor);
|
||||||
|
|
||||||
|
// custom entity names
|
||||||
|
var entityNames = await SettingService.GetEntityNamesAsync();
|
||||||
|
foreach (var entityName in entityNames)
|
||||||
|
{
|
||||||
|
if (!_entityNames.Contains(entityName))
|
||||||
|
{
|
||||||
|
_entityNames.Add(entityName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Loading Setting {Error}", ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.LoadSetting"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EntityNameClicked()
|
||||||
|
{
|
||||||
|
if (_entityNameElement == "select")
|
||||||
|
{
|
||||||
|
_entityName = "";
|
||||||
|
_entityNameElement = "input";
|
||||||
|
_entityNameTitle = Localizer["Select"];
|
||||||
|
_entityId = "";
|
||||||
|
_entityIdElement = "input";
|
||||||
|
_entityIdTitle = Localizer["Select"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_entityName = "-";
|
||||||
|
_entityNameElement = "select";
|
||||||
|
_entityNameTitle = Localizer["Input"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EntityIdClicked()
|
||||||
|
{
|
||||||
|
if (_entityIdElement == "select")
|
||||||
|
{
|
||||||
|
_entityId = "";
|
||||||
|
_entityIdElement = "input";
|
||||||
|
_entityIdTitle = Localizer["Select"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_entityId = "-";
|
||||||
|
_entityIdElement = "select";
|
||||||
|
_entityIdTitle = Localizer["Input"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void EntityNameChanged(ChangeEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_entityName = e.Value.ToString();
|
||||||
|
_entityId = "-";
|
||||||
|
_entityIdElement = "select";
|
||||||
|
_entityIdTitle = Localizer["Input"];
|
||||||
|
if (_entityName != "-")
|
||||||
|
{
|
||||||
|
_entityIds = await SettingService.GetEntityIdsAsync(_entityName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_entityIds = new List<int>();
|
||||||
|
}
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error On EntityNameChanged");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SaveSetting()
|
||||||
|
{
|
||||||
|
validated = true;
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
if (await interop.FormValid(form) && _entityName != "-" && int.TryParse(_entityId, out int entityId))
|
||||||
|
{
|
||||||
|
var setting = new Setting();
|
||||||
|
setting.EntityName = _entityName;
|
||||||
|
setting.EntityId = entityId;
|
||||||
|
setting.SettingName = _settingName;
|
||||||
|
setting.SettingValue = _settingValue;
|
||||||
|
setting.IsPrivate = (bool.Parse(_isPrivate));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
setting = await SettingService.AddSettingAsync(setting);
|
||||||
|
await logger.LogInformation("Setting Saved {Setting}", setting);
|
||||||
|
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Saving Setting {Setting} {Error}", setting, ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.SaveSetting"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
122
Oqtane.Client/Modules/Admin/Settings/Edit.razor
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
@namespace Oqtane.Modules.Admin.Settings
|
||||||
|
@inherits ModuleBase
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
@inject ISettingService SettingService
|
||||||
|
@inject IStringLocalizer<Edit> Localizer
|
||||||
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="entityName" HelpText="Entity Name" ResourceKey="EntityName">Entity:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="entityName" class="form-control" @bind="@_entityName" maxlength="256" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="entityId" HelpText="Entity Id" ResourceKey="EntityId">Id:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="entityId" class="form-control" @bind="@_entityId" maxlength="256" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="settingName" HelpText="Setting Name" ResourceKey="SettingName">Name:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="settingName" class="form-control" @bind="@_settingName" maxlength="256" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="settingValue" HelpText="Setting Value" ResourceKey="SettingValue">Value:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="SettingValue" class="form-control" @bind="@_settingValue" maxlength="256" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="isPrivate" HelpText="Private" ResourceKey="IsPrivate">Private?</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="isPrivate" class="form-select" @bind="@_isPrivate">
|
||||||
|
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||||
|
<option value="False">@SharedLocalizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br /><br />
|
||||||
|
<button type="button" class="btn btn-success" @onclick="SaveSetting">@SharedLocalizer["Save"]</button>
|
||||||
|
<NavLink class="btn btn-secondary" href="@PageState.ReturnUrl">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
<br /><br />
|
||||||
|
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private ElementReference form;
|
||||||
|
private bool validated = false;
|
||||||
|
|
||||||
|
private int _settingId;
|
||||||
|
private string _entityName;
|
||||||
|
private string _entityId;
|
||||||
|
private string _settingName;
|
||||||
|
private string _settingValue;
|
||||||
|
private string _isPrivate;
|
||||||
|
private string _createdby;
|
||||||
|
private DateTime _createdon;
|
||||||
|
private string _modifiedby;
|
||||||
|
private DateTime _modifiedon;
|
||||||
|
|
||||||
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
_settingId = int.Parse(PageState.QueryString["id"]);
|
||||||
|
_entityName = PageState.QueryString["entity"];
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var setting = await SettingService.GetSettingAsync(_entityName, _settingId);
|
||||||
|
if (setting != null)
|
||||||
|
{
|
||||||
|
_entityId = setting.EntityId.ToString();
|
||||||
|
_settingName = setting.SettingName;
|
||||||
|
_settingValue = setting.SettingValue;
|
||||||
|
_isPrivate = setting.IsPrivate.ToString();
|
||||||
|
_createdby = setting.CreatedBy;
|
||||||
|
_createdon = setting.CreatedOn;
|
||||||
|
_modifiedby = setting.ModifiedBy;
|
||||||
|
_modifiedon = setting.ModifiedOn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Loading Setting {SettingId} {Error}", _settingId, ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.LoadSetting"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SaveSetting()
|
||||||
|
{
|
||||||
|
validated = true;
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
if (await interop.FormValid(form))
|
||||||
|
{
|
||||||
|
var setting = await SettingService.GetSettingAsync(_entityName, _settingId);
|
||||||
|
setting.SettingValue = _settingValue;
|
||||||
|
setting.IsPrivate = (_isPrivate != null && Boolean.Parse(_isPrivate));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
setting = await SettingService.UpdateSettingAsync(setting);
|
||||||
|
await logger.LogInformation("Setting Saved {Setting}", setting);
|
||||||
|
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Saving Setting {Setting} {Error}", setting, ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.SaveSetting"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
Oqtane.Client/Modules/Admin/Settings/ImportSettings.razor
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
@namespace Oqtane.Modules.Admin.Settings
|
||||||
|
@inherits ModuleBase
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
@inject ISettingService SettingService
|
||||||
|
@inject IStringLocalizer<ImportSettings> Localizer
|
||||||
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="settings" HelpText="Provide settings in comma delimited format using the column template specified" ResourceKey="Settings">Settings:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="settings" class="form-control" @bind="@_settings" rows="5" required></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<button type="button" class="btn btn-success" @onclick="Import">@Localizer["Import"]</button>
|
||||||
|
<NavLink class="btn btn-secondary" href="@PageState.ReturnUrl">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private string _settings = "Entity,Id,Name,Value,Private\n";
|
||||||
|
|
||||||
|
public override string Title => "Import Settings";
|
||||||
|
|
||||||
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
|
private async Task Import()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_settings))
|
||||||
|
{
|
||||||
|
ShowProgressIndicator();
|
||||||
|
var result = await SettingService.ImportSettingsAsync(new Result { Message = _settings });
|
||||||
|
if (result.Success)
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.Import.Success"], MessageType.Success);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.Import.Failure"], MessageType.Error);
|
||||||
|
}
|
||||||
|
HideProgressIndicator();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.Import.Validation"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Importing Settings {Error}", ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.Import"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
146
Oqtane.Client/Modules/Admin/Settings/Index.razor
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
@namespace Oqtane.Modules.Admin.Settings
|
||||||
|
@inherits ModuleBase
|
||||||
|
@inject ISettingService SettingService
|
||||||
|
@inject IStringLocalizer<Index> Localizer
|
||||||
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<ActionLink Action="Add" Text="Add Setting" Security="SecurityAccessLevel.Host" ResourceKey="AddSetting" ReturnUrl="@(NavigateUrl(PageState.Page.Path, AddUrlParameters(_entityName, _entityId)))" />
|
||||||
|
<ActionLink Action="ImportSettings" Text="Import" Class="btn btn-secondary ms-1" Security="SecurityAccessLevel.Host" ResourceKey="ImportSettings" ReturnUrl="@(NavigateUrl(PageState.Page.Path, AddUrlParameters(_entityName, _entityId)))" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<select class="form-select custom-select" value="@_entityName" @onchange="(e => EntityNameChanged(e))">
|
||||||
|
<option value="-"><@Localizer["Select Entity"]></option>
|
||||||
|
@foreach (var entityName in _entityNames)
|
||||||
|
{
|
||||||
|
<option value="@entityName">@entityName</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<select class="form-select custom-select" value="@_entityId" @onchange="(e => EntityIdChanged(e))">
|
||||||
|
<option value="-"><@Localizer["Select Id"]></option>
|
||||||
|
@foreach (var entityId in _entityIds)
|
||||||
|
{
|
||||||
|
<option value="@entityId">@entityId</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<Pager Items="@_settings" SearchProperties="SettingName,SettingValue">
|
||||||
|
<Header>
|
||||||
|
<th style="width: 1px;"> </th>
|
||||||
|
<th style="width: 1px;"> </th>
|
||||||
|
<th>@Localizer["Name"]</th>
|
||||||
|
<th>@Localizer["Value"]</th>
|
||||||
|
</Header>
|
||||||
|
<Row>
|
||||||
|
<td><ActionLink Action="Edit" Text="Edit" Parameters="@($"entity={context.EntityName}&id={context.SettingId}")" Security="SecurityAccessLevel.Host" ResourceKey="EditSetting" ReturnUrl="@(NavigateUrl(PageState.Page.Path, AddUrlParameters(_entityName, _entityId)))" /></td>
|
||||||
|
<td><ActionDialog Header="Delete Setting" Message="@string.Format(Localizer["Confirm.DeleteSetting"], context.SettingName)" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteSetting(context))" ResourceKey="DeleteSetting" /></td>
|
||||||
|
<td>@context.SettingName</td>
|
||||||
|
<td>@context.SettingValue</td>
|
||||||
|
</Row>
|
||||||
|
</Pager>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private string _entityName = "-";
|
||||||
|
private List<string> _entityNames = new List<string>();
|
||||||
|
private string _entityId = "-";
|
||||||
|
private List<int> _entityIds = new List<int>();
|
||||||
|
private List<Setting> _settings = new List<Setting>();
|
||||||
|
|
||||||
|
public override string UrlParametersTemplate => "/{entityname}/{entityid}";
|
||||||
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
|
protected override async Task OnParametersSetAsync()
|
||||||
|
{
|
||||||
|
_entityNames = await SettingService.GetEntityNamesAsync();
|
||||||
|
|
||||||
|
if (UrlParameters.ContainsKey("entityname"))
|
||||||
|
{
|
||||||
|
_entityName = UrlParameters["entityname"];
|
||||||
|
await GetEntityIds();
|
||||||
|
}
|
||||||
|
if (UrlParameters.ContainsKey("entityid"))
|
||||||
|
{
|
||||||
|
_entityId = UrlParameters["entityid"];
|
||||||
|
await GetSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task GetEntityIds()
|
||||||
|
{
|
||||||
|
if (_entityName != "-")
|
||||||
|
{
|
||||||
|
_entityIds = await SettingService.GetEntityIdsAsync(_entityName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_entityIds = new List<int>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task GetSettings()
|
||||||
|
{
|
||||||
|
if (_entityName != "-" && _entityId != "-")
|
||||||
|
{
|
||||||
|
_settings = await SettingService.GetSettingsAsync(_entityName, int.Parse(_entityId), "");
|
||||||
|
_settings = _settings.OrderBy(item => item.SettingName).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_settings = new List<Setting>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void EntityNameChanged(ChangeEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_entityName = e.Value.ToString();
|
||||||
|
_entityId = "-";
|
||||||
|
await GetEntityIds();
|
||||||
|
await GetSettings();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error On EntityNameChanged");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void EntityIdChanged(ChangeEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_entityId = e.Value.ToString();
|
||||||
|
await GetSettings();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error On EntityIdChanged");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DeleteSetting(Setting setting)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await SettingService.DeleteSettingAsync(setting.EntityName, setting.EntityId, setting.SettingName);
|
||||||
|
await logger.LogInformation("Setting Deleted {Setting}", setting);
|
||||||
|
await GetSettings();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Deleting Setting {Setting} {Error}", setting, ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.DeleteSetting"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -54,15 +54,18 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
<Label Class="col-sm-3" For="isDeleted" HelpText="Is this site deleted?" ResourceKey="IsDeleted">Deleted? </Label>
|
{
|
||||||
<div class="col-sm-9">
|
<div class="row mb-1 align-items-center">
|
||||||
<select id="isDeleted" class="form-select" @bind="@_isdeleted" required>
|
<Label Class="col-sm-3" For="isDeleted" HelpText="Is this site deleted?" ResourceKey="IsDeleted">Deleted? </Label>
|
||||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
<div class="col-sm-9">
|
||||||
<option value="False">@SharedLocalizer["No"]</option>
|
<select id="isDeleted" class="form-select" @bind="@_isdeleted" required>
|
||||||
</select>
|
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||||
|
<option value="False">@SharedLocalizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="sitemap" HelpText="The site map url for this site which can be submitted to search engines for indexing. The sitemap is cached for 5 minutes and the cache can be manually cleared." ResourceKey="SiteMap">Site Map: </Label>
|
<Label Class="col-sm-3" For="sitemap" HelpText="The site map url for this site which can be submitted to search engines for indexing. The sitemap is cached for 5 minutes and the cache can be manually cleared." ResourceKey="SiteMap">Site Map: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -224,11 +227,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="smtpssl" HelpText="Specify if SSL is required for your SMTP server" ResourceKey="SmtpSSL">SSL Required: </Label>
|
<Label Class="col-sm-3" For="smtpssl" HelpText="Specify the type of SSL connection for your SMTP server" ResourceKey="SmtpSSL">SSL Options: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="smtpssl" class="form-select" @bind="@_smtpssl" >
|
<select id="smtpssl" class="form-select" @bind="@_smtpssl">
|
||||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
<option value="None">@Localizer["None"]</option>
|
||||||
<option value="False">@SharedLocalizer["No"]</option>
|
<option value="Auto">@Localizer["Auto"]</option>
|
||||||
|
<option value="StartTls">@Localizer["StartTls"]</option>
|
||||||
|
<option value="SslOnConnect">@Localizer["SslOnConnect"]</option>
|
||||||
|
<option value="StartTlsWhenAvailable">@Localizer["StartTlsWhenAvailable"]</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -504,7 +510,7 @@
|
|||||||
private string _smtpauthentication = "Basic";
|
private string _smtpauthentication = "Basic";
|
||||||
private string _smtphost = string.Empty;
|
private string _smtphost = string.Empty;
|
||||||
private string _smtpport = string.Empty;
|
private string _smtpport = string.Empty;
|
||||||
private string _smtpssl = "True";
|
private string _smtpssl = "Auto";
|
||||||
private string _smtpusername = string.Empty;
|
private string _smtpusername = string.Empty;
|
||||||
private string _smtppassword = string.Empty;
|
private string _smtppassword = string.Empty;
|
||||||
private string _smtppasswordtype = "password";
|
private string _smtppasswordtype = "password";
|
||||||
@ -613,7 +619,9 @@
|
|||||||
{
|
{
|
||||||
_smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty);
|
_smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty);
|
||||||
_smtpport = SettingService.GetSetting(settings, "SMTPPort", string.Empty);
|
_smtpport = SettingService.GetSetting(settings, "SMTPPort", string.Empty);
|
||||||
_smtpssl = SettingService.GetSetting(settings, "SMTPSSL", "False");
|
_smtpssl = SettingService.GetSetting(settings, "SMTPSSL", "Auto");
|
||||||
|
if (_smtpssl == "True") _smtpssl = "SslOnConnect";
|
||||||
|
if (_smtpssl == "False") _smtpssl = "StartTlsWhenAvailable";
|
||||||
_smtpauthentication = SettingService.GetSetting(settings, "SMTPAuthentication", "Basic");
|
_smtpauthentication = SettingService.GetSetting(settings, "SMTPAuthentication", "Basic");
|
||||||
_smtpusername = SettingService.GetSetting(settings, "SMTPUsername", string.Empty);
|
_smtpusername = SettingService.GetSetting(settings, "SMTPUsername", string.Empty);
|
||||||
_smtppassword = SettingService.GetSetting(settings, "SMTPPassword", string.Empty);
|
_smtppassword = SettingService.GetSetting(settings, "SMTPPassword", string.Empty);
|
||||||
@ -657,7 +665,8 @@
|
|||||||
if (tenant != null)
|
if (tenant != null)
|
||||||
{
|
{
|
||||||
_tenant = tenant.Name;
|
_tenant = tenant.Name;
|
||||||
_database = _databases.Find(item => item.DBType == tenant.DBType && item.Name != "LocalDB")?.Name;
|
// hack - there are 3 providers with SqlServerDatabase DBTypes - so we are choosing the last one in alphabetical order
|
||||||
|
_database = _databases.Where(item => item.DBType == tenant.DBType).OrderBy(item => item.Name).Last()?.Name;
|
||||||
_connectionstring = tenant.DBConnectionString;
|
_connectionstring = tenant.DBConnectionString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ else
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_databaseName = "LocalDB";
|
_databaseName = Constants.DefaultDBName;
|
||||||
}
|
}
|
||||||
LoadDatabaseConfigComponent();
|
LoadDatabaseConfigComponent();
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,8 @@ else
|
|||||||
if (tenant != null)
|
if (tenant != null)
|
||||||
{
|
{
|
||||||
_tenant = tenant.Name;
|
_tenant = tenant.Name;
|
||||||
_databasetype = _databases.FirstOrDefault(item => item.DBType == tenant.DBType && item.Name != "LocalDB").Name;
|
// hack - there are 3 providers with SqlServerDatabase DBTypes - so we are choosing the last one in alphabetical order
|
||||||
|
_databasetype = _databases.Where(item => item.DBType == tenant.DBType).OrderBy(item => item.Name).Last()?.Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -211,7 +212,7 @@ else
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_databasetype = "LocalDB";
|
_databasetype = Constants.DefaultDBName;
|
||||||
}
|
}
|
||||||
_showConnectionString = false;
|
_showConnectionString = false;
|
||||||
LoadDatabaseConfigComponent();
|
LoadDatabaseConfigComponent();
|
||||||
|
@ -310,6 +310,6 @@
|
|||||||
|
|
||||||
private void OnUpload()
|
private void OnUpload()
|
||||||
{
|
{
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Theme.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Theme.Upload"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,15 +124,19 @@
|
|||||||
@if (!string.IsNullOrEmpty(p.Autocomplete))
|
@if (!string.IsNullOrEmpty(p.Autocomplete))
|
||||||
{
|
{
|
||||||
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete">
|
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete">
|
||||||
|
<option value=""><@SharedLocalizer["Not Specified"]></option>
|
||||||
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
{
|
{
|
||||||
@if (GetProfileValue(p.Name, "") == option || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == option))
|
var values = option.Split(':');
|
||||||
|
var name = values[0];
|
||||||
|
var value = values.Length > 1 ? values[1] : values[0];
|
||||||
|
@if (GetProfileValue(p.Name, "") == name || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == name))
|
||||||
{
|
{
|
||||||
<option value="@option" selected>@option</option>
|
<option value="@name" selected>@value</option>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<option value="@option">@option</option>
|
<option value="@name">@value</option>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
@ -140,15 +144,19 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
|
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
|
||||||
|
<option value=""><@SharedLocalizer["Not Specified"]></option>
|
||||||
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
{
|
{
|
||||||
@if (GetProfileValue(p.Name, "") == option || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == option))
|
var values = option.Split(':');
|
||||||
|
var name = values[0];
|
||||||
|
var value = values.Length > 1 ? values[1] : values[0];
|
||||||
|
@if (GetProfileValue(p.Name, "") == name || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == name))
|
||||||
{
|
{
|
||||||
<option value="@option" selected>@option</option>
|
<option value="@name" selected>@value</option>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<option value="@option">@option</option>
|
<option value="@name">@value</option>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
@ -404,6 +412,14 @@
|
|||||||
_togglepassword = SharedLocalizer["ShowPassword"];
|
_togglepassword = SharedLocalizer["ShowPassword"];
|
||||||
_allowtwofactor = (SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:TwoFactor", "false") == "true");
|
_allowtwofactor = (SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:TwoFactor", "false") == "true");
|
||||||
_profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
|
_profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
|
||||||
|
foreach (var profile in _profiles)
|
||||||
|
{
|
||||||
|
if (profile.Options.ToLower().StartsWith("entityname:"))
|
||||||
|
{
|
||||||
|
var options = await SettingService.GetSettingsAsync(profile.Options.Substring(11), -1);
|
||||||
|
profile.Options = string.Join(",", options.Select(kvp => $"{kvp.Key}:{kvp.Value}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
_timezones = TimeZoneService.GetTimeZones();
|
_timezones = TimeZoneService.GetTimeZones();
|
||||||
|
|
||||||
if (PageState.User != null)
|
if (PageState.User != null)
|
||||||
|
@ -86,15 +86,19 @@
|
|||||||
@if (!string.IsNullOrEmpty(p.Options))
|
@if (!string.IsNullOrEmpty(p.Options))
|
||||||
{
|
{
|
||||||
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
|
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
|
||||||
|
<option value=""><@SharedLocalizer["Not Specified"]></option>
|
||||||
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
{
|
{
|
||||||
@if (GetProfileValue(p.Name, "") == option || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == option))
|
var values = option.Split(':');
|
||||||
|
var name = values[0];
|
||||||
|
var value = values.Length > 1 ? values[1] : values[0];
|
||||||
|
@if (GetProfileValue(p.Name, "") == name || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == name))
|
||||||
{
|
{
|
||||||
<option value="@option" selected>@option</option>
|
<option value="@name" selected>@value</option>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<option value="@option">@option</option>
|
<option value="@name">@value</option>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
@ -145,6 +149,14 @@
|
|||||||
{
|
{
|
||||||
_timezones = TimeZoneService.GetTimeZones();
|
_timezones = TimeZoneService.GetTimeZones();
|
||||||
_profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
|
_profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
|
||||||
|
foreach (var profile in _profiles)
|
||||||
|
{
|
||||||
|
if (profile.Options.ToLower().StartsWith("entityname:"))
|
||||||
|
{
|
||||||
|
var options = await SettingService.GetSettingsAsync(profile.Options.Substring(11), -1);
|
||||||
|
profile.Options = string.Join(",", options.Select(kvp => $"{kvp.Key}:{kvp.Value}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
_settings = new Dictionary<string, string>();
|
_settings = new Dictionary<string, string>();
|
||||||
_timezoneid = PageState.Site.TimeZoneId;
|
_timezoneid = PageState.Site.TimeZoneId;
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
|
@ -119,15 +119,19 @@
|
|||||||
@if (!string.IsNullOrEmpty(p.Options))
|
@if (!string.IsNullOrEmpty(p.Options))
|
||||||
{
|
{
|
||||||
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
|
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
|
||||||
|
<option value=""><@SharedLocalizer["Not Specified"]></option>
|
||||||
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
{
|
{
|
||||||
@if (GetProfileValue(p.Name, "") == option || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == option))
|
var values = option.Split(':');
|
||||||
|
var name = values[0];
|
||||||
|
var value = values.Length > 1 ? values[1] : values[0];
|
||||||
|
@if (GetProfileValue(p.Name, "") == name || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == name))
|
||||||
{
|
{
|
||||||
<option value="@option" selected>@option</option>
|
<option value="@name" selected>@value</option>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<option value="@option">@option</option>
|
<option value="@name">@value</option>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
@ -204,6 +208,14 @@
|
|||||||
_passwordrequirements = await UserService.GetPasswordRequirementsAsync(PageState.Site.SiteId);
|
_passwordrequirements = await UserService.GetPasswordRequirementsAsync(PageState.Site.SiteId);
|
||||||
_togglepassword = SharedLocalizer["ShowPassword"];
|
_togglepassword = SharedLocalizer["ShowPassword"];
|
||||||
_profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
|
_profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
|
||||||
|
foreach (var profile in _profiles)
|
||||||
|
{
|
||||||
|
if (profile.Options.ToLower().StartsWith("entityname:"))
|
||||||
|
{
|
||||||
|
var options = await SettingService.GetSettingsAsync(profile.Options.Substring(11), -1);
|
||||||
|
profile.Options = string.Join(",", options.Select(kvp => $"{kvp.Key}:{kvp.Value}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
_timezones = TimeZoneService.GetTimeZones();
|
_timezones = TimeZoneService.GetTimeZones();
|
||||||
|
|
||||||
if (PageState.QueryString.ContainsKey("id") && int.TryParse(PageState.QueryString["id"], out int UserId))
|
if (PageState.QueryString.ContainsKey("id") && int.TryParse(PageState.QueryString["id"], out int UserId))
|
||||||
|
@ -114,6 +114,12 @@ else
|
|||||||
<input id="cookiename" class="form-control" @bind="@_cookiename" />
|
<input id="cookiename" class="form-control" @bind="@_cookiename" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="cookiedomain" HelpText="If you would like to share cookies across subdomains you will need to specify a root domain with a leading dot (ie. '.example.com')" ResourceKey="CookieDomain">Cookie Domain:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="cookiedomain" class="form-control" @bind="@_cookiedomain" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="cookieexpiration" HelpText="You can choose to use a custom authentication cookie expiration timespan for each site (e.g. '08:00:00' for 8 hours). The default is 14 days if not specified." ResourceKey="CookieExpiration">Cookie Expiration Timespan:</Label>
|
<Label Class="col-sm-3" For="cookieexpiration" HelpText="You can choose to use a custom authentication cookie expiration timespan for each site (e.g. '08:00:00' for 8 hours). The default is 14 days if not specified." ResourceKey="CookieExpiration">Cookie Expiration Timespan:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -314,6 +320,15 @@ else
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="requirenonce" HelpText="Specify if Nonce validation is required for the ID token (the default is true)" ResourceKey="RequireNonce">Require Nonce?</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="requirenonce" class="form-select" @bind="@_requirenonce" required>
|
||||||
|
<option value="true">@SharedLocalizer["Yes"]</option>
|
||||||
|
<option value="false">@SharedLocalizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="scopes" HelpText="A list of Scopes to request from the provider (separated by commas). If none are specified, standard Scopes will be used by default." ResourceKey="Scopes">Scopes:</Label>
|
<Label Class="col-sm-3" For="scopes" HelpText="A list of Scopes to request from the provider (separated by commas). If none are specified, standard Scopes will be used by default." ResourceKey="Scopes">Scopes:</Label>
|
||||||
@ -516,6 +531,7 @@ else
|
|||||||
private string _requireconfirmedemail;
|
private string _requireconfirmedemail;
|
||||||
private string _twofactor;
|
private string _twofactor;
|
||||||
private string _cookiename;
|
private string _cookiename;
|
||||||
|
private string _cookiedomain;
|
||||||
private string _cookieexpiration;
|
private string _cookieexpiration;
|
||||||
private string _alwaysremember;
|
private string _alwaysremember;
|
||||||
private string _logouteverywhere;
|
private string _logouteverywhere;
|
||||||
@ -543,6 +559,7 @@ else
|
|||||||
private string _clientsecrettype = "password";
|
private string _clientsecrettype = "password";
|
||||||
private string _toggleclientsecret = string.Empty;
|
private string _toggleclientsecret = string.Empty;
|
||||||
private string _authresponsetype;
|
private string _authresponsetype;
|
||||||
|
private string _requirenonce;
|
||||||
private string _scopes;
|
private string _scopes;
|
||||||
private string _parameters;
|
private string _parameters;
|
||||||
private string _pkce;
|
private string _pkce;
|
||||||
@ -590,6 +607,7 @@ else
|
|||||||
{
|
{
|
||||||
_twofactor = SettingService.GetSetting(settings, "LoginOptions:TwoFactor", "false");
|
_twofactor = SettingService.GetSetting(settings, "LoginOptions:TwoFactor", "false");
|
||||||
_cookiename = SettingService.GetSetting(settings, "LoginOptions:CookieName", ".AspNetCore.Identity.Application");
|
_cookiename = SettingService.GetSetting(settings, "LoginOptions:CookieName", ".AspNetCore.Identity.Application");
|
||||||
|
_cookiedomain = SettingService.GetSetting(settings, "LoginOptions:CookieDomain", "");
|
||||||
_cookieexpiration = SettingService.GetSetting(settings, "LoginOptions:CookieExpiration", "");
|
_cookieexpiration = SettingService.GetSetting(settings, "LoginOptions:CookieExpiration", "");
|
||||||
_alwaysremember = SettingService.GetSetting(settings, "LoginOptions:AlwaysRemember", "false");
|
_alwaysremember = SettingService.GetSetting(settings, "LoginOptions:AlwaysRemember", "false");
|
||||||
_logouteverywhere = SettingService.GetSetting(settings, "LoginOptions:LogoutEverywhere", "false");
|
_logouteverywhere = SettingService.GetSetting(settings, "LoginOptions:LogoutEverywhere", "false");
|
||||||
@ -629,6 +647,7 @@ else
|
|||||||
_clientsecret = SettingService.GetSetting(settings, "ExternalLogin:ClientSecret", "");
|
_clientsecret = SettingService.GetSetting(settings, "ExternalLogin:ClientSecret", "");
|
||||||
_toggleclientsecret = SharedLocalizer["ShowPassword"];
|
_toggleclientsecret = SharedLocalizer["ShowPassword"];
|
||||||
_authresponsetype = SettingService.GetSetting(settings, "ExternalLogin:AuthResponseType", "code");
|
_authresponsetype = SettingService.GetSetting(settings, "ExternalLogin:AuthResponseType", "code");
|
||||||
|
_requirenonce = SettingService.GetSetting(settings, "ExternalLogin:RequireNonce", "true");
|
||||||
_scopes = SettingService.GetSetting(settings, "ExternalLogin:Scopes", "");
|
_scopes = SettingService.GetSetting(settings, "ExternalLogin:Scopes", "");
|
||||||
_parameters = SettingService.GetSetting(settings, "ExternalLogin:Parameters", "");
|
_parameters = SettingService.GetSetting(settings, "ExternalLogin:Parameters", "");
|
||||||
_pkce = SettingService.GetSetting(settings, "ExternalLogin:PKCE", "false");
|
_pkce = SettingService.GetSetting(settings, "ExternalLogin:PKCE", "false");
|
||||||
@ -725,6 +744,7 @@ else
|
|||||||
settings = SettingService.SetSetting(settings, "LoginOptions:RequireConfirmedEmail", _requireconfirmedemail, false);
|
settings = SettingService.SetSetting(settings, "LoginOptions:RequireConfirmedEmail", _requireconfirmedemail, false);
|
||||||
settings = SettingService.SetSetting(settings, "LoginOptions:TwoFactor", _twofactor, false);
|
settings = SettingService.SetSetting(settings, "LoginOptions:TwoFactor", _twofactor, false);
|
||||||
settings = SettingService.SetSetting(settings, "LoginOptions:CookieName", _cookiename, true);
|
settings = SettingService.SetSetting(settings, "LoginOptions:CookieName", _cookiename, true);
|
||||||
|
settings = SettingService.SetSetting(settings, "LoginOptions:CookieDomain", _cookiedomain, true);
|
||||||
settings = SettingService.SetSetting(settings, "LoginOptions:CookieExpiration", _cookieexpiration, true);
|
settings = SettingService.SetSetting(settings, "LoginOptions:CookieExpiration", _cookieexpiration, true);
|
||||||
settings = SettingService.SetSetting(settings, "LoginOptions:AlwaysRemember", _alwaysremember, false);
|
settings = SettingService.SetSetting(settings, "LoginOptions:AlwaysRemember", _alwaysremember, false);
|
||||||
settings = SettingService.SetSetting(settings, "LoginOptions:LogoutEverywhere", _logouteverywhere, false);
|
settings = SettingService.SetSetting(settings, "LoginOptions:LogoutEverywhere", _logouteverywhere, false);
|
||||||
@ -750,6 +770,7 @@ else
|
|||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:ClientId", _clientid, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:ClientId", _clientid, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:ClientSecret", _clientsecret, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:ClientSecret", _clientsecret, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:AuthResponseType", _authresponsetype, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:AuthResponseType", _authresponsetype, true);
|
||||||
|
settings = SettingService.SetSetting(settings, "ExternalLogin:RequireNonce", _requirenonce, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:Scopes", _scopes, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:Scopes", _scopes, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:Parameters", _parameters, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:Parameters", _parameters, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:PKCE", _pkce, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:PKCE", _pkce, true);
|
||||||
|
45
Oqtane.Client/Modules/Controls/FileManagerDialog.razor
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
@namespace Oqtane.Modules.Controls
|
||||||
|
@using System.IO
|
||||||
|
@using Radzen
|
||||||
|
@using Radzen.Blazor
|
||||||
|
@inject DialogService DialogService
|
||||||
|
@inject IStringLocalizer<Oqtane.Modules.Controls.RadzenTextEditor> Localizer
|
||||||
|
|
||||||
|
<div class="d-flex">
|
||||||
|
<FileManager @ref="_fileManager" Filter="@Filters" />
|
||||||
|
</div>
|
||||||
|
<div class="d-flex">
|
||||||
|
<ModuleMessage Message="@_message" Type="MessageType.Warning"></ModuleMessage>
|
||||||
|
</div>
|
||||||
|
<div class="mt-1 text-end">
|
||||||
|
<RadzenButton Text="OK" Click=@OnOkClick />
|
||||||
|
<RadzenButton Text="Cancel" Click=@OnCancelClick ButtonStyle="ButtonStyle.Secondary" />
|
||||||
|
</div>
|
||||||
|
@code {
|
||||||
|
private FileManager _fileManager;
|
||||||
|
private string _message = string.Empty;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Filters { get; set; }
|
||||||
|
|
||||||
|
private void OnCancelClick()
|
||||||
|
{
|
||||||
|
DialogService.Close(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnOkClick()
|
||||||
|
{
|
||||||
|
_message = string.Empty;
|
||||||
|
var file = _fileManager.GetFile();
|
||||||
|
if (file != null)
|
||||||
|
{
|
||||||
|
var result = $"<img src=\"{file.Url}\" style=\"max-width: 100%\" alt=\"{file.Name}\" />";
|
||||||
|
DialogService.Close(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_message = Localizer["Message.Require.Image"];
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
222
Oqtane.Client/Modules/Controls/SettingsDialog.razor
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
@namespace Oqtane.Modules.Controls
|
||||||
|
@using System.IO
|
||||||
|
@using Radzen
|
||||||
|
@using Radzen.Blazor
|
||||||
|
@inherits ModuleControlBase
|
||||||
|
@inject DialogService DialogService
|
||||||
|
@inject Radzen.ThemeService ThemeService
|
||||||
|
@inject ISettingService SettingService
|
||||||
|
@inject IRadzenEditorSettingService EditorSettingService
|
||||||
|
@inject IStringLocalizer<Oqtane.Modules.Controls.RadzenTextEditor> Localizer
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-sm-3">
|
||||||
|
@Localizer["Scope"]
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-9">
|
||||||
|
<RadzenRadioButtonList @bind-Value="@_settingScope" TValue="int" Change="OnScopeChanged">
|
||||||
|
<Items>
|
||||||
|
<RadzenRadioButtonListItem Text="@Localizer["Site"]" Value="0" />
|
||||||
|
<RadzenRadioButtonListItem Text="@Localizer["Module"]" Value="1" />
|
||||||
|
</Items>
|
||||||
|
</RadzenRadioButtonList>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-12 col-sm-3">
|
||||||
|
@Localizer["Theme"]
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-9">
|
||||||
|
<RadzenDropDown @bind-Value="_theme" TValue="string" Data="@_themes" Style="width: 100%;">
|
||||||
|
<Template>
|
||||||
|
<span>@Localizer[$"theme.{context}"]</span>
|
||||||
|
</Template>
|
||||||
|
</RadzenDropDown>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-12 col-sm-3">
|
||||||
|
@Localizer["Background"]
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-9">
|
||||||
|
<RadzenDropDown @bind-Value="_background" TValue="string" Data="_backgroundColors" Style="width: 100%;">
|
||||||
|
<Template>
|
||||||
|
<span>@Localizer[context]</span>
|
||||||
|
</Template>
|
||||||
|
</RadzenDropDown>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-12 col-sm-3">
|
||||||
|
@Localizer["Toolbar"]
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-9">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-sm-7">
|
||||||
|
<RadzenDropDown TValue="string" @bind-Value="_addToolbarItem" Data="@RadzenEditorDefinitions.ToolbarItems.Keys" Style="width: 100%;">
|
||||||
|
</RadzenDropDown>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-5 text-end">
|
||||||
|
<button type="button" class="btn btn-primary" @onclick="AddToolbarItem">@Localizer["Add"]</button>
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="ResetToolbarItem">@Localizer["Reset"]</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2" style="max-height: 500px; overflow-y: scroll;">
|
||||||
|
<div class="col">
|
||||||
|
<RadzenDropZoneContainer TItem="ToolbarItem" Data="_toolbarItems"
|
||||||
|
ItemSelector="@((i, z) => true)"
|
||||||
|
CanDrop="@((i) => true)"
|
||||||
|
Drop="OnToolbarItemDrop"
|
||||||
|
ItemRender="OnToolbarItemRender">
|
||||||
|
<ChildContent>
|
||||||
|
<RadzenDropZone TItem="ToolbarItem" class="rounded">
|
||||||
|
</RadzenDropZone>
|
||||||
|
</ChildContent>
|
||||||
|
<Template>
|
||||||
|
<div>
|
||||||
|
<strong>@context.Name</strong>
|
||||||
|
<RadzenButton Icon="delete" Click="@((e) => DeleteToolbarItem(context))" Size="ButtonSize.ExtraSmall" ButtonStyle="ButtonStyle.Light" />
|
||||||
|
</div>
|
||||||
|
</Template>
|
||||||
|
</RadzenDropZoneContainer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 text-end">
|
||||||
|
<RadzenButton Text="OK" Click=@OnOkClick />
|
||||||
|
<RadzenButton Text="Cancel" Click=@OnCancelClick ButtonStyle="ButtonStyle.Secondary" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private readonly IList<string> _themes = new List<string>
|
||||||
|
{
|
||||||
|
"default",
|
||||||
|
"dark",
|
||||||
|
"material",
|
||||||
|
"material-dark",
|
||||||
|
"standard",
|
||||||
|
"standard-dark",
|
||||||
|
"humanistic",
|
||||||
|
"humanistic-dark",
|
||||||
|
"software",
|
||||||
|
"software-dark"
|
||||||
|
};
|
||||||
|
private readonly IList<string> _backgroundColors = new List<string> { "Default", "Light", "Dark" };
|
||||||
|
|
||||||
|
private int _settingScope;
|
||||||
|
private string _theme;
|
||||||
|
private string _background;
|
||||||
|
private IList<ToolbarItem> _toolbarItems = new List<ToolbarItem>();
|
||||||
|
private string _addToolbarItem;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
_settingScope = await EditorSettingService.GetSettingScopeAsync(ModuleState.ModuleId);
|
||||||
|
|
||||||
|
await LoadSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<RadzenEditorSetting> LoadSettingsFromModule()
|
||||||
|
{
|
||||||
|
return await EditorSettingService.LoadSettingsFromModuleAsync(ModuleState.ModuleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<RadzenEditorSetting> LoadSettingsFromSite()
|
||||||
|
{
|
||||||
|
return await EditorSettingService.LoadSettingsFromSiteAsync(PageState.Site.SiteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadSettings()
|
||||||
|
{
|
||||||
|
var editorSetting = _settingScope == 1 ? await LoadSettingsFromModule() : await LoadSettingsFromSite();
|
||||||
|
_theme = editorSetting.Theme;
|
||||||
|
_background = editorSetting.Background;
|
||||||
|
_toolbarItems = editorSetting.ToolbarItems.Split(',').Select((v, i) =>
|
||||||
|
{
|
||||||
|
return new ToolbarItem { Key = i, Name = v };
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnScopeChanged()
|
||||||
|
{
|
||||||
|
await LoadSettings();
|
||||||
|
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddToolbarItem()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_addToolbarItem))
|
||||||
|
{
|
||||||
|
_toolbarItems.Add(new ToolbarItem { Key = _toolbarItems.Count, Name = _addToolbarItem });
|
||||||
|
_addToolbarItem = string.Empty;
|
||||||
|
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetToolbarItem()
|
||||||
|
{
|
||||||
|
_toolbarItems = RadzenEditorDefinitions.DefaultToolbarItems.Split(',').Select((v, i) =>
|
||||||
|
{
|
||||||
|
return new ToolbarItem { Key = i, Name = v };
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteToolbarItem(ToolbarItem item)
|
||||||
|
{
|
||||||
|
_toolbarItems.Remove(item);
|
||||||
|
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCancelClick()
|
||||||
|
{
|
||||||
|
DialogService.Close(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnOkClick()
|
||||||
|
{
|
||||||
|
var editorSetting = new RadzenEditorSetting
|
||||||
|
{
|
||||||
|
Theme = _theme,
|
||||||
|
Background = _background,
|
||||||
|
ToolbarItems = string.Join(",", _toolbarItems.Select(i => i.Name))
|
||||||
|
};
|
||||||
|
await EditorSettingService.UpdateSettingScopeAsync(ModuleState.ModuleId, _settingScope);
|
||||||
|
if (_settingScope == 1)
|
||||||
|
{
|
||||||
|
await EditorSettingService.SaveModuleSettingsAsync(ModuleState.ModuleId, editorSetting);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await EditorSettingService.SaveSiteSettingsAsync(PageState.Site.SiteId, editorSetting);
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogService.Close(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnToolbarItemDrop(RadzenDropZoneItemEventArgs<ToolbarItem> args)
|
||||||
|
{
|
||||||
|
if (args.ToItem != null && args.ToItem.Key != args.Item.Key)
|
||||||
|
{
|
||||||
|
_toolbarItems.Remove(args.Item);
|
||||||
|
_toolbarItems.Insert(_toolbarItems.IndexOf(args.ToItem), args.Item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnToolbarItemRender(RadzenDropZoneItemRenderEventArgs<ToolbarItem> args)
|
||||||
|
{
|
||||||
|
args.Attributes.Add("class", "rz-card rz-variant-flat rz-background-color-primary-lighter rz-color-on-primary-lighter rz-p-2 d-inline-block ms-1 mt-1");
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ToolbarItem
|
||||||
|
{
|
||||||
|
public int Key { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|