Added support for File descriptions, Folder capacity and image sizes. Added image resizing capability using ImageSharp - implemented in user profile. Added parameter to disable image preview in FileManager component. Overhauled Pager component and added Columns parameter for Grid mode. Populated PageState.User.IsAuthenticated in SiteRouter. Added support for zero price commercial extentions.
This commit is contained in:
parent
ba7524b754
commit
898b908c1b
|
@ -27,6 +27,12 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="description" HelpText="A description of the file. This can be used as a caption for image files." ResourceKey="Description">Description: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="description" class="form-control" @bind="@_description" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="size" HelpText="The size of the file (in bytes)" ResourceKey="Size">Size: </Label>
|
<Label Class="col-sm-3" For="size" HelpText="The size of the file (in bytes)" ResourceKey="Size">Size: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
|
@ -49,6 +55,7 @@
|
||||||
private string _name;
|
private string _name;
|
||||||
private List<Folder> _folders;
|
private List<Folder> _folders;
|
||||||
private int _folderId = -1;
|
private int _folderId = -1;
|
||||||
|
private string _description = string.Empty;
|
||||||
private int _size;
|
private int _size;
|
||||||
private string _createdBy;
|
private string _createdBy;
|
||||||
private DateTime _createdOn;
|
private DateTime _createdOn;
|
||||||
|
@ -70,6 +77,7 @@
|
||||||
{
|
{
|
||||||
_name = file.Name;
|
_name = file.Name;
|
||||||
_folderId = file.FolderId;
|
_folderId = file.FolderId;
|
||||||
|
_description = file.Description;
|
||||||
_size = file.Size;
|
_size = file.Size;
|
||||||
_createdBy = file.CreatedBy;
|
_createdBy = file.CreatedBy;
|
||||||
_createdOn = file.CreatedOn;
|
_createdOn = file.CreatedOn;
|
||||||
|
@ -97,6 +105,7 @@
|
||||||
File file = await FileService.GetFileAsync(_fileId);
|
File file = await FileService.GetFileAsync(_fileId);
|
||||||
file.Name = _name;
|
file.Name = _name;
|
||||||
file.FolderId = _folderId;
|
file.FolderId = _folderId;
|
||||||
|
file.Description = _description;
|
||||||
file = await FileService.UpdateFileAsync(file);
|
file = await FileService.UpdateFileAsync(file);
|
||||||
await logger.LogInformation("File Saved {File}", file);
|
await logger.LogInformation("File Saved {File}", file);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="name" HelpText="Enter the folder name" ResourceKey="Name">Name: </Label>
|
<Label Class="col-sm-3" For="name" HelpText="Enter the folder name" ResourceKey="Name">Name: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="name" class="form-control" @bind="@_name" maxlength="50" required />
|
<input id="name" class="form-control" @bind="@_name" maxlength="256" required />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
|
@ -47,6 +47,18 @@
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="imagesizes" HelpText="Enter a list of image sizes which can be generated dynamically from uploaded images (ie. 200x200,x200,200x)" ResourceKey="ImageSizes">Image Sizes: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="imagesizes" class="form-control" @bind="@_imagesizes" maxlength="512" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="capacity" HelpText="Enter the maximum folder capacity (in megabytes). Specify zero if the capacity is unlimited." ResourceKey="Capacity">Capacity: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="capacity" class="form-control" @bind="@_capacity" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<Label Class="col-sm-3" For="permissions" HelpText="Select the permissions you want for the folder" ResourceKey="Permissions">Permissions: </Label>
|
<Label Class="col-sm-3" For="permissions" HelpText="Select the permissions you want for the folder" ResourceKey="Permissions">Permissions: </Label>
|
||||||
|
@ -84,6 +96,8 @@
|
||||||
private int _parentId = -1;
|
private int _parentId = -1;
|
||||||
private string _name;
|
private string _name;
|
||||||
private string _type = FolderTypes.Private;
|
private string _type = FolderTypes.Private;
|
||||||
|
private string _imagesizes = string.Empty;
|
||||||
|
private string _capacity = "0";
|
||||||
private bool _isSystem;
|
private bool _isSystem;
|
||||||
private string _permissions = string.Empty;
|
private string _permissions = string.Empty;
|
||||||
private string _createdBy;
|
private string _createdBy;
|
||||||
|
@ -114,6 +128,8 @@
|
||||||
_parentId = folder.ParentId ?? -1;
|
_parentId = folder.ParentId ?? -1;
|
||||||
_name = folder.Name;
|
_name = folder.Name;
|
||||||
_type = folder.Type;
|
_type = folder.Type;
|
||||||
|
_imagesizes = folder.ImageSizes;
|
||||||
|
_capacity = folder.Capacity.ToString();
|
||||||
_isSystem = folder.IsSystem;
|
_isSystem = folder.IsSystem;
|
||||||
_permissions = folder.Permissions;
|
_permissions = folder.Permissions;
|
||||||
_createdBy = folder.CreatedBy;
|
_createdBy = folder.CreatedBy;
|
||||||
|
@ -125,7 +141,6 @@
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_parentId = _folders[0].FolderId;
|
_parentId = _folders[0].FolderId;
|
||||||
_permissions = string.Empty;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -178,6 +193,8 @@
|
||||||
|
|
||||||
folder.Name = _name;
|
folder.Name = _name;
|
||||||
folder.Type = _type;
|
folder.Type = _type;
|
||||||
|
folder.ImageSizes = _imagesizes;
|
||||||
|
folder.Capacity = int.Parse(_capacity);
|
||||||
folder.IsSystem = _isSystem;
|
folder.IsSystem = _isSystem;
|
||||||
folder.Permissions = _permissionGrid.GetPermissions();
|
folder.Permissions = _permissionGrid.GetPermissions();
|
||||||
|
|
||||||
|
|
|
@ -83,15 +83,15 @@ else
|
||||||
@((MarkupString)(context.TrialPeriod > 0 ? " | <strong>" + context.TrialPeriod + " " + @SharedLocalizer["Trial"] + "</strong>" : ""))
|
@((MarkupString)(context.TrialPeriod > 0 ? " | <strong>" + context.TrialPeriod + " " + @SharedLocalizer["Trial"] + "</strong>" : ""))
|
||||||
</td>
|
</td>
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
<td style="width: 1px; vertical-align: middle;">
|
||||||
@if (context.Price > 0 && !string.IsNullOrEmpty(context.PackageUrl))
|
@if (context.Price != null && !string.IsNullOrEmpty(context.PackageUrl))
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
<td style="width: 1px; vertical-align: middle;">
|
||||||
@if (context.Price > 0 && !string.IsNullOrEmpty(context.PaymentUrl))
|
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
||||||
{
|
{
|
||||||
<a class="btn btn-primary" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@context.Price.ToString("$#,##0.00")</a>
|
<a class="btn btn-primary" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@context.Price.Value.ToString("$#,##0.00")</a>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,15 +40,15 @@
|
||||||
@((MarkupString)(context.TrialPeriod > 0 ? " | <strong>" + context.TrialPeriod + " " + @SharedLocalizer["Trial"] + "</strong>" : ""))
|
@((MarkupString)(context.TrialPeriod > 0 ? " | <strong>" + context.TrialPeriod + " " + @SharedLocalizer["Trial"] + "</strong>" : ""))
|
||||||
</td>
|
</td>
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
<td style="width: 1px; vertical-align: middle;">
|
||||||
@if (context.Price > 0 && !string.IsNullOrEmpty(context.PackageUrl))
|
@if (context.Price != null && !string.IsNullOrEmpty(context.PackageUrl))
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
<td style="width: 1px; vertical-align: middle;">
|
||||||
@if (context.Price > 0 && !string.IsNullOrEmpty(context.PaymentUrl))
|
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
||||||
{
|
{
|
||||||
<a class="btn btn-primary" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@context.Price.ToString("$#,##0.00")</a>
|
<a class="btn btn-primary" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@context.Price.Value.ToString("$#,##0.00")</a>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,15 +40,15 @@
|
||||||
@((MarkupString)(context.TrialPeriod > 0 ? " | <strong>" + context.TrialPeriod + " " + @SharedLocalizer["Trial"] + "</strong>" : ""))
|
@((MarkupString)(context.TrialPeriod > 0 ? " | <strong>" + context.TrialPeriod + " " + @SharedLocalizer["Trial"] + "</strong>" : ""))
|
||||||
</td>
|
</td>
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
<td style="width: 1px; vertical-align: middle;">
|
||||||
@if (context.Price > 0 && !string.IsNullOrEmpty(context.PackageUrl))
|
@if (context.Price != null && !string.IsNullOrEmpty(context.PackageUrl))
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
<td style="width: 1px; vertical-align: middle;">
|
||||||
@if (context.Price > 0 && !string.IsNullOrEmpty(context.PaymentUrl))
|
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
||||||
{
|
{
|
||||||
<a class="btn btn-primary" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@context.Price.ToString("$#,##0.00")</a>
|
<a class="btn btn-primary" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@context.Price.Value.ToString("$#,##0.00")</a>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,12 +6,13 @@
|
||||||
@inject ISettingService SettingService
|
@inject ISettingService SettingService
|
||||||
@inject INotificationService NotificationService
|
@inject INotificationService NotificationService
|
||||||
@inject IFileService FileService
|
@inject IFileService FileService
|
||||||
|
@inject IFolderService FolderService
|
||||||
@inject IStringLocalizer<Index> Localizer
|
@inject IStringLocalizer<Index> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
@if (PageState.User != null && photo != null)
|
@if (PageState.User != null && photo != null)
|
||||||
{
|
{
|
||||||
<img src="@photo.Url" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
|
<img src="@ImageUrl(photofileid, "400x400", "crop")" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -19,7 +20,7 @@ else
|
||||||
}
|
}
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Identity" ResourceKey="Identity">
|
<TabPanel Name="Identity" ResourceKey="Identity">
|
||||||
@if (PageState.User != null)
|
@if (profiles != null && settings != null)
|
||||||
{
|
{
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
|
@ -55,7 +56,7 @@ else
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="@photofileid.ToString()" HelpText="A photo of yourself" ResourceKey="Photo"></Label>
|
<Label Class="col-sm-3" For="@photofileid.ToString()" HelpText="A photo of yourself" ResourceKey="Photo"></Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<FileManager FileId="@photofileid" @ref="filemanager" />
|
<FileManager FileId="@photofileid" Filter="@Constants.ImageFiles" ShowFolders="false" ShowFiles="true" UploadMultiple="false" FolderId="@folderid" @ref="filemanager" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -67,8 +68,6 @@ else
|
||||||
<TabPanel Name="Profile" ResourceKey="Profile">
|
<TabPanel Name="Profile" ResourceKey="Profile">
|
||||||
@if (profiles != null && settings != null)
|
@if (profiles != null && settings != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@foreach (Profile profile in profiles)
|
@foreach (Profile profile in profiles)
|
||||||
|
@ -132,11 +131,11 @@ else
|
||||||
{
|
{
|
||||||
<Pager Items="@notifications">
|
<Pager Items="@notifications">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>@Localizer["From"]</th>
|
<th>@Localizer["From"]</th>
|
||||||
<th>@Localizer["Subject"]</th>
|
<th>@Localizer["Subject"]</th>
|
||||||
<th>@Localizer["Received"]</th>
|
<th>@Localizer["Received"]</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" /></td>
|
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" /></td>
|
||||||
|
@ -165,11 +164,11 @@ else
|
||||||
{
|
{
|
||||||
<Pager Items="@notifications">
|
<Pager Items="@notifications">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
<th>@Localizer["To"]</th>
|
<th>@Localizer["To"]</th>
|
||||||
<th>@Localizer["Subject"]</th>
|
<th>@Localizer["Subject"]</th>
|
||||||
<th>@Localizer["Sent"]</th>
|
<th>@Localizer["Sent"]</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" /></td>
|
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" /></td>
|
||||||
|
@ -210,6 +209,7 @@ else
|
||||||
private string email = string.Empty;
|
private string email = string.Empty;
|
||||||
private string displayname = string.Empty;
|
private string displayname = string.Empty;
|
||||||
private FileManager filemanager;
|
private FileManager filemanager;
|
||||||
|
private int folderid = -1;
|
||||||
private int photofileid = -1;
|
private int photofileid = -1;
|
||||||
private File photo = null;
|
private File photo = null;
|
||||||
private List<Profile> profiles;
|
private List<Profile> profiles;
|
||||||
|
@ -230,6 +230,13 @@ else
|
||||||
email = PageState.User.Email;
|
email = PageState.User.Email;
|
||||||
displayname = PageState.User.DisplayName;
|
displayname = PageState.User.DisplayName;
|
||||||
|
|
||||||
|
// get user folder
|
||||||
|
var folder = await FolderService.GetFolderAsync(ModuleState.SiteId, PageState.User.FolderPath);
|
||||||
|
if (folder != null)
|
||||||
|
{
|
||||||
|
folderid = folder.FolderId;
|
||||||
|
}
|
||||||
|
|
||||||
if (PageState.User.PhotoFileId != null)
|
if (PageState.User.PhotoFileId != null)
|
||||||
{
|
{
|
||||||
photofileid = PageState.User.PhotoFileId.Value;
|
photofileid = PageState.User.PhotoFileId.Value;
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@if (_image != string.Empty)
|
@if (_image != string.Empty && ShowImage)
|
||||||
{
|
{
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
@((MarkupString) _image)
|
@((MarkupString) _image)
|
||||||
|
@ -110,6 +110,9 @@
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public bool ShowFolders { get; set; } = true; // optional - for indicating whether a list of folders should be displayed - default is true
|
public bool ShowFolders { get; set; } = true; // optional - for indicating whether a list of folders should be displayed - default is true
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public bool ShowImage { get; set; } = true; // optional - for indicating whether an image thumbnail should be displayed - default is true
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public int FileId { get; set; } = -1; // optional - for setting a specific file by default
|
public int FileId { get; set; } = -1; // optional - for setting a specific file by default
|
||||||
|
|
||||||
|
|
|
@ -2,68 +2,57 @@
|
||||||
@inherits ModuleControlBase
|
@inherits ModuleControlBase
|
||||||
@typeparam TableItem
|
@typeparam TableItem
|
||||||
|
|
||||||
<p>
|
@if (ItemList != null)
|
||||||
@if (Toolbar == "Top")
|
{
|
||||||
|
@if (Toolbar == "Top" && _pages > 0 && Items.Count() > _maxItems)
|
||||||
{
|
{
|
||||||
<ul class="pagination justify-content-center my-2">
|
<ul class="pagination justify-content-center my-2">
|
||||||
@if (_endPage > 1)
|
<li class="page-item@((_page > 1) ? "" : " disabled")">
|
||||||
|
<a class="page-link" @onclick=@(async () => UpdateList(1))><span class="oi oi-media-step-backward" title="start" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
|
@if (_pages > _displayPages)
|
||||||
{
|
{
|
||||||
<li class="page-item">
|
<li class="page-item@((_page > _displayPages) ? "" : " disabled")">
|
||||||
<a class="page-link" @onclick=@(async () => UpdateList(1))><span class="oi oi-media-step-backward" title="first" aria-hidden="true"></span></a>
|
<a class="page-link" @onclick=@(async () => SkipPages("back"))><span class="oi oi-media-skip-backward" title="skip back" aria-hidden="true"></span></a>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
@if (_page > _maxPages)
|
<li class="page-item@((_page > 1) ? "" : " disabled")">
|
||||||
|
<a class="page-link" @onclick=@(async () => NavigateToPage("previous"))><span class="oi oi-chevron-left" title="previous" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
|
@for (int i = _startPage; i <= _endPage; i++)
|
||||||
{
|
{
|
||||||
<li class="page-item">
|
var pager = i;
|
||||||
<a class="page-link" @onclick=@(async () => SetPagerSize("back"))><span class="oi oi-media-skip-backward" title="back" aria-hidden="true"></span></a>
|
if (pager == _page)
|
||||||
</li>
|
|
||||||
}
|
|
||||||
@if (_endPage > 1)
|
|
||||||
{
|
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" @onclick=@(async () => NavigateToPage("previous"))><span class="oi oi-chevron-left" title="previous" aria-hidden="true"></span></a>
|
|
||||||
</li>
|
|
||||||
@for (int i = _startPage; i <= _endPage; i++)
|
|
||||||
{
|
{
|
||||||
var pager = i;
|
<li class="page-item active">
|
||||||
if (pager == _page)
|
<a class="page-link" @onclick=@(async () => UpdateList(pager))>@pager</a>
|
||||||
{
|
</li>
|
||||||
<li class="page-item active">
|
}
|
||||||
<a class="page-link" @onclick=@(async () => UpdateList(pager))>@pager</a>
|
else
|
||||||
</li>
|
{
|
||||||
}
|
<li class="page-item">
|
||||||
else
|
<a class="page-link" @onclick=@(async () => UpdateList(pager))>@pager</a>
|
||||||
{
|
</li>
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" @onclick=@(async () => UpdateList(pager))>@pager</a>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></a>
|
|
||||||
</li>
|
|
||||||
}
|
}
|
||||||
@if (_endPage < _pages)
|
<li class="page-item@((_page < _pages) ? "" : " disabled")">
|
||||||
|
<a class="page-link" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
|
@if (_pages > _displayPages)
|
||||||
{
|
{
|
||||||
<li class="page-item">
|
<li class="page-item@((_endPage < _pages) ? "" : " disabled")">
|
||||||
<a class="page-link" @onclick=@(async () => SetPagerSize("forward"))><span class="oi oi-media-skip-forward" title="forward" aria-hidden="true"></span></a>
|
<a class="page-link" @onclick=@(async () => SkipPages("forward"))><span class="oi oi-media-skip-forward" title="skip forward" aria-hidden="true"></span></a>
|
||||||
</li>
|
|
||||||
}
|
|
||||||
@if (_endPage > 1)
|
|
||||||
{
|
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="last" aria-hidden="true"></span></a>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
@if (_endPage > 1)
|
|
||||||
{
|
|
||||||
<li class="page-item disabled">
|
|
||||||
<a class="page-link">Page @_page of @_pages</a>
|
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
|
<li class="page-item@((_page < _pages) ? "" : " disabled")">
|
||||||
|
<a class="page-link" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="end" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<a class="page-link">Page @_page of @_pages</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
}
|
}
|
||||||
@if (Format == "Table")
|
@if (Format == "Table" && Row != null)
|
||||||
{
|
{
|
||||||
<table class="@Class">
|
<table class="@Class">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -81,113 +70,125 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
}
|
}
|
||||||
@if (Format == "Grid")
|
@if (Format == "Grid" && Row != null)
|
||||||
{
|
{
|
||||||
|
int count = 0;
|
||||||
|
if (ItemList != null)
|
||||||
|
{
|
||||||
|
count = (int)Math.Ceiling(ItemList.Count() / (decimal)_columns) * _columns;
|
||||||
|
}
|
||||||
<div class="@Class">
|
<div class="@Class">
|
||||||
<div class="row">@Header</div>
|
@if (Header != null)
|
||||||
@foreach (var item in ItemList)
|
|
||||||
{
|
{
|
||||||
<div class="row">@Row(item)</div>
|
<div class="row"><div class="col">@Header</div></div>
|
||||||
@if (Detail != null)
|
}
|
||||||
{
|
@for (int row = 0; row < (count / _columns); row++)
|
||||||
<div class="row">@Detail(item)</div>
|
{
|
||||||
}
|
<div class="row">
|
||||||
|
@for (int col = 0; col < _columns; col++)
|
||||||
|
{
|
||||||
|
int index = (row * _columns) + col;
|
||||||
|
if (index < ItemList.Count())
|
||||||
|
{
|
||||||
|
<div class="col">@Row(ItemList.ElementAt(index))</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="col"> </div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (Toolbar == "Bottom")
|
@if (Toolbar == "Bottom" && _pages > 0 && Items.Count() > _maxItems)
|
||||||
{
|
{
|
||||||
<ul class="pagination justify-content-center my-2">
|
<ul class="pagination justify-content-center my-2">
|
||||||
@if (_endPage > 1)
|
<li class="page-item@((_page > 1) ? "" : " disabled")">
|
||||||
|
<a class="page-link" @onclick=@(async () => UpdateList(1))><span class="oi oi-media-step-backward" title="start" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
|
@if (_pages > _displayPages)
|
||||||
{
|
{
|
||||||
<li class="page-item">
|
<li class="page-item@((_page > _displayPages) ? "" : " disabled")">
|
||||||
<a class="page-link" @onclick=@(async () => UpdateList(1))><span class="oi oi-media-step-backward" title="first" aria-hidden="true"></span></a>
|
<a class="page-link" @onclick=@(async () => SkipPages("back"))><span class="oi oi-media-skip-backward" title="skip back" aria-hidden="true"></span></a>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
@if (_page > _maxPages)
|
<li class="page-item@((_page > 1) ? "" : " disabled")">
|
||||||
|
<a class="page-link" @onclick=@(async () => NavigateToPage("previous"))><span class="oi oi-chevron-left" title="previous" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
|
@for (int i = _startPage; i <= _endPage; i++)
|
||||||
{
|
{
|
||||||
<li class="page-item">
|
var pager = i;
|
||||||
<a class="page-link" @onclick=@(async () => SetPagerSize("back"))><span class="oi oi-media-skip-backward" title="back" aria-hidden="true"></span></a>
|
if (pager == _page)
|
||||||
</li>
|
|
||||||
}
|
|
||||||
@if (_endPage > 1)
|
|
||||||
{
|
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" @onclick=@(async () => NavigateToPage("previous"))><span class="oi oi-chevron-left" title="previous" aria-hidden="true"></span></a>
|
|
||||||
</li>
|
|
||||||
@for (int i = _startPage; i <= _endPage; i++)
|
|
||||||
{
|
{
|
||||||
var pager = i;
|
<li class="page-item active">
|
||||||
if (pager == _page)
|
<a class="page-link" @onclick=@(async () => UpdateList(pager))>@pager</a>
|
||||||
{
|
</li>
|
||||||
<li class="page-item active">
|
}
|
||||||
<a class="page-link" @onclick=@(async () => UpdateList(pager))>@pager</a>
|
else
|
||||||
</li>
|
{
|
||||||
}
|
<li class="page-item">
|
||||||
else
|
<a class="page-link" @onclick=@(async () => UpdateList(pager))>@pager</a>
|
||||||
{
|
</li>
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" @onclick=@(async () => UpdateList(pager))>@pager</a>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></a>
|
|
||||||
</li>
|
|
||||||
}
|
}
|
||||||
@if (_endPage < _pages)
|
<li class="page-item@((_page < _pages) ? "" : " disabled")">
|
||||||
|
<a class="page-link" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
|
@if (_pages > _displayPages)
|
||||||
{
|
{
|
||||||
<li class="page-item">
|
<li class="page-item@((_endPage < _pages) ? "" : " disabled")">
|
||||||
<a class="page-link" @onclick=@(async () => SetPagerSize("forward"))><span class="oi oi-media-skip-forward" title="forward" aria-hidden="true"></span></a>
|
<a class="page-link" @onclick=@(async () => SkipPages("forward"))><span class="oi oi-media-skip-forward" title="skip forward" aria-hidden="true"></span></a>
|
||||||
</li>
|
|
||||||
}
|
|
||||||
@if (_endPage > 1)
|
|
||||||
{
|
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="last" aria-hidden="true"></span></a>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
@if (_endPage > 1)
|
|
||||||
{
|
|
||||||
<li class="page-item disabled">
|
|
||||||
<a class="page-link">Page @_page of @_pages</a>
|
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
|
<li class="page-item@((_page < _pages) ? "" : " disabled")">
|
||||||
|
<a class="page-link" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="end" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<a class="page-link">Page @_page of @_pages</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
}
|
}
|
||||||
</p>
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private int _pages = 0;
|
private int _pages = 0;
|
||||||
private int _page = 1;
|
private int _page = 1;
|
||||||
private int _maxItems = 10;
|
private int _maxItems = 10;
|
||||||
private int _maxPages = 5;
|
private int _displayPages = 5;
|
||||||
private int _startPage = 0;
|
private int _startPage = 0;
|
||||||
private int _endPage = 0;
|
private int _endPage = 0;
|
||||||
|
private int _columns = 1;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Format { get; set; }
|
public string Format { get; set; } // Table or Grid
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Toolbar { get; set; }
|
public string Toolbar { get; set; } // Top or Bottom
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public RenderFragment Header { get; set; }
|
public RenderFragment Header { get; set; } = null;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public RenderFragment<TableItem> Row { get; set; }
|
public RenderFragment<TableItem> Row { get; set; } = null;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public RenderFragment<TableItem> Detail { get; set; }
|
public RenderFragment<TableItem> Detail { get; set; } = null; // only applicable to Table layouts
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public IEnumerable<TableItem> Items { get; set; }
|
public IEnumerable<TableItem> Items { get; set; } // the IEnumerable data source
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string PageSize { get; set; }
|
public string PageSize { get; set; } // number of items to display on a page
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string DisplayPages { get; set; }
|
public string Columns { get; set; } // only applicable to Grid layouts
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string CurrentPage { get; set; } // optional property to set the initial page to display
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string DisplayPages { get; set; } // maximum number of page numbers to display for user selection
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Class { get; set; }
|
public string Class { get; set; }
|
||||||
|
@ -223,86 +224,89 @@
|
||||||
_maxItems = int.Parse(PageSize);
|
_maxItems = int.Parse(PageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(DisplayPages))
|
if (!string.IsNullOrEmpty(Columns))
|
||||||
{
|
{
|
||||||
_maxPages = int.Parse(DisplayPages);
|
_columns = int.Parse(Columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(DisplayPages))
|
||||||
|
{
|
||||||
|
_displayPages = int.Parse(DisplayPages);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(CurrentPage))
|
||||||
|
{
|
||||||
|
_page = int.Parse(CurrentPage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_page = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_page = 1;
|
|
||||||
_startPage = 0;
|
_startPage = 0;
|
||||||
_endPage = 0;
|
_endPage = 0;
|
||||||
|
|
||||||
if (Items != null)
|
if (Items != null)
|
||||||
{
|
{
|
||||||
ItemList = Items.Skip((_page - 1) * _maxItems).Take(_maxItems);
|
|
||||||
_pages = (int)Math.Ceiling(Items.Count() / (decimal)_maxItems);
|
_pages = (int)Math.Ceiling(Items.Count() / (decimal)_maxItems);
|
||||||
|
if (_page > _pages)
|
||||||
|
{
|
||||||
|
_page = _pages;
|
||||||
|
}
|
||||||
|
ItemList = Items.Skip((_page - 1) * _maxItems).Take(_maxItems);
|
||||||
|
SetPagerSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPagerSize("forward");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateList(int currentPage)
|
public void SetPagerSize()
|
||||||
{
|
{
|
||||||
ItemList = Items.Skip((currentPage - 1) * _maxItems).Take(_maxItems);
|
_startPage = ((_page - 1) / _displayPages) * _displayPages + 1;
|
||||||
_page = currentPage;
|
_endPage = _startPage + _displayPages - 1;
|
||||||
|
if (_endPage > _pages)
|
||||||
|
{
|
||||||
|
_endPage = _pages;
|
||||||
|
}
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPagerSize(string direction)
|
public void UpdateList(int page)
|
||||||
{
|
{
|
||||||
if (direction == "forward")
|
ItemList = Items.Skip((page - 1) * _maxItems).Take(_maxItems);
|
||||||
{
|
_page = page;
|
||||||
if (_endPage + 1 < _pages)
|
SetPagerSize();
|
||||||
{
|
}
|
||||||
_startPage = _endPage + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_startPage = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_endPage + _maxPages < _pages)
|
public void SkipPages(string direction)
|
||||||
{
|
{
|
||||||
_endPage = _startPage + _maxPages - 1;
|
switch (direction)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_endPage = _pages;
|
|
||||||
}
|
|
||||||
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
else if (direction == "back")
|
|
||||||
{
|
{
|
||||||
_endPage = _startPage - 1;
|
case "forward":
|
||||||
_startPage = _startPage - _maxPages;
|
_page = _endPage + 1;
|
||||||
|
break;
|
||||||
|
case "back":
|
||||||
|
_page = _startPage - 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetPagerSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void NavigateToPage(string direction)
|
public void NavigateToPage(string direction)
|
||||||
{
|
{
|
||||||
if (direction == "next")
|
switch (direction)
|
||||||
{
|
{
|
||||||
if (_page < _pages)
|
case "next":
|
||||||
{
|
if (_page < _pages)
|
||||||
if (_page == _endPage)
|
|
||||||
{
|
{
|
||||||
SetPagerSize("forward");
|
_page += 1;
|
||||||
}
|
}
|
||||||
_page += 1;
|
break;
|
||||||
}
|
case "previous":
|
||||||
}
|
if (_page > 1)
|
||||||
else if (direction == "previous")
|
|
||||||
{
|
|
||||||
if (_page > 1)
|
|
||||||
{
|
|
||||||
if (_page == _startPage)
|
|
||||||
{
|
{
|
||||||
SetPagerSize("back");
|
_page -= 1;
|
||||||
}
|
}
|
||||||
_page -= 1;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateList(_page);
|
UpdateList(_page);
|
||||||
|
|
|
@ -134,6 +134,11 @@ namespace Oqtane.Modules
|
||||||
return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment);
|
return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string ImageUrl(int fileid, string size, string mode)
|
||||||
|
{
|
||||||
|
return Utilities.ImageUrl(PageState.Alias, fileid, size, mode);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual Dictionary<string, string> GetUrlParameters(string parametersTemplate = "")
|
public virtual Dictionary<string, string> GetUrlParameters(string parametersTemplate = "")
|
||||||
{
|
{
|
||||||
var urlParameters = new Dictionary<string, string>();
|
var urlParameters = new Dictionary<string, string>();
|
||||||
|
|
|
@ -144,4 +144,10 @@
|
||||||
<data name="Size.Text" xml:space="preserve">
|
<data name="Size.Text" xml:space="preserve">
|
||||||
<value>Size: </value>
|
<value>Size: </value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Description.HelpText" xml:space="preserve">
|
||||||
|
<value>A description of the file. This can be used as a caption for image files.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Description.Text" xml:space="preserve">
|
||||||
|
<value>Description:</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -171,4 +171,16 @@
|
||||||
<data name="Type.Text" xml:space="preserve">
|
<data name="Type.Text" xml:space="preserve">
|
||||||
<value>Type:</value>
|
<value>Type:</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Capacity.HelpText" xml:space="preserve">
|
||||||
|
<value>Enter the maximum folder capacity (in megabytes). Specify zero if the capacity is unlimited.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Capacity.Text" xml:space="preserve">
|
||||||
|
<value>Capacity:</value>
|
||||||
|
</data>
|
||||||
|
<data name="ImageSizes.HelpText" xml:space="preserve">
|
||||||
|
<value>Enter a list of image sizes which can be generated dynamically from uploaded images (ie. 200x200,x200,200x)</value>
|
||||||
|
</data>
|
||||||
|
<data name="ImageSizes.Text" xml:space="preserve">
|
||||||
|
<value>Image Sizes:</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -400,17 +400,17 @@
|
||||||
await PageModuleService.AddPageModuleAsync(pageModule);
|
await PageModuleService.AddPageModuleAsync(pageModule);
|
||||||
await PageModuleService.UpdatePageModuleOrderAsync(pageModule.PageId, pageModule.Pane);
|
await PageModuleService.UpdatePageModuleOrderAsync(pageModule.PageId, pageModule.Pane);
|
||||||
|
|
||||||
Message = $"<br /><div class=\"alert alert-success\" role=\"alert\">{Localizer["Success.Page.ModuleAdd"]}</div>";
|
Message = $"<div class=\"alert alert-success mt-2 text-center\" role=\"alert\">{Localizer["Success.Page.ModuleAdd"]}</div>";
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Message = $"<br /><div class=\"alert alert-warning\" role=\"alert\">{Localizer["Message.Require.ModuleSelect"]}</div>";
|
Message = $"<div class=\"alert alert-warning mt-2 text-center\" role=\"alert\">{Localizer["Message.Require.ModuleSelect"]}</div>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Message = $"<br /><div class=\"alert alert-error\" role=\"alert\">{Localizer["Error.Authorize.No"]}</div>";
|
Message = $"<div class=\"alert alert-error mt-2 text-center\" role=\"alert\">{Localizer["Error.Authorize.No"]}</div>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,5 +103,10 @@ namespace Oqtane.Themes
|
||||||
{
|
{
|
||||||
return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment);
|
return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string ImageUrl(int fileid, string size, string mode)
|
||||||
|
{
|
||||||
|
return Utilities.ImageUrl(PageState.Alias, fileid, size, mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,7 @@
|
||||||
if (authState.User.Identity.IsAuthenticated)
|
if (authState.User.Identity.IsAuthenticated)
|
||||||
{
|
{
|
||||||
user = await UserService.GetUserAsync(authState.User.Identity.Name, site.SiteId);
|
user = await UserService.GetUserAsync(authState.User.Identity.Name, site.SiteId);
|
||||||
|
user.IsAuthenticated = authState.User.Identity.IsAuthenticated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -17,6 +17,9 @@ using Oqtane.Infrastructure;
|
||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
using Oqtane.Extensions;
|
using Oqtane.Extensions;
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
using SixLabors.ImageSharp.Formats.Png;
|
||||||
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
|
|
||||||
// ReSharper disable StringIndexOfIsCultureSpecific.1
|
// ReSharper disable StringIndexOfIsCultureSpecific.1
|
||||||
|
|
||||||
|
@ -71,7 +74,7 @@ namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
foreach (string file in Directory.GetFiles(folder))
|
foreach (string file in Directory.GetFiles(folder))
|
||||||
{
|
{
|
||||||
files.Add(new Models.File {Name = Path.GetFileName(file), Extension = Path.GetExtension(file)?.Replace(".", "")});
|
files.Add(new Models.File { Name = Path.GetFileName(file), Extension = Path.GetExtension(file)?.Replace(".", "") });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +172,11 @@ namespace Oqtane.Controllers
|
||||||
string filepath = _files.GetFilePath(file);
|
string filepath = _files.GetFilePath(file);
|
||||||
if (System.IO.File.Exists(filepath))
|
if (System.IO.File.Exists(filepath))
|
||||||
{
|
{
|
||||||
System.IO.File.Delete(filepath);
|
// remove file and thumbnails
|
||||||
|
foreach(var f in Directory.GetFiles(Path.GetDirectoryName(filepath), Path.GetFileNameWithoutExtension(filepath) + ".*"))
|
||||||
|
{
|
||||||
|
System.IO.File.Delete(f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "File Deleted {File}", file);
|
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "File Deleted {File}", file);
|
||||||
|
@ -194,7 +201,7 @@ namespace Oqtane.Controllers
|
||||||
folder = _folders.GetFolder(FolderId);
|
folder = _folders.GetFolder(FolderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Edit, folder.Permissions))
|
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Edit, folder.Permissions))
|
||||||
{
|
{
|
||||||
string folderPath = _folders.GetFolderPath(folder);
|
string folderPath = _folders.GetFolderPath(folder);
|
||||||
CreateDirectory(folderPath);
|
CreateDirectory(folderPath);
|
||||||
|
@ -226,7 +233,11 @@ namespace Oqtane.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
client.DownloadFile(url, targetPath);
|
client.DownloadFile(url, targetPath);
|
||||||
file = _files.AddFile(CreateFile(filename, folder.FolderId, targetPath));
|
file = CreateFile(filename, folder.FolderId, targetPath);
|
||||||
|
if (file != null)
|
||||||
|
{
|
||||||
|
file = _files.AddFile(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -235,7 +246,7 @@ namespace Oqtane.Controllers
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized File Upload Attempt {FolderId} {Url}", folderid, url);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized File Download Attempt {FolderId} {Url}", folderid, url);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,16 +255,16 @@ namespace Oqtane.Controllers
|
||||||
|
|
||||||
// POST api/<controller>/upload
|
// POST api/<controller>/upload
|
||||||
[HttpPost("upload")]
|
[HttpPost("upload")]
|
||||||
public async Task UploadFile(string folder, IFormFile file)
|
public async Task UploadFile(string folder, IFormFile formfile)
|
||||||
{
|
{
|
||||||
if (file.Length <= 0)
|
if (formfile.Length <= 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file.FileName.IsPathOrFileValid())
|
if (!formfile.FileName.IsPathOrFileValid())
|
||||||
{
|
{
|
||||||
HttpContext.Response.StatusCode = (int) HttpStatusCode.Conflict;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,20 +291,24 @@ namespace Oqtane.Controllers
|
||||||
if (!string.IsNullOrEmpty(folderPath))
|
if (!string.IsNullOrEmpty(folderPath))
|
||||||
{
|
{
|
||||||
CreateDirectory(folderPath);
|
CreateDirectory(folderPath);
|
||||||
using (var stream = new FileStream(Path.Combine(folderPath, file.FileName), FileMode.Create))
|
using (var stream = new FileStream(Path.Combine(folderPath, formfile.FileName), FileMode.Create))
|
||||||
{
|
{
|
||||||
await file.CopyToAsync(stream);
|
await formfile.CopyToAsync(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
string upload = await MergeFile(folderPath, file.FileName);
|
string upload = await MergeFile(folderPath, formfile.FileName);
|
||||||
if (upload != "" && FolderId != -1)
|
if (upload != "" && FolderId != -1)
|
||||||
{
|
{
|
||||||
_files.AddFile(CreateFile(upload, FolderId, Path.Combine(folderPath, upload)));
|
var file = CreateFile(upload, FolderId, Path.Combine(folderPath, upload));
|
||||||
|
if (file != null)
|
||||||
|
{
|
||||||
|
_files.AddFile(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized File Upload Attempt {Folder} {File}", folder, file);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized File Upload Attempt {Folder} {File}", folder, formfile.FileName);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,6 +494,99 @@ namespace Oqtane.Controllers
|
||||||
return System.IO.File.Exists(errorPath) ? PhysicalFile(errorPath, MimeUtilities.GetMimeType(errorPath)) : null;
|
return System.IO.File.Exists(errorPath) ? PhysicalFile(errorPath, MimeUtilities.GetMimeType(errorPath)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("image/{id}/{size}/{mode?}")]
|
||||||
|
public IActionResult GetImage(int id, string size, string mode)
|
||||||
|
{
|
||||||
|
var file = _files.GetFile(id);
|
||||||
|
if (file != null && file.Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
|
||||||
|
{
|
||||||
|
if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower()))
|
||||||
|
{
|
||||||
|
var filepath = _files.GetFilePath(file);
|
||||||
|
if (System.IO.File.Exists(filepath))
|
||||||
|
{
|
||||||
|
size = size.ToLower();
|
||||||
|
mode = (string.IsNullOrEmpty(mode)) ? "crop" : mode;
|
||||||
|
if ((_userPermissions.IsAuthorized(User, PermissionNames.Edit, file.Folder.Permissions) ||
|
||||||
|
size.Contains("x") && !string.IsNullOrEmpty(file.Folder.ImageSizes) && file.Folder.ImageSizes.ToLower().Split(",").Contains(size))
|
||||||
|
&& Enum.TryParse(mode, true, out ResizeMode resizemode))
|
||||||
|
{
|
||||||
|
var imagepath = CreateImage(filepath, size, resizemode.ToString());
|
||||||
|
if (!string.IsNullOrEmpty(imagepath))
|
||||||
|
{
|
||||||
|
return PhysicalFile(imagepath, file.GetMimeType());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Error, this, LogFunction.Create, "Error Creating Image For File {File} {Size}", file, size);
|
||||||
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Invalid Image Size For Folder Or Invalid Mode Specification {Folder} {Size} {Mode}", file.Folder, size, mode);
|
||||||
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Error, this, LogFunction.Read, "File Does Not Exist {FileId} {FilePath}", id, filepath);
|
||||||
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "File Is Not An Image {File}", file);
|
||||||
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized File Access Attempt {FileId}", id);
|
||||||
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
string errorPath = Path.Combine(GetFolderPath("images"), "error.png");
|
||||||
|
return System.IO.File.Exists(errorPath) ? PhysicalFile(errorPath, MimeUtilities.GetMimeType(errorPath)) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string CreateImage(string filepath, string size, string mode)
|
||||||
|
{
|
||||||
|
string imagepath = filepath.Replace(Path.GetExtension(filepath), "." + size + "." + mode.ToLower() + ".png");
|
||||||
|
|
||||||
|
if (!System.IO.File.Exists(imagepath))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
|
||||||
|
using (Image image = Image.Load(stream))
|
||||||
|
{
|
||||||
|
var parts = size.Split('x');
|
||||||
|
int width = (!string.IsNullOrEmpty(parts[0])) ? int.Parse(parts[0]) : 0;
|
||||||
|
int height = (!string.IsNullOrEmpty(parts[1])) ? int.Parse(parts[1]) : 0;
|
||||||
|
Enum.TryParse(mode, true, out ResizeMode resizemode);
|
||||||
|
|
||||||
|
image.Mutate(x =>
|
||||||
|
x.Resize(new ResizeOptions
|
||||||
|
{
|
||||||
|
Size = new Size(width, height),
|
||||||
|
Mode = resizemode
|
||||||
|
})
|
||||||
|
.BackgroundColor(new Rgba32(255, 255, 255, 0)));
|
||||||
|
|
||||||
|
image.Save(imagepath, new PngEncoder());
|
||||||
|
}
|
||||||
|
stream.Close();
|
||||||
|
}
|
||||||
|
catch // error creating image
|
||||||
|
{
|
||||||
|
imagepath = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return imagepath;
|
||||||
|
}
|
||||||
|
|
||||||
private string GetFolderPath(string folder)
|
private string GetFolderPath(string folder)
|
||||||
{
|
{
|
||||||
return Utilities.PathCombine(_environment.ContentRootPath, folder);
|
return Utilities.PathCombine(_environment.ContentRootPath, folder);
|
||||||
|
@ -489,7 +597,7 @@ namespace Oqtane.Controllers
|
||||||
if (!Directory.Exists(folderpath))
|
if (!Directory.Exists(folderpath))
|
||||||
{
|
{
|
||||||
string path = "";
|
string path = "";
|
||||||
var separators = new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar};
|
var separators = new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
|
||||||
string[] folders = folderpath.Split(separators, StringSplitOptions.RemoveEmptyEntries);
|
string[] folders = folderpath.Split(separators, StringSplitOptions.RemoveEmptyEntries);
|
||||||
foreach (string folder in folders)
|
foreach (string folder in folders)
|
||||||
{
|
{
|
||||||
|
@ -504,25 +612,52 @@ namespace Oqtane.Controllers
|
||||||
|
|
||||||
private Models.File CreateFile(string filename, int folderid, string filepath)
|
private Models.File CreateFile(string filename, int folderid, string filepath)
|
||||||
{
|
{
|
||||||
Models.File file = new Models.File();
|
Models.File file = null;
|
||||||
file.Name = filename;
|
|
||||||
file.FolderId = folderid;
|
int size = 0;
|
||||||
|
var folder = _folders.GetFolder(folderid);
|
||||||
|
if (folder.Capacity != 0)
|
||||||
|
{
|
||||||
|
foreach (var f in _files.GetFiles(folderid))
|
||||||
|
{
|
||||||
|
size += f.Size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FileInfo fileinfo = new FileInfo(filepath);
|
FileInfo fileinfo = new FileInfo(filepath);
|
||||||
file.Extension = fileinfo.Extension.ToLower().Replace(".", "");
|
if (folder.Capacity == 0 || ((size + fileinfo.Length) / 1000000) < folder.Capacity)
|
||||||
file.Size = (int) fileinfo.Length;
|
|
||||||
file.ImageHeight = 0;
|
|
||||||
file.ImageWidth = 0;
|
|
||||||
|
|
||||||
if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower()))
|
|
||||||
{
|
{
|
||||||
FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
|
file = new Models.File();
|
||||||
using (Image image = Image.Load(stream))
|
file.Name = filename;
|
||||||
|
file.FolderId = folderid;
|
||||||
|
|
||||||
|
file.Extension = fileinfo.Extension.ToLower().Replace(".", "");
|
||||||
|
file.Size = (int)fileinfo.Length;
|
||||||
|
file.ImageHeight = 0;
|
||||||
|
file.ImageWidth = 0;
|
||||||
|
|
||||||
|
if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower()))
|
||||||
{
|
{
|
||||||
file.ImageHeight = image.Height;
|
try
|
||||||
file.ImageWidth = image.Width;
|
{
|
||||||
|
FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
|
||||||
|
using (Image image = Image.Load(stream))
|
||||||
|
{
|
||||||
|
file.ImageHeight = image.Height;
|
||||||
|
file.ImageWidth = image.Width;
|
||||||
|
}
|
||||||
|
stream.Close();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// error opening image file
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stream.Close();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.IO.File.Delete(filepath);
|
||||||
|
_logger.Log(LogLevel.Warning, this, LogFunction.Create, "File Exceeds Folder Capacity {Folder} {File}", folder, filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
|
|
|
@ -187,8 +187,10 @@ namespace Oqtane.Controllers
|
||||||
ParentId = folder.FolderId,
|
ParentId = folder.FolderId,
|
||||||
Name = "My Folder",
|
Name = "My Folder",
|
||||||
Type = FolderTypes.Private,
|
Type = FolderTypes.Private,
|
||||||
Path = Utilities.PathCombine(folder.Path, newUser.UserId.ToString(),Path.DirectorySeparatorChar.ToString()),
|
Path = Utilities.PathCombine(folder.Path, newUser.UserId.ToString(), Path.DirectorySeparatorChar.ToString()),
|
||||||
Order = 1,
|
Order = 1,
|
||||||
|
ImageSizes = "",
|
||||||
|
Capacity = Constants.UserFolderCapacity,
|
||||||
IsSystem = true,
|
IsSystem = true,
|
||||||
Permissions = new List<Permission>
|
Permissions = new List<Permission>
|
||||||
{
|
{
|
||||||
|
@ -196,7 +198,7 @@ namespace Oqtane.Controllers
|
||||||
new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
||||||
new Permission(PermissionNames.Edit, newUser.UserId, true)
|
new Permission(PermissionNames.Edit, newUser.UserId, true)
|
||||||
}.EncodePermissions()
|
}.EncodePermissions()
|
||||||
});
|
}) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -631,13 +631,15 @@ namespace Oqtane.Infrastructure
|
||||||
Type = FolderTypes.Private,
|
Type = FolderTypes.Private,
|
||||||
Path = Utilities.PathCombine(folder.Path, user.UserId.ToString(), Path.DirectorySeparatorChar.ToString()),
|
Path = Utilities.PathCombine(folder.Path, user.UserId.ToString(), Path.DirectorySeparatorChar.ToString()),
|
||||||
Order = 1,
|
Order = 1,
|
||||||
|
ImageSizes = "",
|
||||||
|
Capacity = Constants.UserFolderCapacity,
|
||||||
IsSystem = true,
|
IsSystem = true,
|
||||||
Permissions = new List<Permission>
|
Permissions = new List<Permission>
|
||||||
{
|
{
|
||||||
new Permission(PermissionNames.Browse, user.UserId, true),
|
new Permission(PermissionNames.Browse, user.UserId, true),
|
||||||
new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
||||||
new Permission(PermissionNames.Edit, user.UserId, true),
|
new Permission(PermissionNames.Edit, user.UserId, true),
|
||||||
}.EncodePermissions(),
|
}.EncodePermissions(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Oqtane.Databases.Interfaces;
|
||||||
|
using Oqtane.Migrations.EntityBuilders;
|
||||||
|
using Oqtane.Repository;
|
||||||
|
using Oqtane.Shared;
|
||||||
|
|
||||||
|
namespace Oqtane.Migrations.Tenant
|
||||||
|
{
|
||||||
|
[DbContext(typeof(TenantDBContext))]
|
||||||
|
[Migration("Tenant.02.03.00.01")]
|
||||||
|
public class AddFolderCapacity : MultiDatabaseMigration
|
||||||
|
{
|
||||||
|
public AddFolderCapacity(IDatabase database) : base(database)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||||
|
folderEntityBuilder.AddIntegerColumn("Capacity", true);
|
||||||
|
folderEntityBuilder.UpdateColumn("Capacity", "0");
|
||||||
|
folderEntityBuilder.UpdateColumn("Capacity", Constants.UserFolderCapacity.ToString(), $"{ActiveDatabase.RewriteName("Name")} = 'My Folder'");
|
||||||
|
folderEntityBuilder.AddStringColumn("ImageSizes", 512, true, true);
|
||||||
|
|
||||||
|
var fileEntityBuilder = new FileEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||||
|
fileEntityBuilder.AddStringColumn("Description", 512, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||||
|
folderEntityBuilder.DropColumn("ImageSizes");
|
||||||
|
folderEntityBuilder.DropColumn("Capacity");
|
||||||
|
|
||||||
|
var fileEntityBuilder = new FileEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||||
|
fileEntityBuilder.DropColumn("Description");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -124,7 +124,7 @@ namespace Oqtane.Repository
|
||||||
|
|
||||||
Folder folder = _folderRepository.AddFolder(new Folder
|
Folder folder = _folderRepository.AddFolder(new Folder
|
||||||
{
|
{
|
||||||
SiteId = site.SiteId, ParentId = null, Name = "Root", Type = FolderTypes.Private, Path = "", Order = 1, IsSystem = true,
|
SiteId = site.SiteId, ParentId = null, Name = "Root", Type = FolderTypes.Private, Path = "", Order = 1, ImageSizes = "", Capacity = 0, IsSystem = true,
|
||||||
Permissions = new List<Permission>
|
Permissions = new List<Permission>
|
||||||
{
|
{
|
||||||
new Permission(PermissionNames.Browse, RoleNames.Admin, true),
|
new Permission(PermissionNames.Browse, RoleNames.Admin, true),
|
||||||
|
@ -132,7 +132,7 @@ namespace Oqtane.Repository
|
||||||
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
||||||
}.EncodePermissions()
|
}.EncodePermissions()
|
||||||
});
|
});
|
||||||
_folderRepository.AddFolder(new Folder { SiteId = site.SiteId, ParentId = folder.FolderId, Name = "Public", Type = FolderTypes.Public, Path = Utilities.PathCombine("Public", Path.DirectorySeparatorChar.ToString()), Order = 1, IsSystem = false,
|
_folderRepository.AddFolder(new Folder { SiteId = site.SiteId, ParentId = folder.FolderId, Name = "Public", Type = FolderTypes.Public, Path = Utilities.PathCombine("Public", Path.DirectorySeparatorChar.ToString()), Order = 1, ImageSizes = "", Capacity = 0, IsSystem = false,
|
||||||
Permissions = new List<Permission>
|
Permissions = new List<Permission>
|
||||||
{
|
{
|
||||||
new Permission(PermissionNames.Browse, RoleNames.Admin, true),
|
new Permission(PermissionNames.Browse, RoleNames.Admin, true),
|
||||||
|
@ -142,7 +142,7 @@ namespace Oqtane.Repository
|
||||||
});
|
});
|
||||||
_folderRepository.AddFolder(new Folder
|
_folderRepository.AddFolder(new Folder
|
||||||
{
|
{
|
||||||
SiteId = site.SiteId, ParentId = folder.FolderId, Name = "Users", Type = FolderTypes.Private, Path = Utilities.PathCombine("Users",Path.DirectorySeparatorChar.ToString()), Order = 3, IsSystem = true,
|
SiteId = site.SiteId, ParentId = folder.FolderId, Name = "Users", Type = FolderTypes.Private, Path = Utilities.PathCombine("Users",Path.DirectorySeparatorChar.ToString()), Order = 3, ImageSizes = "", Capacity = 0, IsSystem = true,
|
||||||
Permissions = new List<Permission>
|
Permissions = new List<Permission>
|
||||||
{
|
{
|
||||||
new Permission(PermissionNames.Browse, RoleNames.Admin, true),
|
new Permission(PermissionNames.Browse, RoleNames.Admin, true),
|
||||||
|
|
|
@ -333,7 +333,7 @@ Oqtane.Interop = {
|
||||||
|
|
||||||
var data = new FormData();
|
var data = new FormData();
|
||||||
data.append('folder', folder);
|
data.append('folder', folder);
|
||||||
data.append('file', Chunk, FileName);
|
data.append('formfile', Chunk, FileName);
|
||||||
var request = new XMLHttpRequest();
|
var request = new XMLHttpRequest();
|
||||||
request.open('POST', posturl, true);
|
request.open('POST', posturl, true);
|
||||||
request.upload.onloadstart = function (e) {
|
request.upload.onloadstart = function (e) {
|
||||||
|
|
|
@ -50,6 +50,11 @@ namespace Oqtane.Models
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int ImageWidth { get; set; }
|
public int ImageWidth { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Description of a file
|
||||||
|
/// </summary>
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
#region IAuditable Properties
|
#region IAuditable Properties
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
|
@ -45,7 +45,17 @@ namespace Oqtane.Models
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// TODO: unclear what this is for
|
/// List of image sizes which can be generated dynamically from uploaded images (ie. 200x200,x200,200x)
|
||||||
|
/// </summary>
|
||||||
|
public string ImageSizes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum folder capacity (in bytes)
|
||||||
|
/// </summary>
|
||||||
|
public int Capacity { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Folder is a dependency of the framework and cannot be modified or removed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsSystem { get; set; }
|
public bool IsSystem { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -67,24 +67,28 @@ namespace Oqtane.Models
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Vulnerabilities { get; set; }
|
public int Vulnerabilities { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
#region Commercial Properties
|
||||||
/// The price of the package ( if commercial )
|
|
||||||
/// </summary>
|
|
||||||
public decimal Price { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Url for purchasing the package ( if commercial )
|
/// The price of the package
|
||||||
|
/// </summary>
|
||||||
|
public decimal? Price { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Url for purchasing the package
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string PaymentUrl { get; set; }
|
public string PaymentUrl { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The trial period in days ( if commercial )
|
/// The trial period in days
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int TrialPeriod { get; set; }
|
public int TrialPeriod { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The expiry date of the package ( if commercial )
|
/// The expiry date of the package
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? ExpiryDate { get; set; }
|
public DateTime? ExpiryDate { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,5 +88,14 @@ namespace Oqtane.Models
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public bool IsAuthenticated { get; set; }
|
public bool IsAuthenticated { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The path name of the user's personal folder
|
||||||
|
/// </summary>
|
||||||
|
[NotMapped]
|
||||||
|
public string FolderPath
|
||||||
|
{
|
||||||
|
get => "Users\\" + UserId.ToString() + "\\";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,8 @@ namespace Oqtane.Shared {
|
||||||
public const string DefaultSiteTemplate = "Oqtane.SiteTemplates.DefaultSiteTemplate, Oqtane.Server";
|
public const string DefaultSiteTemplate = "Oqtane.SiteTemplates.DefaultSiteTemplate, Oqtane.Server";
|
||||||
|
|
||||||
public const string ContentUrl = "/api/file/download/";
|
public const string ContentUrl = "/api/file/download/";
|
||||||
|
public const string ImageUrl = "/api/file/image/";
|
||||||
|
public const int UserFolderCapacity = 20; // megabytes
|
||||||
|
|
||||||
[Obsolete("Use UserNames.Host instead.")]
|
[Obsolete("Use UserNames.Host instead.")]
|
||||||
public const string HostUser = UserNames.Host;
|
public const string HostUser = UserNames.Host;
|
||||||
|
|
|
@ -112,6 +112,12 @@ namespace Oqtane.Shared
|
||||||
return $"{aliasUrl}{Constants.ContentUrl}{fileId}{method}";
|
return $"{aliasUrl}{Constants.ContentUrl}{fileId}{method}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string ImageUrl(Alias alias, int fileId, string size, string mode)
|
||||||
|
{
|
||||||
|
var aliasUrl = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path : "";
|
||||||
|
return $"{aliasUrl}{Constants.ImageUrl}{fileId}/{size}/{mode}";
|
||||||
|
}
|
||||||
|
|
||||||
public static string TenantUrl(Alias alias, string url)
|
public static string TenantUrl(Alias alias, string url)
|
||||||
{
|
{
|
||||||
url = (!url.StartsWith("/")) ? "/" + url : url;
|
url = (!url.StartsWith("/")) ? "/" + url : url;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user