I don't know, media shit, does not work
This commit is contained in:
@@ -7,6 +7,7 @@ using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
@@ -20,6 +21,9 @@ namespace zero.Core.Collections
|
||||
{
|
||||
public class MediaCollection : CollectionBase<IMedia>, IMediaCollection
|
||||
{
|
||||
private IAsyncDocumentSession _coreSession;
|
||||
|
||||
|
||||
public MediaCollection(IZeroContext context, ICollectionInterceptorHandler interceptor, IValidator<IMedia> validator, IPaths paths) : base(context, interceptor, validator)
|
||||
{
|
||||
PreSave = model => model.IsActive = true;
|
||||
@@ -27,6 +31,24 @@ namespace zero.Core.Collections
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create an an async document session
|
||||
/// </summary>
|
||||
protected IAsyncDocumentSession CoreSession
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_coreSession != null)
|
||||
{
|
||||
return _coreSession;
|
||||
}
|
||||
_coreSession = Store.OpenCoreSession();
|
||||
_coreSession.Advanced.WaitForIndexesAfterSaveChanges(throwOnTimeout: false);
|
||||
return _coreSession;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected const char PATH_SEPARATOR = '/';
|
||||
|
||||
protected const string PATH_PREFIX = "/uploads";
|
||||
@@ -40,13 +62,49 @@ namespace zero.Core.Collections
|
||||
protected IPaths Paths { get; set; }
|
||||
|
||||
|
||||
public override Task<IMedia> GetById(string id)
|
||||
{
|
||||
ApplyScopeBasedOnId(id);
|
||||
return base.GetById(id);
|
||||
}
|
||||
|
||||
|
||||
public override async Task<Dictionary<string, IMedia>> GetByIds(params string[] ids)
|
||||
{
|
||||
string[] localIds = ids.Where(x => !x.StartsWith(Constants.Database.CoreIdPrefix)).ToArray();
|
||||
string[] coreIds = ids.Except(localIds).ToArray();
|
||||
|
||||
Dictionary<string, IMedia> result = new Dictionary<string, IMedia>();
|
||||
Dictionary<string, IMedia> models = null;
|
||||
|
||||
if (localIds.Length > 0)
|
||||
{
|
||||
models = await Session.LoadAsync<IMedia>(localIds);
|
||||
foreach (string id in localIds)
|
||||
{
|
||||
models.TryGetValue(id, out IMedia model);
|
||||
result.Add(id, model);
|
||||
}
|
||||
}
|
||||
if (coreIds.Length > 0)
|
||||
{
|
||||
models = await CoreSession.LoadAsync<IMedia>(coreIds);
|
||||
foreach (string id in coreIds)
|
||||
{
|
||||
models.TryGetValue(id, out IMedia model);
|
||||
result.Add(id, model);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<string> GetSourceById(string id, bool thumb = false)
|
||||
{
|
||||
if (id.StartsWith(Constants.Database.CoreIdPrefix))
|
||||
{
|
||||
ApplyScope("shared");
|
||||
}
|
||||
ApplyScopeBasedOnId(id);
|
||||
|
||||
IMedia media = await Session.LoadAsync<IMedia>(id);
|
||||
|
||||
if (media == null)
|
||||
@@ -66,6 +124,8 @@ namespace zero.Core.Collections
|
||||
/// <inheritdoc />
|
||||
public async Task<ListResult<IMedia>> GetByQuery(MediaListQuery query)
|
||||
{
|
||||
ApplyScopeBasedOnId(query.FolderId);
|
||||
|
||||
query.SearchFor(entity => entity.Name);
|
||||
|
||||
return await Query
|
||||
@@ -195,6 +255,18 @@ namespace zero.Core.Collections
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Applies the shared scope when an ID is prefixed with core.
|
||||
/// </summary>
|
||||
void ApplyScopeBasedOnId(string id)
|
||||
{
|
||||
if (!id.IsNullOrWhiteSpace() && id.StartsWith(Constants.Database.CoreIdPrefix, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
ApplyScope("shared");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Saves a thumbnail of an image
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace zero.Core.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// By default most entities are app aware and stored in their own database context.
|
||||
/// Exceptions (like media) are stored in the core database and need to be marked as app aware
|
||||
/// </summary>
|
||||
public interface IAppAwareEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Associated app id of the entity
|
||||
/// </summary>
|
||||
string AppId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,9 @@ namespace zero.Core.Entities
|
||||
/// <inheritdoc />
|
||||
public class Media : ZeroEntity, IMedia
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string AppId { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string FileId { get; set; }
|
||||
|
||||
@@ -38,9 +41,6 @@ namespace zero.Core.Entities
|
||||
|
||||
/// <inheritdoc />
|
||||
public MediaType Type { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsCore { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace zero.Core.Entities
|
||||
/// A media file (can contain an image or other media like videos and documents)
|
||||
/// </summary>
|
||||
[Collection("Media", LongId = true)]
|
||||
public interface IMedia : IZeroEntity, IZeroDbConventions
|
||||
public interface IMedia : IZeroEntity, IZeroDbConventions, IAppAwareEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Id/name of the phyiscal folder which is stored on disk/cloud
|
||||
@@ -104,10 +104,5 @@ namespace zero.Core.Entities
|
||||
/// Type of the media
|
||||
/// </summary>
|
||||
MediaType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this media item is part of the core database (for multi-tenant setup)
|
||||
/// </summary>
|
||||
bool IsCore { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ namespace zero.Core.Entities
|
||||
public class MediaFolder : ZeroEntity, IMediaFolder
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string ParentId { get; set; }
|
||||
public string AppId { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsCore { get; set; }
|
||||
public string ParentId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -17,16 +17,11 @@ namespace zero.Core.Entities
|
||||
/// A media folder contains media and other folders
|
||||
/// </summary>
|
||||
[Collection("MediaFolders", LongId = true)]
|
||||
public interface IMediaFolder : IZeroEntity, IZeroDbConventions
|
||||
public interface IMediaFolder : IZeroEntity, IZeroDbConventions, IAppAwareEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Parent folder id
|
||||
/// </summary>
|
||||
string ParentId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this media folder is part of the core database (for multi-tenant setup)
|
||||
/// </summary>
|
||||
bool IsCore { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -30,22 +30,16 @@ namespace zero.Core.Extensions
|
||||
|
||||
store.Conventions.RegisterAsyncIdConvention<IZeroEntity>((_, entity) =>
|
||||
{
|
||||
string prefix = String.Empty;
|
||||
string guid = IdGenerator.Create();
|
||||
string collection = store.Conventions.GetCollectionName(entity);
|
||||
//CollectionAttribute collectionAttribute = entity.GetType().GetCustomAttribute<CollectionAttribute>(true);
|
||||
|
||||
if ((entity is IMedia && ((IMedia)entity).IsCore) || (entity is IMediaFolder && ((IMediaFolder)entity).IsCore))
|
||||
{
|
||||
prefix = Constants.Database.CoreIdPrefix;
|
||||
}
|
||||
if (entity is IBackofficeUser or IBackofficeUserRole)
|
||||
{
|
||||
guid = IdGenerator.Create(8);
|
||||
}
|
||||
|
||||
string tag = store.Conventions.TransformTypeCollectionNameToDocumentIdPrefix(collection);
|
||||
return Task.FromResult(prefix + tag + store.Conventions.IdentityPartsSeparator + guid);
|
||||
return Task.FromResult(tag + store.Conventions.IdentityPartsSeparator + guid);
|
||||
});
|
||||
|
||||
store.Conventions.RegisterAsyncIdConvention<IPage>((_, entity) =>
|
||||
|
||||
@@ -93,17 +93,8 @@ namespace zero.Core.Routing
|
||||
return routes;
|
||||
}
|
||||
|
||||
List<IRoute> allRoutes = new List<IRoute>();
|
||||
IList<IPage> pages = await session.Query<IPage>().ToListAsync();
|
||||
//IEnumerable<IGrouping<string, IPage>> groupedPages = pages. pages.GroupBy(x => x.AppId);
|
||||
|
||||
//foreach (var group in groupedPages)
|
||||
//{
|
||||
IList<IRoute> routes = TraversePageChildren(null, new List<IPage>() { }, pages);
|
||||
allRoutes.AddRange(routes);
|
||||
//}
|
||||
|
||||
return allRoutes;
|
||||
return TraversePageChildren(null, new List<IPage>() { }, pages);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+25
-18
@@ -161,31 +161,38 @@ namespace zero.Core.Routing
|
||||
{
|
||||
int count = 0;
|
||||
List<IRoute> all = new List<IRoute>();
|
||||
using IAsyncDocumentSession session = Store.OpenAsyncSession();
|
||||
session.Advanced.MaxNumberOfRequestsPerSession = 1000;
|
||||
|
||||
foreach (IRouteProvider provider in Providers)
|
||||
using IAsyncDocumentSession coreSession = Store.OpenCoreSession();
|
||||
List<IApplication> apps = await coreSession.Query<IApplication>().ToListAsync();
|
||||
|
||||
foreach (IApplication app in apps)
|
||||
{
|
||||
// get all routes for this provider
|
||||
IList<IRoute> routes = await provider.GetAllRoutes(session);
|
||||
using IAsyncDocumentSession session = Store.OpenAsyncSession(app.Database);
|
||||
session.Advanced.MaxNumberOfRequestsPerSession = 1000;
|
||||
|
||||
// delete all registered routes in the database for this provider
|
||||
await Store.PurgeAsync<IRoute>(null, $"where {nameof(IRoute.ProviderAlias)} = $alias", new Raven.Client.Parameters()
|
||||
foreach (IRouteProvider provider in Providers)
|
||||
{
|
||||
{ "alias", provider.Alias }
|
||||
});
|
||||
// get all routes for this provider
|
||||
IList<IRoute> routes = await provider.GetAllRoutes(session);
|
||||
|
||||
// store new routes
|
||||
using (BulkInsertOperation bulkInsert = Store.BulkInsert())
|
||||
{
|
||||
foreach (IRoute route in routes)
|
||||
// delete all registered routes in the database for this provider
|
||||
await Store.PurgeAsync<IRoute>(app.Database, $"where {nameof(IRoute.ProviderAlias)} = $alias", new Raven.Client.Parameters()
|
||||
{
|
||||
await bulkInsert.StoreAsync(route, route.Id);
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
{ "alias", provider.Alias }
|
||||
});
|
||||
|
||||
all.AddRange(routes);
|
||||
// store new routes
|
||||
using (BulkInsertOperation bulkInsert = Store.BulkInsert(app.Database))
|
||||
{
|
||||
foreach (IRoute route in routes)
|
||||
{
|
||||
await bulkInsert.StoreAsync(route, route.Id);
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
all.AddRange(routes);
|
||||
}
|
||||
}
|
||||
|
||||
return all;
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
max-width: 300px;
|
||||
max-width: 100%;
|
||||
|
||||
&.has-icon
|
||||
{
|
||||
|
||||
@@ -714,7 +714,8 @@
|
||||
}
|
||||
|
||||
.ui-pick-preview + .ui-pick-preview,
|
||||
.ui-pick-previews + .ui-select-button
|
||||
.ui-pick-previews + .ui-select-button,
|
||||
.ui-pick-previews + .ui-pick-add
|
||||
{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ a.app-nav-item, button.app-nav-item
|
||||
|
||||
.app-nav-item-icon
|
||||
{
|
||||
color: var(--color-text);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.app-nav-item-arrow
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
--padding-l: 64px;
|
||||
|
||||
--height-top: 74px;
|
||||
--radius: 3px;
|
||||
--radius: 5px;
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
{
|
||||
--shadow: 0 3px 20px rgba(0, 0, 0, 0.07);
|
||||
--shadow-mid: 0 1px 12px rgba(0, 0, 0, 0.03);
|
||||
--shadow-short: 0.5px 0.5px 1.5px 0 rgba(0, 0, 0, 0.06);
|
||||
--shadow-short: 0.5px 0.5px 2px 0 rgba(0, 0, 0, 0.07);
|
||||
//--shadow-dropdown: rgba(0, 0, 0, 0.15);
|
||||
--shadow-dropdown: 3px 6px 15px rgba(0, 0, 0, 0.07);
|
||||
--shadow-overlay: -30px 0 40px rgba(0, 0, 0, 0.07);
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
.theme-dark
|
||||
{
|
||||
// accent colors
|
||||
$color-primary: #1db1b6;
|
||||
$color-primary: #3c9a92; //#18a471
|
||||
$color-primary-fg: #fff;
|
||||
$color-primary-low: #{rgba(#2c3036, 0.2)};
|
||||
$color-secondary: #f9e0c4;
|
||||
$color-secondary-fg: #20242a;
|
||||
$color-secondary: #24b4a6;
|
||||
$color-secondary-fg: #fff;
|
||||
$color-tertiary: #c4e4de;
|
||||
$color-tertiary-fg: #2c3036;
|
||||
|
||||
// foreground colors
|
||||
$color-fg: #fff;
|
||||
@@ -32,6 +34,10 @@
|
||||
--color-primary: #{$color-primary};
|
||||
--color-primary-low: #{$color-primary-low};
|
||||
--color-primary-text: #{$color-primary-fg};
|
||||
--color-secondary: #{$color-secondary};
|
||||
--color-secondary-text: #{$color-secondary-fg};
|
||||
--color-tertiary: #{$color-tertiary};
|
||||
--color-tertiary-text: #{$color-tertiary-fg};
|
||||
|
||||
// generic shades
|
||||
// (try to avoid them)
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
$color-primary: #2c3036; //#18a471
|
||||
$color-primary-fg: #fff;
|
||||
$color-primary-low: #{rgba(#2c3036, 0.2)};
|
||||
$color-secondary: #f9e0c4;
|
||||
$color-secondary-fg: #20242a;
|
||||
$color-secondary: #24b4a6;
|
||||
$color-secondary-fg: #fff;
|
||||
$color-tertiary: #c4e4de;
|
||||
$color-tertiary-fg: #2c3036;
|
||||
|
||||
// foreground colors
|
||||
$color-fg: #2c3036;
|
||||
@@ -15,9 +17,9 @@
|
||||
$color-fg-shade-3: #c8cbcf;
|
||||
|
||||
// background colors
|
||||
$color-bg: #f4f4f7;
|
||||
$color-bg: #f4f4f6;
|
||||
$color-bg-shade-1: #fff; // bright
|
||||
$color-bg-shade-2: #f8f8fa; // dim
|
||||
$color-bg-shade-2: #f8f8f9; // dim
|
||||
$color-bg-shade-3: #f5f5f6; // bright-two
|
||||
$color-bg-shade-4: #efeff1; // bright-three
|
||||
$color-bg-shade-5: #eaecef;
|
||||
@@ -34,6 +36,10 @@
|
||||
--color-primary: #{$color-primary};
|
||||
--color-primary-low: #{$color-primary-low};
|
||||
--color-primary-text: #{$color-primary-fg};
|
||||
--color-secondary: #{$color-secondary};
|
||||
--color-secondary-text: #{$color-secondary-fg};
|
||||
--color-tertiary: #{$color-tertiary};
|
||||
--color-tertiary-text: #{$color-tertiary-fg};
|
||||
|
||||
// generic shades
|
||||
// (try to avoid them)
|
||||
|
||||
Reference in New Issue
Block a user