From d6ca934883000fc76a6a8b4cfb09781fafaafc39 Mon Sep 17 00:00:00 2001 From: Tobias Klika Date: Wed, 25 Nov 2020 14:01:55 +0100 Subject: [PATCH] I don't know, media shit, does not work --- .../Collections/Media/MediaCollection.cs | 80 ++++++++++++++++++- zero.Core/Entities/IAppAwareEntity.cs | 14 ++++ zero.Core/Entities/Media/Media.cs | 13 +-- zero.Core/Entities/Media/MediaFolder.cs | 11 +-- .../RavenDocumentStoreExtensions.cs | 8 +- zero.Core/Routing/Page/PageRouteProvider.cs | 11 +-- zero.Core/Routing/Routes.cs | 43 +++++----- .../components/overlays/dropdown-button.vue | 2 +- zero.Web.UI/App/components/pickers/pick.vue | 3 +- zero.Web.UI/Sass/Canvas/_navigation.scss | 2 +- zero.Web.UI/Sass/Settings/_dimensions.scss | 2 +- zero.Web.UI/Sass/Settings/_shadows.scss | 2 +- zero.Web.UI/Sass/Settings/_theme-dark.scss | 12 ++- zero.Web.UI/Sass/Settings/_theme-light.scss | 14 +++- 14 files changed, 149 insertions(+), 68 deletions(-) create mode 100644 zero.Core/Entities/IAppAwareEntity.cs diff --git a/zero.Core/Collections/Media/MediaCollection.cs b/zero.Core/Collections/Media/MediaCollection.cs index d58503ce..54a07e1a 100644 --- a/zero.Core/Collections/Media/MediaCollection.cs +++ b/zero.Core/Collections/Media/MediaCollection.cs @@ -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, IMediaCollection { + private IAsyncDocumentSession _coreSession; + + public MediaCollection(IZeroContext context, ICollectionInterceptorHandler interceptor, IValidator validator, IPaths paths) : base(context, interceptor, validator) { PreSave = model => model.IsActive = true; @@ -27,6 +31,24 @@ namespace zero.Core.Collections } + /// + /// Create an an async document session + /// + 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 GetById(string id) + { + ApplyScopeBasedOnId(id); + return base.GetById(id); + } + + + public override async Task> GetByIds(params string[] ids) + { + string[] localIds = ids.Where(x => !x.StartsWith(Constants.Database.CoreIdPrefix)).ToArray(); + string[] coreIds = ids.Except(localIds).ToArray(); + + Dictionary result = new Dictionary(); + Dictionary models = null; + + if (localIds.Length > 0) + { + models = await Session.LoadAsync(localIds); + foreach (string id in localIds) + { + models.TryGetValue(id, out IMedia model); + result.Add(id, model); + } + } + if (coreIds.Length > 0) + { + models = await CoreSession.LoadAsync(coreIds); + foreach (string id in coreIds) + { + models.TryGetValue(id, out IMedia model); + result.Add(id, model); + } + } + + return result; + } + + /// public async Task GetSourceById(string id, bool thumb = false) { - if (id.StartsWith(Constants.Database.CoreIdPrefix)) - { - ApplyScope("shared"); - } + ApplyScopeBasedOnId(id); + IMedia media = await Session.LoadAsync(id); if (media == null) @@ -66,6 +124,8 @@ namespace zero.Core.Collections /// public async Task> GetByQuery(MediaListQuery query) { + ApplyScopeBasedOnId(query.FolderId); + query.SearchFor(entity => entity.Name); return await Query @@ -195,6 +255,18 @@ namespace zero.Core.Collections } + /// + /// Applies the shared scope when an ID is prefixed with core. + /// + void ApplyScopeBasedOnId(string id) + { + if (!id.IsNullOrWhiteSpace() && id.StartsWith(Constants.Database.CoreIdPrefix, StringComparison.InvariantCultureIgnoreCase)) + { + ApplyScope("shared"); + } + } + + /// /// Saves a thumbnail of an image /// diff --git a/zero.Core/Entities/IAppAwareEntity.cs b/zero.Core/Entities/IAppAwareEntity.cs new file mode 100644 index 00000000..12fef12a --- /dev/null +++ b/zero.Core/Entities/IAppAwareEntity.cs @@ -0,0 +1,14 @@ +namespace zero.Core.Entities +{ + /// + /// 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 + /// + public interface IAppAwareEntity + { + /// + /// Associated app id of the entity + /// + string AppId { get; set; } + } +} diff --git a/zero.Core/Entities/Media/Media.cs b/zero.Core/Entities/Media/Media.cs index 3782301b..c2a4f82e 100644 --- a/zero.Core/Entities/Media/Media.cs +++ b/zero.Core/Entities/Media/Media.cs @@ -6,6 +6,9 @@ namespace zero.Core.Entities /// public class Media : ZeroEntity, IMedia { + /// + public string AppId { get; set; } + /// public string FileId { get; set; } @@ -38,9 +41,6 @@ namespace zero.Core.Entities /// public MediaType Type { get; set; } - - /// - 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) /// [Collection("Media", LongId = true)] - public interface IMedia : IZeroEntity, IZeroDbConventions + public interface IMedia : IZeroEntity, IZeroDbConventions, IAppAwareEntity { /// /// Id/name of the phyiscal folder which is stored on disk/cloud @@ -104,10 +104,5 @@ namespace zero.Core.Entities /// Type of the media /// MediaType Type { get; set; } - - /// - /// Whether this media item is part of the core database (for multi-tenant setup) - /// - bool IsCore { get; set; } } } diff --git a/zero.Core/Entities/Media/MediaFolder.cs b/zero.Core/Entities/Media/MediaFolder.cs index 4c04cc34..175f005c 100644 --- a/zero.Core/Entities/Media/MediaFolder.cs +++ b/zero.Core/Entities/Media/MediaFolder.cs @@ -6,10 +6,10 @@ namespace zero.Core.Entities public class MediaFolder : ZeroEntity, IMediaFolder { /// - public string ParentId { get; set; } + public string AppId { get; set; } /// - 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 /// [Collection("MediaFolders", LongId = true)] - public interface IMediaFolder : IZeroEntity, IZeroDbConventions + public interface IMediaFolder : IZeroEntity, IZeroDbConventions, IAppAwareEntity { /// /// Parent folder id /// string ParentId { get; set; } - - /// - /// Whether this media folder is part of the core database (for multi-tenant setup) - /// - bool IsCore { get; set; } } } \ No newline at end of file diff --git a/zero.Core/Extensions/RavenDocumentStoreExtensions.cs b/zero.Core/Extensions/RavenDocumentStoreExtensions.cs index c1c9860d..7abbe458 100644 --- a/zero.Core/Extensions/RavenDocumentStoreExtensions.cs +++ b/zero.Core/Extensions/RavenDocumentStoreExtensions.cs @@ -30,22 +30,16 @@ namespace zero.Core.Extensions store.Conventions.RegisterAsyncIdConvention((_, entity) => { - string prefix = String.Empty; string guid = IdGenerator.Create(); string collection = store.Conventions.GetCollectionName(entity); - //CollectionAttribute collectionAttribute = entity.GetType().GetCustomAttribute(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((_, entity) => diff --git a/zero.Core/Routing/Page/PageRouteProvider.cs b/zero.Core/Routing/Page/PageRouteProvider.cs index fc952fee..a60e7ab6 100644 --- a/zero.Core/Routing/Page/PageRouteProvider.cs +++ b/zero.Core/Routing/Page/PageRouteProvider.cs @@ -93,17 +93,8 @@ namespace zero.Core.Routing return routes; } - List allRoutes = new List(); IList pages = await session.Query().ToListAsync(); - //IEnumerable> groupedPages = pages. pages.GroupBy(x => x.AppId); - - //foreach (var group in groupedPages) - //{ - IList routes = TraversePageChildren(null, new List() { }, pages); - allRoutes.AddRange(routes); - //} - - return allRoutes; + return TraversePageChildren(null, new List() { }, pages); } diff --git a/zero.Core/Routing/Routes.cs b/zero.Core/Routing/Routes.cs index 36dc99df..47219c9b 100644 --- a/zero.Core/Routing/Routes.cs +++ b/zero.Core/Routing/Routes.cs @@ -161,31 +161,38 @@ namespace zero.Core.Routing { int count = 0; List all = new List(); - using IAsyncDocumentSession session = Store.OpenAsyncSession(); - session.Advanced.MaxNumberOfRequestsPerSession = 1000; - foreach (IRouteProvider provider in Providers) + using IAsyncDocumentSession coreSession = Store.OpenCoreSession(); + List apps = await coreSession.Query().ToListAsync(); + + foreach (IApplication app in apps) { - // get all routes for this provider - IList 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(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 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(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; diff --git a/zero.Web.UI/App/components/overlays/dropdown-button.vue b/zero.Web.UI/App/components/overlays/dropdown-button.vue index 17e1a638..1078884b 100644 --- a/zero.Web.UI/App/components/overlays/dropdown-button.vue +++ b/zero.Web.UI/App/components/overlays/dropdown-button.vue @@ -155,7 +155,7 @@ white-space: nowrap; text-overflow: ellipsis; overflow: hidden; - max-width: 300px; + max-width: 100%; &.has-icon { diff --git a/zero.Web.UI/App/components/pickers/pick.vue b/zero.Web.UI/App/components/pickers/pick.vue index 3251f13a..cf7a8e37 100644 --- a/zero.Web.UI/App/components/pickers/pick.vue +++ b/zero.Web.UI/App/components/pickers/pick.vue @@ -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; } diff --git a/zero.Web.UI/Sass/Canvas/_navigation.scss b/zero.Web.UI/Sass/Canvas/_navigation.scss index b639ebfa..6eb256ef 100644 --- a/zero.Web.UI/Sass/Canvas/_navigation.scss +++ b/zero.Web.UI/Sass/Canvas/_navigation.scss @@ -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 diff --git a/zero.Web.UI/Sass/Settings/_dimensions.scss b/zero.Web.UI/Sass/Settings/_dimensions.scss index 333d2436..7e2754ec 100644 --- a/zero.Web.UI/Sass/Settings/_dimensions.scss +++ b/zero.Web.UI/Sass/Settings/_dimensions.scss @@ -7,5 +7,5 @@ --padding-l: 64px; --height-top: 74px; - --radius: 3px; + --radius: 5px; } \ No newline at end of file diff --git a/zero.Web.UI/Sass/Settings/_shadows.scss b/zero.Web.UI/Sass/Settings/_shadows.scss index d0965f34..24f3011f 100644 --- a/zero.Web.UI/Sass/Settings/_shadows.scss +++ b/zero.Web.UI/Sass/Settings/_shadows.scss @@ -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); diff --git a/zero.Web.UI/Sass/Settings/_theme-dark.scss b/zero.Web.UI/Sass/Settings/_theme-dark.scss index 4b60a94c..c7254bec 100644 --- a/zero.Web.UI/Sass/Settings/_theme-dark.scss +++ b/zero.Web.UI/Sass/Settings/_theme-dark.scss @@ -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) diff --git a/zero.Web.UI/Sass/Settings/_theme-light.scss b/zero.Web.UI/Sass/Settings/_theme-light.scss index 680a4930..586d7ffc 100644 --- a/zero.Web.UI/Sass/Settings/_theme-light.scss +++ b/zero.Web.UI/Sass/Settings/_theme-light.scss @@ -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)