commit
06ebce31ca
|
@ -12,11 +12,12 @@
|
|||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||
{
|
||||
string url = NavigateUrl(p.Path);
|
||||
<div class="col-md-2 mx-auto text-center mb-3">
|
||||
<p class="col-md-2 mx-auto text-center mb-3">
|
||||
<NavLink class="nav-link text-primary" href="@url" Match="NavLinkMatch.All">
|
||||
<h2><span class="@p.Icon" aria-hidden="true"></span></h2>@SharedLocalizer[p.Name]
|
||||
<h2><span class="@p.Icon" aria-hidden="true"></span></h2>
|
||||
<p class="lead">@((MarkupString)SharedLocalizer[p.Name].ToString().Replace(" ", "<br />"))</p>
|
||||
</NavLink>
|
||||
</div>
|
||||
</p>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<br /><br />
|
||||
|
||||
@if (!_isSystem)
|
||||
{
|
||||
|
@ -79,8 +80,7 @@
|
|||
@((MarkupString)" ")
|
||||
<ActionDialog Header="Delete Folder" Message="Are You Sure You Wish To Delete This Folder?" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFolder())" ResourceKey="DeleteFolder" />
|
||||
}
|
||||
<br />
|
||||
<br />
|
||||
<br /><br />
|
||||
@if (PageState.QueryString.ContainsKey("id"))
|
||||
{
|
||||
<AuditInfo CreatedBy="@_createdBy" CreatedOn="@_createdOn" ModifiedBy="@_modifiedBy" ModifiedOn="@_modifiedOn"></AuditInfo>
|
||||
|
|
|
@ -8,27 +8,28 @@
|
|||
|
||||
@if (_files != null)
|
||||
{
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<div class="col-sm-2">
|
||||
<label class="control-label">@Localizer["Folder"] </label>
|
||||
<div class="row">
|
||||
<div class="col-md mb-1">
|
||||
<ActionLink Action="Edit" Text="Add Folder" Class="btn btn-secondary" ResourceKey="AddFolder" />
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="col-md-8 mb-1">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">@Localizer["Folder"]:</span>
|
||||
<select class="form-select" @onchange="(e => FolderChanged(e))">
|
||||
@foreach (Folder folder in _folders)
|
||||
{
|
||||
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<ActionLink Action="Edit" Text="Edit Folder" Class="btn btn-secondary" Parameters="@($"id=" + _folderId.ToString())" ResourceKey="EditFolder" />
|
||||
<ActionLink Action="Edit" Text="Add Folder" Class="btn btn-secondary" ResourceKey="AddFolder" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md mb-1 text-end">
|
||||
<ActionLink Action="Add" Text="Upload Files" Parameters="@($"id=" + _folderId.ToString())" ResourceKey="UploadFiles" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Pager Items="@_files">
|
||||
|
||||
<Pager Items="@_files" SearchProperties="Name">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
|
|
|
@ -15,7 +15,7 @@ else
|
|||
<br />
|
||||
<br />
|
||||
|
||||
<Pager Items="@_jobs">
|
||||
<Pager Items="@_jobs" SearchProperties="Name">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
|
|
|
@ -14,7 +14,7 @@ else
|
|||
{
|
||||
<ActionLink Action="Add" Text="Add Language" ResourceKey="AddLanguage" />
|
||||
|
||||
<Pager Items="@_languages">
|
||||
<Pager Items="@_languages" SearchProperties="Name,Code">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>@SharedLocalizer["Name"]</th>
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
<div class="container-fluid px-0">
|
||||
<div class="row g-0 mb-2">
|
||||
<div class="col-4">
|
||||
<a href="@context.ProductUrl" target="_blank">
|
||||
@if (context.LogoUrl != null)
|
||||
{
|
||||
<img src="@context.LogoUrl" class="img-fluid" alt="@context.Name" />
|
||||
|
@ -74,6 +75,7 @@
|
|||
{
|
||||
<img src="/package.png" class="img-fluid" alt="@context.Name" />
|
||||
}
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-8 text-end">
|
||||
<small>@SharedLocalizer["Search.Version"]:</small> <strong>@context.Version</strong>
|
||||
|
|
|
@ -156,7 +156,7 @@
|
|||
private bool IsValidXML(string description)
|
||||
{
|
||||
// must contain letters, digits, or spaces
|
||||
return Regex.IsMatch(description, "^[A-Za-z0-9 ]+$");
|
||||
return Regex.IsMatch(description, "^[A-Za-z0-9 .,!?]+$");
|
||||
}
|
||||
|
||||
private void TemplateChanged(ChangeEventArgs e)
|
||||
|
|
|
@ -26,6 +26,17 @@
|
|||
<input id="title" type="text" class="form-control" @bind="@_title" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="pane" HelpText="The pane where the module will be displayed" ResourceKey="Pane">Pane: </Label>
|
||||
<div class="col-sm-9">
|
||||
<select class="form-select" @bind="@_pane">
|
||||
@foreach (string pane in PageState.Page.Panes)
|
||||
{
|
||||
<option value="@pane">@pane Pane</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="container" HelpText="Select the module's container" ResourceKey="Container">Container: </Label>
|
||||
<div class="col-sm-9">
|
||||
|
@ -112,6 +123,7 @@
|
|||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private string _module;
|
||||
private string _title;
|
||||
private string _pane;
|
||||
private string _containerType;
|
||||
private string _allPages = "false";
|
||||
private string _permissionNames = "";
|
||||
|
@ -134,6 +146,7 @@
|
|||
{
|
||||
_module = ModuleState.ModuleDefinition.Name;
|
||||
_title = ModuleState.Title;
|
||||
_pane = ModuleState.Pane;
|
||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, PageState.Page.ThemeType);
|
||||
_containerType = ModuleState.ContainerType;
|
||||
_allPages = ModuleState.AllPages.ToString();
|
||||
|
@ -206,6 +219,7 @@
|
|||
var pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId);
|
||||
pagemodule.PageId = int.Parse(_pageId);
|
||||
pagemodule.Title = _title;
|
||||
pagemodule.Pane = _pane;
|
||||
pagemodule.ContainerType = (_containerType != "-") ? _containerType : string.Empty;
|
||||
if (!string.IsNullOrEmpty(pagemodule.ContainerType) && pagemodule.ContainerType == PageState.Page.DefaultContainerType)
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
{
|
||||
<ActionLink Action="Add" Text="Add Page" ResourceKey="AddPage" />
|
||||
|
||||
<Pager Items="@PageState.Pages.Where(item => !item.IsDeleted)">
|
||||
<Pager Items="@PageState.Pages.Where(item => !item.IsDeleted)" SearchProperties="Name">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="description" HelpText="The help text displayed to the user for this profile item" ResourceKey="Description">Description: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="description" class="form-control" @bind="@_description" rows="5" maxlength="256" required ></textarea>
|
||||
<textarea id="description" class="form-control" @bind="@_description" rows="3" maxlength="256" required ></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
|
@ -43,6 +43,12 @@
|
|||
<input id="length" class="form-control" @bind="@_maxlength" maxlength="4" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="rows" HelpText="The number of rows for text entry (one is the default)" ResourceKey="Rows">Rows: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="rows" class="form-control" @bind="@_rows" maxlength="2" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="defaultVal" HelpText="The default value for this profile item" ResourceKey="DefaultValue">Default Value: </Label>
|
||||
<div class="col-sm-9">
|
||||
|
@ -101,6 +107,7 @@
|
|||
private string _category = string.Empty;
|
||||
private string _vieworder = "0";
|
||||
private string _maxlength = "0";
|
||||
private string _rows = "1";
|
||||
private string _defaultvalue = string.Empty;
|
||||
private string _options = string.Empty;
|
||||
private string _validation = string.Empty;
|
||||
|
@ -131,6 +138,7 @@
|
|||
_category = profile.Category;
|
||||
_vieworder = profile.ViewOrder.ToString();
|
||||
_maxlength = profile.MaxLength.ToString();
|
||||
_rows = profile.Rows.ToString();
|
||||
_defaultvalue = profile.DefaultValue;
|
||||
_options = profile.Options;
|
||||
_validation = profile.Validation;
|
||||
|
@ -175,6 +183,7 @@
|
|||
profile.Category = _category;
|
||||
profile.ViewOrder = int.Parse(_vieworder);
|
||||
profile.MaxLength = int.Parse(_maxlength);
|
||||
profile.Rows = int.Parse(_rows);
|
||||
profile.DefaultValue = _defaultvalue;
|
||||
profile.Options = _options;
|
||||
profile.Validation = _validation;
|
||||
|
|
|
@ -12,7 +12,7 @@ else
|
|||
{
|
||||
<ActionLink Action="Add" Text="Add Profile" Security="SecurityAccessLevel.Edit" ResourceKey="AddProfile" />
|
||||
|
||||
<Pager Items="@_profiles">
|
||||
<Pager Items="@_profiles" SearchProperties="Title,Category">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
|
|
|
@ -12,7 +12,7 @@ else
|
|||
{
|
||||
<ActionLink Action="Add" Text="Add Role" Security="SecurityAccessLevel.Edit" ResourceKey="AddRole" />
|
||||
|
||||
<Pager Items="@_roles">
|
||||
<Pager Items="@_roles" SearchProperties="Name">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
|
|
|
@ -14,7 +14,7 @@ else
|
|||
{
|
||||
<ActionLink Action="Add" Text="Add Site" ResourceKey="AddSite" />
|
||||
|
||||
<Pager Items="@_sites">
|
||||
<Pager Items="@_sites" SearchProperties="Name">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
<div class="container-fluid px-0">
|
||||
<div class="row g-0 mb-2">
|
||||
<div class="col-4">
|
||||
<a href="@context.ProductUrl" target="_blank">
|
||||
@if (context.LogoUrl != null)
|
||||
{
|
||||
<img src="@context.LogoUrl" class="img-fluid" alt="@context.Name" />
|
||||
|
@ -74,6 +75,7 @@
|
|||
{
|
||||
<img src="/package.png" class="img-fluid" alt="@context.Name" />
|
||||
}
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-8 text-end">
|
||||
<small>@SharedLocalizer["Search.Version"]:</small> <strong>@context.Version</strong>
|
||||
|
|
|
@ -28,7 +28,7 @@ else
|
|||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<Pager Items="@_urlMappings">
|
||||
<Pager Items="@_urlMappings" SearchProperties="Url">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
|
|
|
@ -122,6 +122,8 @@ else
|
|||
</select>
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (p.Rows == 1)
|
||||
{
|
||||
@if (p.IsRequired)
|
||||
{
|
||||
|
@ -132,6 +134,18 @@ else
|
|||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (p.IsRequired)
|
||||
{
|
||||
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
||||
}
|
||||
else
|
||||
{
|
||||
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -282,9 +296,11 @@ else
|
|||
private int folderid = -1;
|
||||
private int photofileid = -1;
|
||||
private File photo = null;
|
||||
|
||||
private List<Profile> profiles;
|
||||
private Dictionary<string, string> settings;
|
||||
private string category = string.Empty;
|
||||
|
||||
private string filter = "to";
|
||||
private List<Notification> notifications;
|
||||
private string notificationSummary = string.Empty;
|
||||
|
@ -363,9 +379,11 @@ else
|
|||
{
|
||||
try
|
||||
{
|
||||
if (username != string.Empty && email != string.Empty && ValidateProfiles())
|
||||
if (username != string.Empty && email != string.Empty)
|
||||
{
|
||||
if (_password == confirm)
|
||||
{
|
||||
if (ValidateProfiles())
|
||||
{
|
||||
var user = PageState.User;
|
||||
user.Username = username;
|
||||
|
@ -403,6 +421,7 @@ else
|
|||
AddModuleMessage(Localizer["Message.Password.Complexity"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage(Localizer["Message.Password.Invalid"], MessageType.Warning);
|
||||
|
@ -424,7 +443,6 @@ else
|
|||
|
||||
private bool ValidateProfiles()
|
||||
{
|
||||
bool valid = true;
|
||||
foreach (Profile profile in profiles)
|
||||
{
|
||||
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||
|
@ -433,18 +451,24 @@ else
|
|||
}
|
||||
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||
{
|
||||
if (valid == true && profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||
{
|
||||
valid = false;
|
||||
AddModuleMessage(string.Format(SharedLocalizer["ProfileRequired"], profile.Title), MessageType.Warning);
|
||||
return false;
|
||||
}
|
||||
if (valid == true && !string.IsNullOrEmpty(profile.Validation))
|
||||
if (!string.IsNullOrEmpty(profile.Validation))
|
||||
{
|
||||
Regex regex = new Regex(profile.Validation);
|
||||
valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
|
||||
bool valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
|
||||
if (!valid)
|
||||
{
|
||||
AddModuleMessage(string.Format(SharedLocalizer["ProfileInvalid"], profile.Title), MessageType.Warning);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void Cancel()
|
||||
|
|
|
@ -80,6 +80,26 @@
|
|||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="@p.Name" HelpText="@p.Description">@p.Title</Label>
|
||||
<div class="col-sm-9">
|
||||
@if (!string.IsNullOrEmpty(p.Options))
|
||||
{
|
||||
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
|
||||
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
@if (GetProfileValue(p.Name, "") == option || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == option))
|
||||
{
|
||||
<option value="@option" selected>@option</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@option">@option</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (p.Rows == 1)
|
||||
{
|
||||
@if (p.IsRequired)
|
||||
{
|
||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
|
@ -88,10 +108,22 @@
|
|||
{
|
||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (p.IsRequired)
|
||||
{
|
||||
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
||||
}
|
||||
else
|
||||
{
|
||||
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -148,9 +180,11 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
if (_username != string.Empty && _password != string.Empty && _confirm != string.Empty && _email != string.Empty && ValidateProfiles())
|
||||
if (_username != string.Empty && _password != string.Empty && _confirm != string.Empty && _email != string.Empty)
|
||||
{
|
||||
if (_password == _confirm)
|
||||
{
|
||||
if (ValidateProfiles())
|
||||
{
|
||||
var user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
|
@ -175,6 +209,7 @@
|
|||
AddModuleMessage(Localizer["Error.User.AddCheckPass"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage(Localizer["Message.Password.NoMatch"], MessageType.Warning);
|
||||
|
@ -194,7 +229,6 @@
|
|||
|
||||
private bool ValidateProfiles()
|
||||
{
|
||||
bool valid = true;
|
||||
foreach (Profile profile in profiles)
|
||||
{
|
||||
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||
|
@ -203,18 +237,24 @@
|
|||
}
|
||||
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||
{
|
||||
if (valid == true && profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||
{
|
||||
valid = false;
|
||||
AddModuleMessage(string.Format(SharedLocalizer["ProfileRequired"], profile.Title), MessageType.Warning);
|
||||
return false;
|
||||
}
|
||||
if (valid == true && !string.IsNullOrEmpty(profile.Validation))
|
||||
if (!string.IsNullOrEmpty(profile.Validation))
|
||||
{
|
||||
Regex regex = new Regex(profile.Validation);
|
||||
valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
|
||||
bool valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
|
||||
if (!valid)
|
||||
{
|
||||
AddModuleMessage(string.Format(SharedLocalizer["ProfileInvalid"], profile.Title), MessageType.Warning);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||
|
|
|
@ -124,6 +124,8 @@ else
|
|||
</select>
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (p.Rows == 1)
|
||||
{
|
||||
@if (p.IsRequired)
|
||||
{
|
||||
|
@ -134,6 +136,18 @@ else
|
|||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (p.IsRequired)
|
||||
{
|
||||
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
||||
}
|
||||
else
|
||||
{
|
||||
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -240,9 +254,11 @@ else
|
|||
{
|
||||
try
|
||||
{
|
||||
if (username != string.Empty && email != string.Empty && ValidateProfiles())
|
||||
if (username != string.Empty && email != string.Empty)
|
||||
{
|
||||
if (_password == confirm)
|
||||
{
|
||||
if (ValidateProfiles())
|
||||
{
|
||||
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
|
@ -271,6 +287,7 @@ else
|
|||
AddModuleMessage(Localizer["Message.Password.Complexity"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage(Localizer["Message.Password.NoMatch"], MessageType.Warning);
|
||||
|
@ -290,7 +307,6 @@ else
|
|||
|
||||
private bool ValidateProfiles()
|
||||
{
|
||||
bool valid = true;
|
||||
foreach (Profile profile in profiles)
|
||||
{
|
||||
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||
|
@ -299,18 +315,24 @@ else
|
|||
}
|
||||
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||
{
|
||||
if (valid == true && profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||
{
|
||||
valid = false;
|
||||
AddModuleMessage(string.Format(SharedLocalizer["ProfileRequired"], profile.Title), MessageType.Warning);
|
||||
return false;
|
||||
}
|
||||
if (valid == true && !string.IsNullOrEmpty(profile.Validation))
|
||||
if (!string.IsNullOrEmpty(profile.Validation))
|
||||
{
|
||||
Regex regex = new Regex(profile.Validation);
|
||||
valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
|
||||
bool valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
|
||||
if (!valid)
|
||||
{
|
||||
AddModuleMessage(string.Format(SharedLocalizer["ProfileInvalid"], profile.Title), MessageType.Warning);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||
|
|
|
@ -17,21 +17,10 @@ else
|
|||
{
|
||||
<TabStrip>
|
||||
<TabPanel Name="Users" Heading="Users" ResourceKey="Users">
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<div class="col-sm-4">
|
||||
<ActionLink Action="Add" Text="Add User" Security="SecurityAccessLevel.Edit" ResourceKey="AddUser" />
|
||||
<ActionLink Text="Import Users" Class="btn btn-secondary" Action="Users" Security="SecurityAccessLevel.Admin" ResourceKey="ImportUsers"/>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<input class="form-control" @bind="@_search" />
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" class="btn btn-secondary" @onclick="OnSearch">@SharedLocalizer["Search"]</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Pager Items="@users" RowClass="align-middle">
|
||||
<ActionLink Text="Import Users" Class="btn btn-secondary ms-2" Action="Users" Security="SecurityAccessLevel.Admin" ResourceKey="ImportUsers"/>
|
||||
|
||||
<Pager Items="@users" RowClass="align-middle" SearchProperties="User.Username,User.Email,User.DisplayName">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
|
@ -262,6 +251,21 @@ else
|
|||
<input id="parameters" class="form-control" @bind="@_parameters" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="authresponsetype" HelpText="Specify the authorization response type" ResourceKey="AuthResponseType">Authorization Response Type</Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="authresponsetype" class="form-select" @bind="@_authresponsetype" required>
|
||||
<option value="code">@Localizer["AuthFlow.Code"]</option>
|
||||
<option value="code id_token">@Localizer["AuthFlow.CodeIdToken"]</option>
|
||||
<option value="code id_token token">@Localizer["AuthFlow.CodeIdTokenToken"]</option>
|
||||
<option value="code token">@Localizer["AuthFlow.CodeToken"]</option>
|
||||
<option value="id_token">@Localizer["AuthFlow.IdToken"]</option>
|
||||
<option value="id_token token">@Localizer["AuthFlow.IdTokenToken"]</option>
|
||||
<option value="token">@Localizer["AuthFlow.Token"]</option>
|
||||
<option value="none">@Localizer["AuthFlow.None"]</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="pkce" HelpText="Indicate if the provider supports Proof Key for Code Exchange (PKCE)" ResourceKey="PKCE">Use PKCE?</Label>
|
||||
<div class="col-sm-9">
|
||||
|
@ -368,9 +372,7 @@ else
|
|||
}
|
||||
|
||||
@code {
|
||||
private List<UserRole> allusers;
|
||||
private List<UserRole> users;
|
||||
private string _search = "";
|
||||
|
||||
private string _allowregistration;
|
||||
private string _allowsitelogin;
|
||||
|
@ -400,6 +402,7 @@ else
|
|||
private string _scopes;
|
||||
private string _parameters;
|
||||
private string _pkce;
|
||||
private string _authresponsetype;
|
||||
private string _redirecturl;
|
||||
private string _identifierclaimtype;
|
||||
private string _emailclaimtype;
|
||||
|
@ -423,7 +426,6 @@ else
|
|||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadUserSettingsAsync();
|
||||
await LoadUsersAsync(true);
|
||||
|
||||
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
||||
|
@ -458,6 +460,7 @@ else
|
|||
_scopes = SettingService.GetSetting(settings, "ExternalLogin:Scopes", "");
|
||||
_parameters = SettingService.GetSetting(settings, "ExternalLogin:Parameters", "");
|
||||
_pkce = SettingService.GetSetting(settings, "ExternalLogin:PKCE", "false");
|
||||
_authresponsetype = SettingService.GetSetting(settings, "ExternalLogin:AuthResponseType", "code");
|
||||
_redirecturl = PageState.Uri.Scheme + "://" + PageState.Alias.Name + "/signin-" + _providertype;
|
||||
_identifierclaimtype = SettingService.GetSetting(settings, "ExternalLogin:IdentifierClaimType", "sub");
|
||||
_emailclaimtype = SettingService.GetSetting(settings, "ExternalLogin:EmailClaimType", "email");
|
||||
|
@ -478,32 +481,14 @@ else
|
|||
{
|
||||
if (load)
|
||||
{
|
||||
allusers = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Registered);
|
||||
users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Registered);
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
var hosts = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Host);
|
||||
allusers.AddRange(hosts);
|
||||
allusers = allusers.OrderBy(u => u.User.DisplayName).ToList();
|
||||
users.AddRange(hosts);
|
||||
users = users.OrderBy(u => u.User.DisplayName).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
users = allusers;
|
||||
if (!string.IsNullOrEmpty(_search))
|
||||
{
|
||||
users = users.Where(item =>
|
||||
(
|
||||
item.User.Username.Contains(_search, StringComparison.OrdinalIgnoreCase) ||
|
||||
item.User.Email.Contains(_search, StringComparison.OrdinalIgnoreCase) ||
|
||||
item.User.DisplayName.Contains(_search, StringComparison.OrdinalIgnoreCase)
|
||||
)
|
||||
).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnSearch()
|
||||
{
|
||||
await UpdateUserSettingsAsync();
|
||||
await LoadUsersAsync(false);
|
||||
}
|
||||
|
||||
private async Task DeleteUser(UserRole UserRole)
|
||||
|
@ -526,21 +511,6 @@ else
|
|||
}
|
||||
}
|
||||
|
||||
private string settingSearch = "AU-search";
|
||||
|
||||
private async Task LoadUserSettingsAsync()
|
||||
{
|
||||
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
||||
_search = SettingService.GetSetting(settings, settingSearch, "");
|
||||
}
|
||||
|
||||
private async Task UpdateUserSettingsAsync()
|
||||
{
|
||||
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
||||
settings = SettingService.SetSetting(settings, settingSearch, _search);
|
||||
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
|
||||
}
|
||||
|
||||
private async Task SaveSiteSettings()
|
||||
{
|
||||
try
|
||||
|
@ -579,6 +549,7 @@ else
|
|||
settings = SettingService.SetSetting(settings, "ExternalLogin:Scopes", _scopes, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:Parameters", _parameters, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:PKCE", _pkce, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:AuthResponseType", _authresponsetype, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:IdentifierClaimType", _identifierclaimtype, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:EmailClaimType", _emailclaimtype, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:RoleClaimType", _roleclaimtype, true);
|
||||
|
|
|
@ -40,6 +40,13 @@
|
|||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetFileId() != -1 && !UploadMultiple)
|
||||
{
|
||||
<input class="form-control" @bind="@_file.Name" disabled />
|
||||
}
|
||||
}
|
||||
@if (ShowUpload && _haseditpermission)
|
||||
{
|
||||
<div class="row">
|
||||
|
@ -55,7 +62,7 @@
|
|||
</div>
|
||||
<div class="col mt-2 text-end">
|
||||
<button type="button" class="btn btn-success" @onclick="UploadFiles">@SharedLocalizer["Upload"]</button>
|
||||
@if (GetFileId() != -1)
|
||||
@if (GetFileId() != -1 && !UploadMultiple)
|
||||
{
|
||||
<button type="button" class="btn btn-danger mx-1" @onclick="DeleteFile">@SharedLocalizer["Delete"]</button>
|
||||
}
|
||||
|
@ -371,7 +378,7 @@
|
|||
success = false;
|
||||
var filename = uploads[upload].Split(':')[0];
|
||||
var size = Int64.Parse(uploads[upload].Split(':')[1]);
|
||||
var maxattempts = (int)Math.Ceiling(size / 500000.0) + 1; // 30 MB takes 1 minute at 5 Mbps
|
||||
var maxattempts = (int)Math.Ceiling(size / 500000.0) + 4; // 30 MB takes 1 minute at 5 Mbps (min 5 attempts)
|
||||
|
||||
int attempts = 0;
|
||||
while (attempts < maxattempts && !success)
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleControlBase
|
||||
@inject IStringLocalizerFactory LocalizerFactory
|
||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||
@typeparam TableItem
|
||||
|
||||
@if (ItemList != null)
|
||||
{
|
||||
@if (!string.IsNullOrEmpty(SearchProperties))
|
||||
{
|
||||
<div class="input-group my-3">
|
||||
<input id="search" class="form-control" placeholder=@string.Format(Localizer["SearchPlaceholder"], FormatSearchProperties()) @bind="@_search" />
|
||||
<button type="button" class="btn btn-primary" @onclick="Search">@SharedLocalizer["Search"]</button>
|
||||
<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if ((Toolbar == "Top" || Toolbar == "Both") && _pages > 0 && Items.Count() > _maxItems)
|
||||
{
|
||||
<ul class="pagination justify-content-center my-2">
|
||||
|
@ -175,6 +185,9 @@
|
|||
private int _startPage = 0;
|
||||
private int _endPage = 0;
|
||||
private int _columns = 0;
|
||||
private string _search = "";
|
||||
|
||||
private IEnumerable<TableItem> AllItems;
|
||||
|
||||
[Parameter]
|
||||
public string Format { get; set; } // Table or Grid
|
||||
|
@ -221,6 +234,9 @@
|
|||
[Parameter]
|
||||
public Action<int> OnPageChange { get; set; } // a method to be executed in the calling component when the page changes
|
||||
|
||||
[Parameter]
|
||||
public string SearchProperties { get; set; } // comma delimited list of property names to include in search
|
||||
|
||||
private IEnumerable<TableItem> ItemList { get; set; }
|
||||
|
||||
protected override void OnInitialized()
|
||||
|
@ -276,6 +292,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(SearchProperties))
|
||||
{
|
||||
AllItems = Items; // only used in search
|
||||
if (!string.IsNullOrEmpty(_search))
|
||||
{
|
||||
Search();
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(PageSize))
|
||||
{
|
||||
_maxItems = int.Parse(PageSize);
|
||||
|
@ -369,4 +394,75 @@
|
|||
|
||||
UpdateList(_page);
|
||||
}
|
||||
|
||||
public void Search()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_search))
|
||||
{
|
||||
Items = AllItems.Where(item =>
|
||||
{
|
||||
var values = SearchProperties.Split(',')
|
||||
.Select(itemType => GetPropertyValue(item, itemType))
|
||||
.Where(value => value != null)
|
||||
.Select(value => value.ToString().ToLower());
|
||||
|
||||
return values.Any(value => value.Contains(_search.ToLower()));
|
||||
}).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
Items = AllItems;
|
||||
}
|
||||
_pages = (int)Math.Ceiling(Items.Count() / (decimal)_maxItems);
|
||||
UpdateList(1);
|
||||
}
|
||||
|
||||
private object GetPropertyValue(object obj, string propertyName)
|
||||
{
|
||||
var index = propertyName.IndexOf(".");
|
||||
if (index != -1)
|
||||
{
|
||||
var propertyInfo = obj.GetType().GetProperty(propertyName.Substring(0, index));
|
||||
if (propertyInfo != null)
|
||||
{
|
||||
return GetPropertyValue(propertyInfo.GetValue(obj), propertyName.Substring(index + 1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
var propertyInfo = obj.GetType().GetProperty(propertyName);
|
||||
if (propertyInfo != null)
|
||||
{
|
||||
return propertyInfo.GetValue(obj);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_search = "";
|
||||
Items = AllItems;
|
||||
_pages = (int)Math.Ceiling(Items.Count() / (decimal)_maxItems);
|
||||
UpdateList(1);
|
||||
}
|
||||
|
||||
private string FormatSearchProperties()
|
||||
{
|
||||
var properties = new List<string>();
|
||||
foreach (var property in SearchProperties.Split(',', StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
var index = property.LastIndexOf(".");
|
||||
if (index != -1)
|
||||
{
|
||||
properties.Add(property.Substring(index + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
properties.Add(property);
|
||||
}
|
||||
}
|
||||
return string.Join(",", properties);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>net7.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>4.0.5</Version>
|
||||
<Version>4.0.6</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
|
|
|
@ -159,4 +159,10 @@
|
|||
<data name="Module Settings" xml:space="preserve">
|
||||
<value>Module Settings</value>
|
||||
</data>
|
||||
<data name="Pane.HelpText" xml:space="preserve">
|
||||
<value>The pane where the module will be displayed</value>
|
||||
</data>
|
||||
<data name="Pane.Text" xml:space="preserve">
|
||||
<value>Pane:</value>
|
||||
</data>
|
||||
</root>
|
|
@ -408,4 +408,31 @@
|
|||
<data name="ImportUsers.Text" xml:space="preserve">
|
||||
<value>Import Users</value>
|
||||
</data>
|
||||
<data name="AuthFlow.Code" xml:space="preserve">
|
||||
<value>code</value>
|
||||
</data>
|
||||
<data name="AuthFlow.CodeIdToken" xml:space="preserve">
|
||||
<value>code id_token</value>
|
||||
</data>
|
||||
<data name="AuthFlow.CodeIdTokenToken" xml:space="preserve">
|
||||
<value>code id_token token</value>
|
||||
</data>
|
||||
<data name="AuthFlow.CodeToken" xml:space="preserve">
|
||||
<value>code token</value>
|
||||
</data>
|
||||
<data name="AuthFlow.IdToken" xml:space="preserve">
|
||||
<value>id_token</value>
|
||||
</data>
|
||||
<data name="AuthFlow.IdTokenToken" xml:space="preserve">
|
||||
<value>id_token token</value>
|
||||
</data>
|
||||
<data name="AuthFlow.None" xml:space="preserve">
|
||||
<value>none</value>
|
||||
</data>
|
||||
<data name="AuthFlow.Token" xml:space="preserve">
|
||||
<value>token</value>
|
||||
</data>
|
||||
<data name="AuthResponseType" xml:space="preserve">
|
||||
<value>Authorization Response Type</value>
|
||||
</data>
|
||||
</root>
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
@ -120,4 +120,7 @@
|
|||
<data name="PageOfPages" xml:space="preserve">
|
||||
<value>Page {0} of {1}</value>
|
||||
</data>
|
||||
<data name="SearchPlaceholder" xml:space="preserve">
|
||||
<value>Search: {0}</value>
|
||||
</data>
|
||||
</root>
|
|
@ -426,4 +426,10 @@
|
|||
<data name="Password.ValidationCriteria" xml:space="preserve">
|
||||
<value>Passwords Must Have A Minimum Length Of {0} Characters, Including At Least {1} Unique Character(s), {2}{3}{4}{5} To Satisfy Password Compexity Requirements For This Site.</value>
|
||||
</data>
|
||||
<data name="ProfileInvalid" xml:space="preserve">
|
||||
<value>{0} Is Not Valid</value>
|
||||
</data>
|
||||
<data name="ProfileRequired" xml:space="preserve">
|
||||
<value>{0} Is Required</value>
|
||||
</data>
|
||||
</root>
|
|
@ -189,4 +189,13 @@
|
|||
<data name="Confirm.Page.Delete" xml:space="preserve">
|
||||
<value>Are You Sure You Want To Delete This Page?</value>
|
||||
</data>
|
||||
<data name="Location" xml:space="preserve">
|
||||
<value>Location:</value>
|
||||
</data>
|
||||
<data name="LocationBottom" xml:space="preserve">
|
||||
<value>Bottom</value>
|
||||
</data>
|
||||
<data name="LocationTop" xml:space="preserve">
|
||||
<value>Top</value>
|
||||
</data>
|
||||
</root>
|
|
@ -4,6 +4,7 @@ using System.Net.Http;
|
|||
using System;
|
||||
using Oqtane.Documentation;
|
||||
using Oqtane.Shared;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
|
@ -18,7 +19,7 @@ namespace Oqtane.Services
|
|||
/// <inheritdoc />
|
||||
public async Task<Sync> GetSyncEventsAsync(DateTime lastSyncDate)
|
||||
{
|
||||
return await GetJsonAsync<Sync>($"{ApiUrl}/{lastSyncDate.ToString("yyyyMMddHHmmssfff")}");
|
||||
return await GetJsonAsync<Sync>($"{ApiUrl}/{lastSyncDate.ToString("yyyyMMddHHmmssfff", CultureInfo.InvariantCulture)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
<div class="main g-0">
|
||||
<div class="top-row px-4">
|
||||
<div class="ms-auto"><UserProfile /> <Login /> <ControlPanel /></div>
|
||||
<div class="ms-auto"><UserProfile /> <Login /> <ControlPanel LanguageDropdownAlignment="right" /></div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row px-4">
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
@if (ShowLanguageSwitcher)
|
||||
{
|
||||
<LanguageSwitcher />
|
||||
<LanguageSwitcher DropdownAlignment="@LanguageDropdownAlignment" />
|
||||
}
|
||||
|
||||
@if (_showEditMode || (PageState.Page.IsPersonalizable && PageState.User != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Registered)))
|
||||
|
@ -183,8 +183,6 @@
|
|||
<input type="text" name="Title" class="form-control" @bind="@Title" />
|
||||
</div>
|
||||
</div>
|
||||
@if (_pane.Length > 1)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<label for="Pane" class="control-label">@Localizer["Pane"]</label>
|
||||
|
@ -196,7 +194,15 @@
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<label for="Insert" class="control-label">@Localizer["Location"]</label>
|
||||
<select class="form-select" @bind="@Location">
|
||||
<option value="@int.MinValue">@Localizer["LocationTop"]</option>
|
||||
<option value="@int.MaxValue">@Localizer["LocationBottom"]</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<label for="Container" class="control-label">@Localizer["Container"]</label>
|
||||
|
@ -233,6 +239,24 @@
|
|||
}
|
||||
|
||||
@code{
|
||||
[Parameter]
|
||||
public string ButtonClass { get; set; } = "btn-outline-secondary";
|
||||
|
||||
[Parameter]
|
||||
public string ContainerClass { get; set; } = "offcanvas offcanvas-end";
|
||||
|
||||
[Parameter]
|
||||
public string HeaderClass { get; set; } = "offcanvas-header";
|
||||
|
||||
[Parameter]
|
||||
public string BodyClass { get; set; } = "offcanvas-body overflow-auto";
|
||||
|
||||
[Parameter]
|
||||
public bool ShowLanguageSwitcher { get; set; } = true;
|
||||
|
||||
[Parameter]
|
||||
public string LanguageDropdownAlignment { get; set; } = string.Empty; // Empty or Left or Right
|
||||
|
||||
private bool _canViewAdminDashboard = false;
|
||||
private bool _showEditMode = false;
|
||||
private bool _deleteConfirmation = false;
|
||||
|
@ -243,6 +267,7 @@
|
|||
private List<Module> _modules = new List<Module>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private string _category = "Common";
|
||||
private string _pane = "";
|
||||
|
||||
protected string PageId { get; private set; } = "-";
|
||||
protected string ModuleId { get; private set; } = "-";
|
||||
|
@ -251,12 +276,12 @@
|
|||
|
||||
protected string Title { get; private set; } = "";
|
||||
protected string ContainerType { get; private set; } = "";
|
||||
protected int Location { get; private set; } = int.MaxValue;
|
||||
protected string Visibility { get; private set; } = "view";
|
||||
protected string Message { get; private set; } = "";
|
||||
|
||||
private string settingCategory = "CP-category";
|
||||
private string settingPane = "CP-pane";
|
||||
private string _pane = "";
|
||||
|
||||
protected string Category
|
||||
{
|
||||
|
@ -288,21 +313,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public string ButtonClass { get; set; } = "btn-outline-secondary";
|
||||
|
||||
[Parameter]
|
||||
public string ContainerClass { get; set; } = "offcanvas offcanvas-end";
|
||||
|
||||
[Parameter]
|
||||
public string HeaderClass { get; set; } = "offcanvas-header";
|
||||
|
||||
[Parameter]
|
||||
public string BodyClass { get; set; } = "offcanvas-body overflow-auto";
|
||||
|
||||
[Parameter]
|
||||
public bool ShowLanguageSwitcher { get; set; } = true;
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
_canViewAdminDashboard = CanViewAdminDashboard();
|
||||
|
@ -310,8 +320,9 @@
|
|||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList))
|
||||
{
|
||||
_showEditMode = true;
|
||||
_pages?.Clear();
|
||||
LoadSettingsAsync();
|
||||
|
||||
_pages?.Clear();
|
||||
foreach (Page p in PageState.Pages)
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||
|
@ -319,7 +330,6 @@
|
|||
_pages.Add(p);
|
||||
}
|
||||
}
|
||||
await LoadSettingsAsync();
|
||||
|
||||
var themes = await ThemeService.GetThemesAsync();
|
||||
_containers = ThemeService.GetContainerControls(themes, PageState.Page.ThemeType);
|
||||
|
@ -443,7 +453,7 @@
|
|||
}
|
||||
|
||||
pageModule.Pane = Pane;
|
||||
pageModule.Order = int.MaxValue;
|
||||
pageModule.Order = Location;
|
||||
pageModule.ContainerType = ContainerType;
|
||||
|
||||
if (pageModule.ContainerType == PageState.Site.DefaultContainerType)
|
||||
|
@ -653,11 +663,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
private async Task LoadSettingsAsync()
|
||||
private void LoadSettingsAsync()
|
||||
{
|
||||
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
||||
_category = SettingService.GetSetting(settings, settingCategory, "Common");
|
||||
var pane = SettingService.GetSetting(settings, settingPane, "");
|
||||
_category = SettingService.GetSetting(PageState.User.Settings, settingCategory, "Common");
|
||||
var pane = SettingService.GetSetting(PageState.User.Settings, settingPane, "");
|
||||
if (PageState.Page.Panes.Contains(pane))
|
||||
{
|
||||
_pane = pane;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<button id="btnCultures" type="button" class="btn btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="oi oi-globe"></span>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="btnCultures">
|
||||
<div class="dropdown-menu @MenuAlignment" aria-labelledby="btnCultures">
|
||||
@foreach (var culture in _supportedCultures)
|
||||
{
|
||||
<a class="dropdown-item @(CultureInfo.CurrentUICulture.Name == culture.Name ? "active" : String.Empty)" href="#" @onclick="@(async e => await SetCultureAsync(culture.Name))">@culture.DisplayName</a>
|
||||
|
@ -23,9 +23,14 @@
|
|||
|
||||
@code{
|
||||
private IEnumerable<Culture> _supportedCultures;
|
||||
[Parameter]
|
||||
public string DropdownAlignment { get; set; } = string.Empty; // Empty or Left or Right
|
||||
private string MenuAlignment = string.Empty;
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
MenuAlignment = DropdownAlignment.ToLower() == "right" ? "dropdown-menu-end" : string.Empty;
|
||||
|
||||
var languages = PageState.Languages;
|
||||
_supportedCultures = languages.Select(l => new Culture { Name = l.Code, DisplayName = l.Name });
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<nav class="navbar navbar-dark bg-primary fixed-top">
|
||||
<Logo /><Menu Orientation="Horizontal" />
|
||||
<div class="controls ms-auto">
|
||||
<div class="controls-group"><UserProfile ShowRegister="@_register" /> <Login ShowLogin="@_login" /> <ControlPanel /></div>
|
||||
<div class="controls-group"><UserProfile ShowRegister="@_register" /> <Login ShowLogin="@_login" /> <ControlPanel LanguageDropdownAlignment="right" /></div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="content">
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Version>4.0.5</Version>
|
||||
<Version>4.0.6</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -10,7 +10,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Database.MySQL</id>
|
||||
<version>4.0.5</version>
|
||||
<version>4.0.6</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane MySQL Provider</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Version>4.0.5</Version>
|
||||
<Version>4.0.6</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -10,7 +10,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Database.PostgreSQL</id>
|
||||
<version>4.0.5</version>
|
||||
<version>4.0.6</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane PostgreSQL Provider</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Version>4.0.5</Version>
|
||||
<Version>4.0.6</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -10,7 +10,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Database.SqlServer</id>
|
||||
<version>4.0.5</version>
|
||||
<version>4.0.6</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane SQL Server Provider</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Version>4.0.5</Version>
|
||||
<Version>4.0.6</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -10,7 +10,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Database.Sqlite</id>
|
||||
<version>4.0.5</version>
|
||||
<version>4.0.6</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane SQLite Provider</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<!-- <TargetFrameworks>net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks> -->
|
||||
<!-- <TargetFrameworks>$(TargetFrameworks);net7.0-tizen</TargetFrameworks> -->
|
||||
<OutputType>Exe</OutputType>
|
||||
<Version>4.0.5</Version>
|
||||
<Version>4.0.6</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -14,7 +14,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane.Maui</RootNamespace>
|
||||
|
@ -31,7 +31,7 @@
|
|||
<ApplicationIdGuid>0E29FC31-1B83-48ED-B6E0-9F3C67B775D4</ApplicationIdGuid>
|
||||
|
||||
<!-- Versions -->
|
||||
<ApplicationDisplayVersion>4.0.5</ApplicationDisplayVersion>
|
||||
<ApplicationDisplayVersion>4.0.6</ApplicationDisplayVersion>
|
||||
<ApplicationVersion>1</ApplicationVersion>
|
||||
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Client</id>
|
||||
<version>4.0.5</version>
|
||||
<version>4.0.6</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Framework</id>
|
||||
<version>4.0.5</version>
|
||||
<version>4.0.6</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -11,8 +11,8 @@
|
|||
<copyright>.NET Foundation</copyright>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v4.0.5/Oqtane.Framework.4.0.5.Upgrade.zip</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</releaseNotes>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v4.0.6/Oqtane.Framework.4.0.6.Upgrade.zip</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane framework</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Server</id>
|
||||
<version>4.0.5</version>
|
||||
<version>4.0.6</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Shared</id>
|
||||
<version>4.0.5</version>
|
||||
<version>4.0.6</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Updater</id>
|
||||
<version>4.0.5</version>
|
||||
<version>4.0.6</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -1 +1 @@
|
|||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net7.0\publish\*" -DestinationPath "Oqtane.Framework.4.0.5.Install.zip" -Force
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net7.0\publish\*" -DestinationPath "Oqtane.Framework.4.0.6.Install.zip" -Force
|
|
@ -1 +1 @@
|
|||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net7.0\publish\*" -DestinationPath "Oqtane.Framework.4.0.5.Upgrade.zip" -Force
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net7.0\publish\*" -DestinationPath "Oqtane.Framework.4.0.6.Upgrade.zip" -Force
|
|
@ -44,7 +44,7 @@ namespace Oqtane.Extensions
|
|||
options.SaveTokens = false;
|
||||
options.GetClaimsFromUserInfoEndpoint = true;
|
||||
options.CallbackPath = string.IsNullOrEmpty(alias.Path) ? "/signin-" + AuthenticationProviderTypes.OpenIDConnect : "/" + alias.Path + "/signin-" + AuthenticationProviderTypes.OpenIDConnect;
|
||||
options.ResponseType = OpenIdConnectResponseType.Code; // authorization code flow
|
||||
options.ResponseType = sitesettings.GetValue("ExternalLogin:AuthResponseType", "code"); // authorization code flow
|
||||
options.ResponseMode = OpenIdConnectResponseMode.FormPost; // recommended as most secure
|
||||
|
||||
// cookie config is required to avoid Correlation Failed errors
|
||||
|
|
29
Oqtane.Server/Migrations/Tenant/04000601_AddProfileRows.cs
Normal file
29
Oqtane.Server/Migrations/Tenant/04000601_AddProfileRows.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Oqtane.Databases.Interfaces;
|
||||
using Oqtane.Migrations.EntityBuilders;
|
||||
using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Migrations.Tenant
|
||||
{
|
||||
[DbContext(typeof(TenantDBContext))]
|
||||
[Migration("Tenant.04.00.06.01")]
|
||||
public class AddProfileRows : MultiDatabaseMigration
|
||||
{
|
||||
public AddProfileRows(IDatabase database) : base(database)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||
profileEntityBuilder.AddIntegerColumn("Rows", true);
|
||||
profileEntityBuilder.UpdateColumn("Rows", "1");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// not implemented
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>4.0.5</Version>
|
||||
<Version>4.0.6</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -11,7 +11,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
|
|
|
@ -32,8 +32,9 @@ namespace Oqtane.Repository
|
|||
|
||||
public IEnumerable<File> GetFiles(int folderId, bool tracking)
|
||||
{
|
||||
var alias = _tenants.GetAlias();
|
||||
IEnumerable<Permission> permissions = _permissions.GetPermissions(alias.SiteId, EntityNames.Folder, folderId).ToList();
|
||||
var folder = _folderRepository.GetFolder(folderId, false);
|
||||
IEnumerable<Permission> permissions = _permissions.GetPermissions(folder.SiteId, EntityNames.Folder, folderId).ToList();
|
||||
|
||||
IEnumerable<File> files;
|
||||
if (tracking)
|
||||
{
|
||||
|
@ -46,6 +47,7 @@ namespace Oqtane.Repository
|
|||
foreach (File file in files)
|
||||
{
|
||||
file.Folder.PermissionList = permissions.ToList();
|
||||
var alias = _tenants.GetAlias();
|
||||
file.Url = GetFileUrl(file, alias);
|
||||
}
|
||||
return files;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<Product>[Owner].Module.[Module]</Product>
|
||||
<Copyright>[Owner]</Copyright>
|
||||
<AssemblyName>[Owner].Module.[Module].Client.Oqtane</AssemblyName>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -73,5 +73,10 @@ namespace Oqtane.Models
|
|||
/// Optional RegExp validation expression
|
||||
/// </summary>
|
||||
public string Validation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional number of rows (textarea)
|
||||
/// </summary>
|
||||
public int Rows { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>4.0.5</Version>
|
||||
<Version>4.0.6</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -11,7 +11,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
|
|
|
@ -7,8 +7,8 @@ namespace Oqtane.Shared
|
|||
{
|
||||
public class Constants
|
||||
{
|
||||
public static readonly string Version = "4.0.5";
|
||||
public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5";
|
||||
public static readonly string Version = "4.0.6";
|
||||
public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5,4.0.6";
|
||||
public const string PackageId = "Oqtane.Framework";
|
||||
public const string ClientId = "Oqtane.Client";
|
||||
public const string UpdaterPackageId = "Oqtane.Updater";
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
using Oqtane.Models;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
@ -390,12 +388,19 @@ namespace Oqtane.Shared
|
|||
|
||||
public static string UrlCombine(params string[] segments)
|
||||
{
|
||||
segments = segments.Where(item => !string.IsNullOrEmpty(item) && item != "/" && item != "\\").ToArray();
|
||||
for (int i = 1; i < segments.Length; i++)
|
||||
var url = new List<string>();
|
||||
for (int i = 0; i < segments.Length; i++)
|
||||
{
|
||||
segments[i] = segments[i].Replace("\\", "/");
|
||||
if (!string.IsNullOrEmpty(segments[i]) && segments[i] != "/")
|
||||
{
|
||||
foreach (var segment in segments[i].Split('/', StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
url.Add(segment);
|
||||
}
|
||||
return string.Join("/", segments);
|
||||
}
|
||||
}
|
||||
return string.Join("/", url);
|
||||
}
|
||||
|
||||
public static bool IsPathValid(this Folder folder)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<Version>4.0.5</Version>
|
||||
<Version>4.0.6</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -11,7 +11,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Latest Release
|
||||
|
||||
[4.0.4](https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.4) was released on Sep 25, 2023 and is primarily focused on stabilization. This release includes 53 pull requests by 4 different contributors, pushing the total number of project commits all-time to over 4100. The Oqtane framework continues to evolve at a rapid pace to meet the needs of .NET developers.
|
||||
[4.0.5](https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5) was released on Sep 26, 2023 and is primarily focused on stabilization. This release includes 53 pull requests by 4 different contributors, pushing the total number of project commits all-time to over 4100. The Oqtane framework continues to evolve at a rapid pace to meet the needs of .NET developers.
|
||||
|
||||
[](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Foqtane%2Foqtane.framework%2Fmaster%2Fazuredeploy.json)
|
||||
|
||||
|
@ -53,6 +53,9 @@ Backlog (TBD)
|
|||
5.0.0 (Q4 2023)
|
||||
- [ ] Migration to .NET 8
|
||||
|
||||
[4.0.5](https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.5) ( Sep 26, 2023 )
|
||||
- [x] Stabilization improvements
|
||||
|
||||
[4.0.4](https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.4) ( Sep 25, 2023 )
|
||||
- [x] Stabilization improvements
|
||||
- [x] User Import
|
||||
|
|
Loading…
Reference in New Issue
Block a user