file uploads for media management (not persisted yet)
This commit is contained in:
@@ -0,0 +1,250 @@
|
||||
using Raven.Client.Documents;
|
||||
using Raven.Client.Documents.Linq;
|
||||
using Raven.Client.Documents.Session;
|
||||
|
||||
namespace zero.Backoffice.Modules;
|
||||
|
||||
public class MediaTreeService : IMediaTreeService
|
||||
{
|
||||
protected IMediaStore Media { get; private set; }
|
||||
|
||||
protected PageOptions PageOptions { get; set; }
|
||||
|
||||
|
||||
public PageTreeService(IPagesStore pages, IZeroOptions options, IRoutes routes)
|
||||
{
|
||||
Media = pages;
|
||||
Routes = routes;
|
||||
PageOptions = options.For<PageOptions>();
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
/// FOR MEDIA
|
||||
public virtual async Task<Paged<MediaListItem>> Load(MediaListItemQuery query)
|
||||
{
|
||||
bool hasSearch = !query.Search.IsNullOrWhiteSpace();
|
||||
bool isRoot = query.FolderId.IsNullOrWhiteSpace();
|
||||
|
||||
query.SearchFor(entity => entity.Name);
|
||||
|
||||
query.OrderQuery = q => q
|
||||
.OrderByDescending(x => x.IsFolder)
|
||||
.ThenBy(query.OrderBy, query.OrderIsDescending, query.OrderType == ListQueryOrderType.String ? OrderingType.String : OrderingType.Double);
|
||||
|
||||
IRavenQueryable<MediaListItem> dbQuery = Session.Query<MediaListItem, Media_ByParent>().ProjectInto<MediaListItem>();
|
||||
|
||||
if (!hasSearch || !query.SearchIsGlobal)
|
||||
{
|
||||
dbQuery = dbQuery.WhereIf(x => x.ParentId == query.FolderId, !query.FolderId.IsNullOrEmpty(), x => x.ParentId == null);
|
||||
}
|
||||
|
||||
Paged<MediaListItem> result = await dbQuery.ToQueriedListAsyncX(query);
|
||||
|
||||
string[] ids = result.Items.Where(x => x.IsFolder).Select(x => x.Id).ToArray();
|
||||
|
||||
List<Media_ByChildren.Result> children = await Session.Query<Media_ByChildren.Result, Media_ByChildren>()
|
||||
.Where(x => x.ParentId.In(ids))
|
||||
.ToListAsync();
|
||||
|
||||
foreach (MediaListItem item in result.Items)
|
||||
{
|
||||
item.Children = children.FirstOrDefault(x => x.ParentId == item.Id)?.ChildrenCount ?? 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
/// FOR MEDIA FOLDER
|
||||
public async Task<List<TreeItem>> LoadAsTree(string parentId = null, string activeId = null)
|
||||
{
|
||||
List<TreeItem> items = new();
|
||||
string[] openIds = Array.Empty<string>();
|
||||
|
||||
IList<MediaFolder> folders = await Session.Query<MediaFolder>()
|
||||
.WhereIf(x => x.ParentId == parentId, !parentId.IsNullOrEmpty(), x => x.ParentId == null)
|
||||
.OrderByDescending(x => x.CreatedDate).ThenBy(x => x.Name)
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
// get hierarchy so we know if we should set the folder to open
|
||||
if (!activeId.IsNullOrEmpty())
|
||||
{
|
||||
MediaFolder_ByHierarchy.Result result = await Session.Query<MediaFolder_ByHierarchy.Result, MediaFolder_ByHierarchy>()
|
||||
.ProjectInto<MediaFolder_ByHierarchy.Result>()
|
||||
.Include<MediaFolder_ByHierarchy.Result, MediaFolder>(x => x.Path.Select(p => p.Id))
|
||||
.FirstOrDefaultAsync(x => x.Id == activeId);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
openIds = result.Path.Select(x => x.Id).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// get children for all folders
|
||||
string[] folderIds = folders.Select(x => x.Id).ToArray();
|
||||
|
||||
IList<MediaFolders_WithChildren.Result> children = await Session.Query<MediaFolders_WithChildren.Result, MediaFolders_WithChildren>()
|
||||
.ProjectInto<MediaFolders_WithChildren.Result>()
|
||||
.Where(x => x.Id.In(folderIds))
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
foreach (MediaFolder folder in folders)
|
||||
{
|
||||
int childCount = children.Count(x => x.Id == folder.Id);
|
||||
|
||||
items.Add(new TreeItem()
|
||||
{
|
||||
Id = folder.Id,
|
||||
Name = folder.Name,
|
||||
HasChildren = childCount > 0,
|
||||
ChildCount = childCount,
|
||||
ParentId = folder.ParentId,
|
||||
Sort = folder.Sort,
|
||||
Icon = "fth-folder",
|
||||
IsOpen = openIds.Contains(folder.Id),
|
||||
IsInactive = !folder.IsActive,
|
||||
HasActions = true,
|
||||
Modifier = !folder.IsActive ? new TreeItemModifier()
|
||||
{
|
||||
Icon = "fth-minus-circle color-yellow",
|
||||
Name = "Inactive"
|
||||
} : null
|
||||
});
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IList<TreeItem>> GetChildren(string parentId = null, string activeId = null, string search = null)
|
||||
{
|
||||
IList<TreeItem> items = new List<TreeItem>();
|
||||
IReadOnlyCollection<PageType> pageTypes = PageOptions.GetAllItems();
|
||||
string[] openIds = new string[0] { };
|
||||
Paged<Page> pages = null;
|
||||
IList<Pages_WithChildren.Result> children = null;
|
||||
bool isSearch = !search.IsNullOrWhiteSpace();
|
||||
|
||||
if (isSearch)
|
||||
{
|
||||
pages = await Media.Load(1, Int32.MaxValue, q => q.SearchIf(x => x.Name, search, "*").OrderBy(x => x.Sort, OrderingType.Long));
|
||||
|
||||
var urls = await Routes.GetUrls(pages.Items.ToArray());
|
||||
|
||||
foreach (Page page in pages.Items)
|
||||
{
|
||||
if (urls.TryGetValue(page, out string url))
|
||||
{
|
||||
page.Url = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pages = await Media.Load(1, Int32.MaxValue, q => q
|
||||
.WhereIf(x => x.ParentId == parentId, !parentId.IsNullOrEmpty(), x => x.ParentId == null)
|
||||
.OrderBy(x => x.Sort, OrderingType.Long));
|
||||
|
||||
|
||||
// get hierarchy so we know if we should set the page to open
|
||||
if (!activeId.IsNullOrEmpty())
|
||||
{
|
||||
Pages_ByHierarchy.Result result = await Media.Session.Query<Pages_ByHierarchy.Result, Pages_ByHierarchy>()
|
||||
.ProjectInto<Pages_ByHierarchy.Result>()
|
||||
.Include<Pages_ByHierarchy.Result, Page>(x => x.Path.Select(p => p.Id))
|
||||
.FirstOrDefaultAsync(x => x.Id == activeId);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
openIds = result.Path.Select(x => x.Id).ToArray(); // .Union(new string[1] { activeId })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// get children for all pages
|
||||
string[] pageIds = pages.Items.Select(x => x.Id).ToArray();
|
||||
|
||||
children = await Media.Session.Query<Pages_WithChildren.Result, Pages_WithChildren>()
|
||||
.ProjectInto<Pages_WithChildren.Result>()
|
||||
.Where(x => x.Id.In(pageIds))
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
// function to get modifier icon
|
||||
TreeItemModifier GetModifier(Page page)
|
||||
{
|
||||
if (page.PublishDate > DateTimeOffset.Now || page.UnpublishDate > DateTimeOffset.Now)
|
||||
{
|
||||
return new TreeItemModifier("@page.schedule.scheduled", "fth-clock");
|
||||
}
|
||||
if (!page.IsActive)
|
||||
{
|
||||
return new TreeItemModifier("@ui.inactive", "fth-minus-circle color-red");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// build tree
|
||||
foreach (Page page in pages.Items)
|
||||
{
|
||||
PageType pageType = pageTypes.FirstOrDefault(x => x.Alias == page.PageTypeAlias);
|
||||
|
||||
if (pageType == null)
|
||||
{
|
||||
continue;
|
||||
// TODO the page type does not exist anymore
|
||||
}
|
||||
|
||||
int childCount = isSearch ? 0 : children.Count(x => x.Id == page.Id);
|
||||
|
||||
items.Add(new TreeItem()
|
||||
{
|
||||
Id = page.Id,
|
||||
Name = page.Name,
|
||||
HasChildren = childCount > 0,
|
||||
ChildCount = childCount,
|
||||
ParentId = page.ParentId,
|
||||
Sort = page.Sort,
|
||||
Icon = pageType.Icon,
|
||||
IsOpen = openIds.Contains(page.Id),
|
||||
IsInactive = !page.IsActive,
|
||||
HasActions = true,
|
||||
Modifier = GetModifier(page),
|
||||
Description = isSearch ? page.Url : null
|
||||
});
|
||||
}
|
||||
|
||||
if (parentId.IsNullOrEmpty())
|
||||
{
|
||||
items.Add(new TreeItem()
|
||||
{
|
||||
Id = "recyclebin",
|
||||
ParentId = null,
|
||||
Sort = 99999,
|
||||
Name = "@recyclebin.name",
|
||||
Icon = "fth-trash",
|
||||
HasChildren = false,
|
||||
HasActions = true
|
||||
});
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface IMediaTreeService
|
||||
{
|
||||
/// <summary>
|
||||
/// Get media children as tree items
|
||||
/// </summary>
|
||||
Task<IList<TreeItem>> GetChildren(string parentId = null, string activeId = null, string search = null);
|
||||
}
|
||||
Reference in New Issue
Block a user