@ -1,31 +1,39 @@
|
|||||||
@inject IInstallationService InstallationService
|
@inject IInstallationService InstallationService
|
||||||
|
|
||||||
@if (_initialized)
|
@if (_initialized)
|
||||||
{
|
{
|
||||||
@if (!_installed)
|
@if (!_installation.Success)
|
||||||
{
|
{
|
||||||
<Installer />
|
<Installer />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<CascadingAuthenticationState>
|
@if (string.IsNullOrEmpty(_installation.Message))
|
||||||
<CascadingValue Value="@PageState">
|
{
|
||||||
<SiteRouter OnStateChange="@ChangeState" />
|
<CascadingAuthenticationState>
|
||||||
</CascadingValue>
|
<CascadingValue Value="@PageState">
|
||||||
</CascadingAuthenticationState>
|
<SiteRouter OnStateChange="@ChangeState" />
|
||||||
|
</CascadingValue>
|
||||||
|
</CascadingAuthenticationState>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="app-alert">
|
||||||
|
@_installation.Message
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private Installation _installation;
|
||||||
private bool _initialized;
|
private bool _initialized;
|
||||||
private bool _installed;
|
|
||||||
|
|
||||||
private PageState PageState { get; set; }
|
private PageState PageState { get; set; }
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
var installation = await InstallationService.IsInstalled();
|
_installation = await InstallationService.IsInstalled();
|
||||||
_installed = installation.Success;
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ else
|
|||||||
<td>
|
<td>
|
||||||
@if (context.AssemblyName != "Oqtane.Client")
|
@if (context.AssemblyName != "Oqtane.Client")
|
||||||
{
|
{
|
||||||
<ActionDialog Header="Delete Module" Message="@("Are You Sure You Wish To Delete The " + context.Name + " Module?")" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" />
|
<ActionDialog Header="Delete Module" Message="@Localizer["Are You Sure You Wish To Delete The {0} Module?", context.Name]" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" />
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.PageId.ToString())" ResourceKey="EditPage" /></td>
|
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.PageId.ToString())" ResourceKey="EditPage" /></td>
|
||||||
<td><ActionDialog Header="Delete Page" Message="@("Are You Sure You Wish To Delete The " + context.Name + " Page?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeletePage(context))" ResourceKey="DeletePage" /></td>
|
<td><ActionDialog Header="Delete Page" Message="@Localizer["Are You Sure You Wish To Delete The {0} Page?", context.Name]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeletePage(context))" ResourceKey="DeletePage" /></td>
|
||||||
<td>@(new string('-', context.Level * 2))@(context.Name)</td>
|
<td>@(new string('-', context.Level * 2))@(context.Name)</td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
|
@ -19,7 +19,7 @@ else
|
|||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ProfileId.ToString())" ResourceKey="EditProfile" /></td>
|
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ProfileId.ToString())" ResourceKey="EditProfile" /></td>
|
||||||
<td><ActionDialog Header="Delete Profile" Message="@("Are You Sure You Wish To Delete " + context.Name + "?")" Action="Delete" Class="btn btn-danger" OnClick="@(async () => await DeleteProfile(context.ProfileId))" ResourceKey="DeleteProfile" /></td>
|
<td><ActionDialog Header="Delete Profile" Message="@Localizer["Are You Sure You Wish To Delete {0}?", context.Name]" Action="Delete" Class="btn btn-danger" OnClick="@(async () => await DeleteProfile(context.ProfileId))" ResourceKey="DeleteProfile" /></td>
|
||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
@if (_pages.Any())
|
@if (_pages.Any())
|
||||||
{
|
{
|
||||||
<div style="text-align:right;">
|
<div style="text-align:right;">
|
||||||
<ActionDialog Header="Delete All Pages" Message="@Localizer["Are You Sure You Wish To Permanently Delete All Pages?", "Delete All Pages"]" Action="Delete All Pages" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllPages())" ResourceKey="DeleteAllPages" />
|
<ActionDialog Header="Delete All Pages" Message="Are You Sure You Wish To Permanently Delete All Pages?" Action="Delete All Pages" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllPages())" ResourceKey="DeleteAllPages" />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@
|
|||||||
@if (_modules.Any())
|
@if (_modules.Any())
|
||||||
{
|
{
|
||||||
<div style="text-align:right;">
|
<div style="text-align:right;">
|
||||||
<ActionDialog Header="Delete All Modules" Message="@Localizer["Are You Sure You Wish To Permanently Delete All Modules?", "Delete All Modules"]" Action="Delete All Modules" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllModules())" ResourceKey="DeleteAllModules" />
|
<ActionDialog Header="Delete All Modules" Message="Are You Sure You Wish To Permanently Delete All Modules?" Action="Delete All Modules" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllModules())" ResourceKey="DeleteAllModules" />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,146 +7,150 @@
|
|||||||
@inject IThemeService ThemeService
|
@inject IThemeService ThemeService
|
||||||
@inject ISettingService SettingService
|
@inject ISettingService SettingService
|
||||||
@inject IStringLocalizer<Index> Localizer
|
@inject IStringLocalizer<Index> Localizer
|
||||||
|
@inject INotificationService NotificationService
|
||||||
|
|
||||||
@if (_initialized)
|
@if (_initialized)
|
||||||
{
|
{
|
||||||
<table class="table table-borderless">
|
<table class="table table-borderless">
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<Label For="name" HelpText="Enter the site name" ResourceKey="Name">Name: </Label>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<input id="name" class="form-control" @bind="@_name" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<Label For="tenant" HelpText="Enter the tenant for the site" ResourceKey="Tenant">Tenant: </Label>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<input id="tenant" class="form-control" @bind="@_tenant" readonly />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<Label For="alias" HelpText="Enter the alias for the server" ResourceKey="Aliases">Aliases: </Label>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<textarea id="alias" class="form-control" @bind="@_urls" rows="3"></textarea>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<Label For="logo" HelpText="Upload a logo for the site" ResourceKey="Logo">Logo: </Label>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<FileManager FileId="@_logofileid" Filter="@Constants.ImageFiles" @ref="_logofilemanager" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<Label For="favicon" HelpText="Select Your default icon" ResourceKey="FavoriteIcon">Favicon: </Label>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<FileManager FileId="@_faviconfileid" Filter="ico" @ref="_faviconfilemanager" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<Label For="defaultTheme" HelpText="Select the sites default theme" ResourceKey="DefaultTheme">Default Theme: </Label>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
|
||||||
<option value="-"><@Localizer["Select Theme"]></option>
|
|
||||||
@foreach (var theme in _themes)
|
|
||||||
{
|
|
||||||
if (theme.TypeName == _themetype)
|
|
||||||
{
|
|
||||||
<option value="@theme.TypeName" selected>@theme.Name</option>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<option value="@theme.TypeName">@theme.Name</option>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@if (_layouts.Count > 0)
|
|
||||||
{
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="defaultLayout" HelpText="Select the sites default layout" ResourceKey="DefaultLayout">Default Layout: </Label>
|
<Label For="name" HelpText="Enter the site name" ResourceKey="Name">Name: </Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
<input id="name" class="form-control" @bind="@_name" />
|
||||||
<option value="-"><@Localizer["Select Layout"]></option>
|
</td>
|
||||||
@foreach (var layout in _layouts)
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="tenant" HelpText="Enter the tenant for the site" ResourceKey="Tenant">Tenant: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input id="tenant" class="form-control" @bind="@_tenant" readonly />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="alias" HelpText="Enter the alias for the server" ResourceKey="Aliases">Aliases: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<textarea id="alias" class="form-control" @bind="@_urls" rows="3"></textarea>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="allowRegister" HelpText="Do you want the users to be able to register for an account on the site" ResourceKey="AllowRegistration">Allow User Registration? </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<select id="allowRegister" class="form-control" @bind="@_allowregistration">
|
||||||
|
<option value="True">@Localizer["Yes"]</option>
|
||||||
|
<option value="False">@Localizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="isDeleted" HelpText="Is this site deleted?" ResourceKey="IsDeleted">Is Deleted? </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<select id="isDeleted" class="form-control" @bind="@_isdeleted">
|
||||||
|
<option value="True">@Localizer["Yes"]</option>
|
||||||
|
<option value="False">@Localizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<Section Name="Appearance" Heading="Appearance" ResourceKey="Appearance">
|
||||||
|
<table class="table table-borderless">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<FileManager FileId="@_logofileid" Filter="@Constants.ImageFiles" @ref="_logofilemanager" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="favicon" HelpText="Specify a Favicon" ResourceKey="FavoriteIcon">Favicon: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<FileManager FileId="@_faviconfileid" Filter="ico" @ref="_faviconfilemanager" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="defaultTheme" HelpText="Select the sites default theme" ResourceKey="DefaultTheme">Default Theme: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||||
|
<option value="-"><@Localizer["Select Theme"]></option>
|
||||||
|
@foreach (var theme in _themes)
|
||||||
{
|
{
|
||||||
<option value="@(layout.TypeName)">@(layout.Name)</option>
|
if (theme.TypeName == _themetype)
|
||||||
|
{
|
||||||
|
<option value="@theme.TypeName" selected>@theme.Name</option>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<option value="@theme.TypeName">@theme.Name</option>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
@if (_layouts.Count > 0)
|
||||||
<tr>
|
{
|
||||||
<td>
|
<tr>
|
||||||
<Label For="defaultContainer" HelpText="Select the default container for the site" ResourceKey="DefaultContainer">Default Container: </Label>
|
<td>
|
||||||
</td>
|
<Label For="defaultLayout" HelpText="Select the sites default layout" ResourceKey="DefaultLayout">Default Layout: </Label>
|
||||||
<td>
|
</td>
|
||||||
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
<td>
|
||||||
<option value="-"><@Localizer["Select Container"]></option>
|
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
||||||
@foreach (var container in _containers)
|
<option value="-"><@Localizer["Select Layout"]></option>
|
||||||
{
|
@foreach (var layout in _layouts)
|
||||||
<option value="@container.TypeName">@container.Name</option>
|
{
|
||||||
}
|
<option value="@(layout.TypeName)">@(layout.Name)</option>
|
||||||
</select>
|
}
|
||||||
</td>
|
</select>
|
||||||
</tr>
|
</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>
|
}
|
||||||
<Label For="defaultAdminContainer" HelpText="Select the default admin container for the site" ResourceKey="DefaultAdminContainer">Default Admin Container: </Label>
|
<tr>
|
||||||
</td>
|
<td>
|
||||||
<td>
|
<Label For="defaultContainer" HelpText="Select the default container for the site" ResourceKey="DefaultContainer">Default Container: </Label>
|
||||||
<select id="defaultAdminContainer" class="form-control" @bind="@_admincontainertype">
|
</td>
|
||||||
<option value="-"><@Localizer["Select Container"]></option>
|
<td>
|
||||||
<option value=""><@Localizer["Default Admin Container"]></option>
|
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
||||||
@foreach (var container in _containers)
|
<option value="-"><@Localizer["Select Container"]></option>
|
||||||
{
|
@foreach (var container in _containers)
|
||||||
<option value="@container.TypeName">@container.Name</option>
|
{
|
||||||
}
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
</select>
|
}
|
||||||
</td>
|
</select>
|
||||||
</tr>
|
</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>
|
<tr>
|
||||||
<Label For="allowRegister" HelpText="Do you want the users to be able to register for an account on the site" ResourceKey="AllowRegistration">Allow User Registration? </Label>
|
<td>
|
||||||
</td>
|
<Label For="defaultAdminContainer" HelpText="Select the default admin container for the site" ResourceKey="DefaultAdminContainer">Default Admin Container: </Label>
|
||||||
<td>
|
</td>
|
||||||
<select id="allowRegister" class="form-control" @bind="@_allowregistration">
|
<td>
|
||||||
<option value="True">@Localizer["Yes"]</option>
|
<select id="defaultAdminContainer" class="form-control" @bind="@_admincontainertype">
|
||||||
<option value="False">@Localizer["No"]</option>
|
<option value="-"><@Localizer["Select Container"]></option>
|
||||||
</select>
|
<option value=""><@Localizer["Default Admin Container"]></option>
|
||||||
</td>
|
@foreach (var container in _containers)
|
||||||
</tr>
|
{
|
||||||
<tr>
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
<td>
|
}
|
||||||
<Label For="isDeleted" HelpText="Is this site deleted?" ResourceKey="IsDeleted">Is Deleted? </Label>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
</tr>
|
||||||
<select id="isDeleted" class="form-control" @bind="@_isdeleted">
|
</table>
|
||||||
<option value="True">@Localizer["Yes"]</option>
|
</Section>
|
||||||
<option value="False">@Localizer["No"]</option>
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
|
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
|
||||||
<table class="table table-borderless">
|
<table class="table table-borderless">
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
@Localizer["Please Note That SMTP Requires The Notification Job To Be Enabled In the Scheduled Jobs"]
|
<strong>@Localizer["Please Note That SMTP Requires The Notification Job To Be Enabled In Scheduled Jobs"]</strong>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -201,6 +205,8 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="SendEmail">@Localizer["Test SMTP Configuration"]</button>
|
||||||
|
<br /><br />
|
||||||
</Section>
|
</Section>
|
||||||
<Section Name="PWA" Heading="Progressive Web Application Settings" ResourceKey="PWASettings">
|
<Section Name="PWA" Heading="Progressive Web Application Settings" ResourceKey="PWASettings">
|
||||||
<table class="table table-borderless">
|
<table class="table table-borderless">
|
||||||
@ -482,7 +488,6 @@
|
|||||||
await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId);
|
await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId);
|
||||||
|
|
||||||
await logger.LogInformation("Site Settings Saved {Site}", site);
|
await logger.LogInformation("Site Settings Saved {Site}", site);
|
||||||
|
|
||||||
AddModuleMessage(Localizer["Site Settings Saved"], MessageType.Success);
|
AddModuleMessage(Localizer["Site Settings Saved"], MessageType.Success);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -502,4 +507,36 @@
|
|||||||
AddModuleMessage(Localizer["Error Saving Site"], MessageType.Error);
|
AddModuleMessage(Localizer["Error Saving Site"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task SendEmail()
|
||||||
|
{
|
||||||
|
if (_smtphost != "" && _smtpport != "" && _smtpsender != "")
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
||||||
|
SettingService.SetSetting(settings, "SMTPHost", _smtphost);
|
||||||
|
SettingService.SetSetting(settings, "SMTPPort", _smtpport);
|
||||||
|
SettingService.SetSetting(settings, "SMTPSSL", _smtpssl);
|
||||||
|
SettingService.SetSetting(settings, "SMTPUsername", _smtpusername);
|
||||||
|
SettingService.SetSetting(settings, "SMTPPassword", _smtppassword);
|
||||||
|
SettingService.SetSetting(settings, "SMTPSender", _smtpsender);
|
||||||
|
await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId);
|
||||||
|
await logger.LogInformation("Site SMTP Settings Saved");
|
||||||
|
|
||||||
|
await NotificationService.AddNotificationAsync(new Notification(PageState.Site.SiteId, PageState.User.DisplayName, PageState.User.Email, PageState.User.DisplayName, PageState.User.Email, PageState.Site.Name + " SMTP Configuration Test", "SMTP Server Is Configured Correctly."));
|
||||||
|
AddModuleMessage(Localizer["SMTP Settings Saved And A Message Has Been Sent To The Email Address Associated To Your User Account... Please Wait A Few Minutes For Delivery. If You Do Not Receive The Email Please Review The Notification Job In Scheduled Jobs For Any Log Details."], MessageType.Info);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Testing SMTP Configuration");
|
||||||
|
AddModuleMessage(Localizer["Error Testing SMTP Configuration"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["You Must Specify The SMTP Host, Port, And Sender"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ else
|
|||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.AliasId.ToString())" ResourceKey="EditSite" /></td>
|
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.AliasId.ToString())" ResourceKey="EditSite" /></td>
|
||||||
<td><ActionDialog Header="Delete Site" Message="@Localizer["Are You Sure You Wish To Delete The {0} Site?", context.Name]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteSite(context))" ResourceKey="DeleteSite" /></td>
|
<td><ActionDialog Header="Delete Site" Message="@Localizer["Are You Sure You Wish To Delete The {0} Site?", context.Name]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteSite(context))" ResourceKey="DeleteSite" /></td>
|
||||||
<td><a href="@(_scheme + context.Name)">@context.Name</a></td>
|
<td><a href="@(_scheme + context.Name +"?reload")">@context.Name</a></td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="version" HelpText="The version of the thene" ResourceKey="Version">Version: </Label>
|
<Label For="version" HelpText="The version of the theme" ResourceKey="Version">Version: </Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input id="version" class="form-control" @bind="@_version" disabled />
|
<input id="version" class="form-control" @bind="@_version" disabled />
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
{
|
{
|
||||||
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body, null);
|
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body, null);
|
||||||
notification = await NotificationService.AddNotificationAsync(notification);
|
notification = await NotificationService.AddNotificationAsync(notification);
|
||||||
await logger.LogInformation("Notification Created {Notification}", notification);
|
await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -183,7 +183,7 @@
|
|||||||
{
|
{
|
||||||
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body, notificationid);
|
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body, notificationid);
|
||||||
notification = await NotificationService.AddNotificationAsync(notification);
|
notification = await NotificationService.AddNotificationAsync(notification);
|
||||||
await logger.LogInformation("Notification Created {Notification}", notification);
|
await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
var urlparameters = string.Empty;
|
var urlparameters = string.Empty;
|
||||||
var editmode = false;
|
var editmode = false;
|
||||||
var reload = Reload.None;
|
var reload = Reload.None;
|
||||||
var lastsyncdate = DateTime.UtcNow;
|
var lastsyncdate = DateTime.UtcNow.AddHours(-1);
|
||||||
var runtime = GetRuntime();
|
var runtime = GetRuntime();
|
||||||
|
|
||||||
Uri uri = new Uri(_absoluteUri);
|
Uri uri = new Uri(_absoluteUri);
|
||||||
@ -107,9 +107,14 @@
|
|||||||
SiteState.Alias = alias; // set state for services
|
SiteState.Alias = alias; // set state for services
|
||||||
lastsyncdate = alias.SyncDate;
|
lastsyncdate = alias.SyncDate;
|
||||||
|
|
||||||
// process any sync events for site
|
// process any sync events
|
||||||
if (reload != Reload.Site && alias.SyncEvents.Any())
|
if (reload != Reload.Site && alias.SyncEvents.Any())
|
||||||
{
|
{
|
||||||
|
// if running on WebAssembly reload the client application if the server application was restarted
|
||||||
|
if (runtime == Shared.Runtime.WebAssembly && PageState != null && alias.SyncEvents.Exists(item => item.TenantId == -1))
|
||||||
|
{
|
||||||
|
NavigationManager.NavigateTo(_absoluteUri + (!_absoluteUri.Contains("?") ? "?" : "&") + "reload", true);
|
||||||
|
}
|
||||||
if (alias.SyncEvents.Exists(item => item.EntityName == EntityNames.Site && item.EntityId == alias.SiteId))
|
if (alias.SyncEvents.Exists(item => item.EntityName == EntityNames.Site && item.EntityId == alias.SiteId))
|
||||||
{
|
{
|
||||||
reload = Reload.Site;
|
reload = Reload.Site;
|
||||||
|
@ -55,8 +55,7 @@ namespace Oqtane.Controllers
|
|||||||
[HttpGet("installed")]
|
[HttpGet("installed")]
|
||||||
public Installation IsInstalled()
|
public Installation IsInstalled()
|
||||||
{
|
{
|
||||||
bool isInstalled = _databaseManager.IsInstalled();
|
return _databaseManager.IsInstalled();
|
||||||
return new Installation {Success = isInstalled, Message = string.Empty};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("upgrade")]
|
[HttpGet("upgrade")]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Oqtane.Enums;
|
using Oqtane.Enums;
|
||||||
@ -65,7 +65,7 @@ namespace Oqtane.Controllers
|
|||||||
if (IsAuthorized(notification.FromUserId))
|
if (IsAuthorized(notification.FromUserId))
|
||||||
{
|
{
|
||||||
notification = _notifications.AddNotification(notification);
|
notification = _notifications.AddNotification(notification);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Notification Added {Notification}", notification);
|
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Notification Added {NotificationId}", notification.NotificationId);
|
||||||
}
|
}
|
||||||
return notification;
|
return notification;
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ namespace Oqtane.Controllers
|
|||||||
if (IsAuthorized(notification.FromUserId))
|
if (IsAuthorized(notification.FromUserId))
|
||||||
{
|
{
|
||||||
notification = _notifications.UpdateNotification(notification);
|
notification = _notifications.UpdateNotification(notification);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Notification Updated {Folder}", notification);
|
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Notification Updated {NotificationId}", notification.NotificationId);
|
||||||
}
|
}
|
||||||
return notification;
|
return notification;
|
||||||
}
|
}
|
||||||
|
@ -33,27 +33,30 @@ namespace Oqtane.Infrastructure
|
|||||||
_cache = cache;
|
_cache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsInstalled()
|
public Installation IsInstalled()
|
||||||
{
|
{
|
||||||
var defaultConnectionString = NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey));
|
var result = new Installation { Success = false, Message = string.Empty };
|
||||||
var result = !string.IsNullOrEmpty(defaultConnectionString);
|
if (!string.IsNullOrEmpty(_config.GetConnectionString(SettingKeys.ConnectionStringKey)))
|
||||||
if (result)
|
|
||||||
{
|
{
|
||||||
|
result.Success = true;
|
||||||
using (var scope = _serviceScopeFactory.CreateScope())
|
using (var scope = _serviceScopeFactory.CreateScope())
|
||||||
{
|
{
|
||||||
var db = scope.ServiceProvider.GetRequiredService<MasterDBContext>();
|
var db = scope.ServiceProvider.GetRequiredService<MasterDBContext>();
|
||||||
result = db.Database.CanConnect();
|
if (db.Database.CanConnect())
|
||||||
if (result)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = db.Tenant.Any();
|
var provisioned = db.Tenant.Any();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
result = false;
|
result.Message = "Master Database Not Installed Correctly";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.Message = "Cannot Connect To Master Database";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -74,7 +77,8 @@ namespace Oqtane.Infrastructure
|
|||||||
// startup or silent installation
|
// startup or silent installation
|
||||||
install = new InstallConfig { ConnectionString = _config.GetConnectionString(SettingKeys.ConnectionStringKey), TenantName = TenantNames.Master, IsNewTenant = false };
|
install = new InstallConfig { ConnectionString = _config.GetConnectionString(SettingKeys.ConnectionStringKey), TenantName = TenantNames.Master, IsNewTenant = false };
|
||||||
|
|
||||||
if (!IsInstalled())
|
var installation = IsInstalled();
|
||||||
|
if (!installation.Success)
|
||||||
{
|
{
|
||||||
install.Aliases = GetInstallationConfig(SettingKeys.DefaultAliasKey, string.Empty);
|
install.Aliases = GetInstallationConfig(SettingKeys.DefaultAliasKey, string.Empty);
|
||||||
install.HostPassword = GetInstallationConfig(SettingKeys.HostPasswordKey, string.Empty);
|
install.HostPassword = GetInstallationConfig(SettingKeys.HostPasswordKey, string.Empty);
|
||||||
@ -97,6 +101,14 @@ namespace Oqtane.Infrastructure
|
|||||||
install.ConnectionString = "";
|
install.ConnectionString = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(installation.Message))
|
||||||
|
{
|
||||||
|
// problem with prior installation
|
||||||
|
install.ConnectionString = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
|
|
||||||
namespace Oqtane.Infrastructure
|
namespace Oqtane.Infrastructure
|
||||||
{
|
{
|
||||||
public interface IDatabaseManager
|
public interface IDatabaseManager
|
||||||
{
|
{
|
||||||
bool IsInstalled();
|
Installation IsInstalled();
|
||||||
Installation Install();
|
Installation Install();
|
||||||
Installation Install(InstallConfig install);
|
Installation Install(InstallConfig install);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -17,7 +17,7 @@ namespace Oqtane.Infrastructure
|
|||||||
|
|
||||||
public List<SyncEvent> GetSyncEvents(int tenantId, DateTime lastSyncDate)
|
public List<SyncEvent> GetSyncEvents(int tenantId, DateTime lastSyncDate)
|
||||||
{
|
{
|
||||||
return SyncEvents.Where(item => item.TenantId == tenantId && item.ModifiedOn >= lastSyncDate).ToList();
|
return SyncEvents.Where(item => (item.TenantId == tenantId || item.TenantId == -1) && item.ModifiedOn >= lastSyncDate).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddSyncEvent(int tenantId, string entityName, int entityId)
|
public void AddSyncEvent(int tenantId, string entityName, int entityId)
|
||||||
|
@ -25,14 +25,12 @@ namespace Oqtane.Infrastructure
|
|||||||
|
|
||||||
public void Upgrade(Tenant tenant, string version)
|
public void Upgrade(Tenant tenant, string version)
|
||||||
{
|
{
|
||||||
// core framework upgrade logic - note that you can check if current tenant is Master if you only want to execute logic once
|
// core framework upgrade logic - note that you can check if current tenant is Master if you only want to execute the logic once
|
||||||
var pageTemplates = new List<PageTemplate>();
|
|
||||||
|
|
||||||
switch (version)
|
switch (version)
|
||||||
{
|
{
|
||||||
case "0.9.0":
|
case "0.9.0":
|
||||||
// add a page to all existing sites on upgrade
|
// this code is commented out on purpose - it provides an example of how to programmatically add a page to all existing sites on upgrade
|
||||||
|
var pageTemplates = new List<PageTemplate>();
|
||||||
//pageTemplates.Add(new PageTemplate
|
//pageTemplates.Add(new PageTemplate
|
||||||
//{
|
//{
|
||||||
// Name = "Test",
|
// Name = "Test",
|
||||||
@ -68,7 +66,12 @@ namespace Oqtane.Infrastructure
|
|||||||
case "2.0.2":
|
case "2.0.2":
|
||||||
if (tenant.Name == TenantNames.Master)
|
if (tenant.Name == TenantNames.Master)
|
||||||
{
|
{
|
||||||
Directory.Delete(Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", "Internal", Path.DirectorySeparatorChar.ToString()), true);
|
// remove Internal module template files as they are no longer supported
|
||||||
|
var internalTemplatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", "Internal", Path.DirectorySeparatorChar.ToString());
|
||||||
|
if (Directory.Exists(internalTemplatePath))
|
||||||
|
{
|
||||||
|
Directory.Delete(internalTemplatePath, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,9 @@
|
|||||||
|
|
||||||
@if (Model.Message != "")
|
@if (Model.Message != "")
|
||||||
{
|
{
|
||||||
@Model.Message
|
<div class="app-alert">
|
||||||
|
@Model.Message
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<script src="js/interop.js"></script>
|
<script src="js/interop.js"></script>
|
||||||
|
@ -226,7 +226,7 @@ namespace Oqtane
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ISyncManager sync)
|
||||||
{
|
{
|
||||||
ServiceActivator.Configure(app.ApplicationServices);
|
ServiceActivator.Configure(app.ApplicationServices);
|
||||||
|
|
||||||
@ -264,6 +264,9 @@ namespace Oqtane
|
|||||||
endpoints.MapControllers();
|
endpoints.MapControllers();
|
||||||
endpoints.MapFallbackToPage("/_Host");
|
endpoints.MapFallbackToPage("/_Host");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// create a sync event to identify server application startup
|
||||||
|
sync.AddSyncEvent(-1, "Application", -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
|
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||||
@ -125,6 +125,13 @@ app {
|
|||||||
vertical-align: inherit;
|
vertical-align: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-alert {
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f44336; /* red */
|
||||||
|
color: white;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Tooltips */
|
/* Tooltips */
|
||||||
.app-tooltip {
|
.app-tooltip {
|
||||||
cursor: help;
|
cursor: help;
|
||||||
|
Reference in New Issue
Block a user