Browse Source

Style improvements.

pull/711/head
Sebastian Stehle 5 years ago
parent
commit
b57ab4af9c
  1. 9
      backend/src/Migrations/RebuildOptions.cs
  2. 14
      backend/src/Migrations/RebuildRunner.cs
  3. 24
      backend/src/Migrations/RebuilderExtensions.cs
  4. 5
      backend/src/Squidex.Domain.Apps.Entities/Assets/BackupAssets.cs
  5. 4
      backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreGrain.cs
  6. 3
      backend/src/Squidex.Domain.Apps.Entities/Contents/BackupContents.cs
  7. 19
      backend/src/Squidex.Infrastructure/Commands/Rebuilder.cs
  8. 2
      backend/src/Squidex/Areas/IdentityServer/Views/Account/AccessDenied.cshtml
  9. 3
      backend/src/Squidex/Areas/IdentityServer/Views/Account/Consent.cshtml
  10. 2
      backend/src/Squidex/Areas/IdentityServer/Views/Account/LockedOut.cshtml
  11. 2
      backend/src/Squidex/Areas/IdentityServer/Views/Account/Login.cshtml
  12. 2
      backend/src/Squidex/Areas/IdentityServer/Views/Account/LogoutCompleted.cshtml
  13. 6
      backend/src/Squidex/Areas/IdentityServer/Views/Error/Error.cshtml
  14. 5
      backend/src/Squidex/Areas/IdentityServer/Views/Profile/Profile.cshtml
  15. 215
      backend/src/Squidex/Areas/IdentityServer/Views/Setup/Setup.cshtml
  16. 16
      backend/src/Squidex/Areas/IdentityServer/Views/_Layout.cshtml

9
backend/src/Migrations/RebuildOptions.cs

@ -5,6 +5,8 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
namespace Migrations
{
public sealed class RebuildOptions
@ -22,5 +24,12 @@ namespace Migrations
public bool Rules { get; set; }
public bool Schemas { get; set; }
public int BatchSize { get; set; } = 100;
public int CalculateBatchSize()
{
return Math.Max(10, Math.Min(1000, BatchSize));
}
}
}

14
backend/src/Migrations/RebuildRunner.cs

@ -41,25 +41,27 @@ namespace Migrations
public async Task RunAsync(CancellationToken ct)
{
var batchSize = rebuildOptions.CalculateBatchSize();
if (rebuildOptions.Apps)
{
await rebuilder.RebuildAppsAsync(ct);
await rebuilder.RebuildAppsAsync(batchSize, ct);
}
if (rebuildOptions.Schemas)
{
await rebuilder.RebuildSchemasAsync(ct);
await rebuilder.RebuildSchemasAsync(batchSize, ct);
}
if (rebuildOptions.Rules)
{
await rebuilder.RebuildRulesAsync(ct);
await rebuilder.RebuildRulesAsync(batchSize, ct);
}
if (rebuildOptions.Assets)
{
await rebuilder.RebuildAssetsAsync(ct);
await rebuilder.RebuildAssetFoldersAsync(ct);
await rebuilder.RebuildAssetsAsync(batchSize, ct);
await rebuilder.RebuildAssetFoldersAsync(batchSize, ct);
}
if (rebuildOptions.AssetFiles)
@ -69,7 +71,7 @@ namespace Migrations
if (rebuildOptions.Contents)
{
await rebuilder.RebuildContentAsync(ct);
await rebuilder.RebuildContentAsync(batchSize, ct);
}
if (rebuildOptions.Indexes)

24
backend/src/Migrations/RebuilderExtensions.cs

@ -18,34 +18,34 @@ namespace Migrations
{
public static class RebuilderExtensions
{
public static Task RebuildAppsAsync(this Rebuilder rebuilder, CancellationToken ct = default)
public static Task RebuildAppsAsync(this Rebuilder rebuilder, int batchSize, CancellationToken ct = default)
{
return rebuilder.RebuildAsync<AppDomainObject, AppDomainObject.State>("^app\\-", ct);
return rebuilder.RebuildAsync<AppDomainObject, AppDomainObject.State>("^app\\-", batchSize, ct);
}
public static Task RebuildSchemasAsync(this Rebuilder rebuilder, CancellationToken ct = default)
public static Task RebuildSchemasAsync(this Rebuilder rebuilder, int batchSize, CancellationToken ct = default)
{
return rebuilder.RebuildAsync<SchemaDomainObject, SchemaDomainObject.State>("^schema\\-", ct);
return rebuilder.RebuildAsync<SchemaDomainObject, SchemaDomainObject.State>("^schema\\-", batchSize, ct);
}
public static Task RebuildRulesAsync(this Rebuilder rebuilder, CancellationToken ct = default)
public static Task RebuildRulesAsync(this Rebuilder rebuilder, int batchSize, CancellationToken ct = default)
{
return rebuilder.RebuildAsync<RuleDomainObject, RuleDomainObject.State>("^rule\\-", ct);
return rebuilder.RebuildAsync<RuleDomainObject, RuleDomainObject.State>("^rule\\-", batchSize, ct);
}
public static Task RebuildAssetsAsync(this Rebuilder rebuilder, CancellationToken ct = default)
public static Task RebuildAssetsAsync(this Rebuilder rebuilder, int batchSize, CancellationToken ct = default)
{
return rebuilder.RebuildAsync<AssetDomainObject, AssetDomainObject.State>("^asset\\-", ct);
return rebuilder.RebuildAsync<AssetDomainObject, AssetDomainObject.State>("^asset\\-", batchSize, ct);
}
public static Task RebuildAssetFoldersAsync(this Rebuilder rebuilder, CancellationToken ct = default)
public static Task RebuildAssetFoldersAsync(this Rebuilder rebuilder, int batchSize, CancellationToken ct = default)
{
return rebuilder.RebuildAsync<AssetFolderDomainObject, AssetFolderDomainObject.State>("^assetFolder\\-", ct);
return rebuilder.RebuildAsync<AssetFolderDomainObject, AssetFolderDomainObject.State>("^assetFolder\\-", batchSize, ct);
}
public static Task RebuildContentAsync(this Rebuilder rebuilder, CancellationToken ct = default)
public static Task RebuildContentAsync(this Rebuilder rebuilder, int batchSize, CancellationToken ct = default)
{
return rebuilder.RebuildAsync<ContentDomainObject, ContentDomainObject.State>("^content\\-", ct);
return rebuilder.RebuildAsync<ContentDomainObject, ContentDomainObject.State>("^content\\-", batchSize, ct);
}
}
}

5
backend/src/Squidex.Domain.Apps.Entities/Assets/BackupAssets.cs

@ -21,6 +21,7 @@ namespace Squidex.Domain.Apps.Entities.Assets
{
public sealed class BackupAssets : IBackupHandler
{
private const int BatchSize = 100;
private const string TagsFile = "AssetTags.json";
private readonly HashSet<DomainId> assetIds = new HashSet<DomainId>();
private readonly HashSet<DomainId> assetFolderIds = new HashSet<DomainId>();
@ -101,12 +102,12 @@ namespace Squidex.Domain.Apps.Entities.Assets
if (assetIds.Count > 0)
{
await rebuilder.InsertManyAsync<AssetDomainObject, AssetDomainObject.State>(assetIds);
await rebuilder.InsertManyAsync<AssetDomainObject, AssetDomainObject.State>(assetIds, BatchSize);
}
if (assetFolderIds.Count > 0)
{
await rebuilder.InsertManyAsync<AssetFolderDomainObject, AssetFolderDomainObject.State>(assetFolderIds);
await rebuilder.InsertManyAsync<AssetFolderDomainObject, AssetFolderDomainObject.State>(assetFolderIds, BatchSize);
}
}

4
backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreGrain.cs

@ -1,4 +1,4 @@
// ==========================================================================
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
@ -356,7 +356,7 @@ namespace Squidex.Domain.Apps.Entities.Backup
var batchBlock = new BatchBlock<(string, Envelope<IEvent>)>(BatchSize, new GroupingDataflowBlockOptions
{
BoundedCapacity = BatchSize
BoundedCapacity = BatchSize * 2
});
batchBlock.LinkTo(writeBlock, new DataflowLinkOptions

3
backend/src/Squidex.Domain.Apps.Entities/Contents/BackupContents.cs

@ -24,6 +24,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
{
public sealed class BackupContents : IBackupHandler
{
private const int BatchSize = 100;
private delegate void ObjectSetter(IReadOnlyDictionary<string, IJsonValue> obj, string key, IJsonValue value);
private const string UrlsFile = "Urls.json";
@ -216,7 +217,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
if (ids.Any())
{
await rebuilder.InsertManyAsync<ContentDomainObject, ContentDomainObject.State>(ids);
await rebuilder.InsertManyAsync<ContentDomainObject, ContentDomainObject.State>(ids, BatchSize);
}
}

19
backend/src/Squidex.Infrastructure/Commands/Rebuilder.cs

@ -19,8 +19,6 @@ using Squidex.Infrastructure.States;
namespace Squidex.Infrastructure.Commands
{
public delegate Task IdSource(Func<DomainId, Task> add);
public class Rebuilder
{
private readonly ILocalCache localCache;
@ -51,7 +49,7 @@ namespace Squidex.Infrastructure.Commands
this.localCache = localCache;
}
public virtual async Task RebuildAsync<T, TState>(string filter, CancellationToken ct) where T : DomainObject<TState> where TState : class, IDomainState<TState>, new()
public virtual async Task RebuildAsync<T, TState>(string filter, int batchSize, CancellationToken ct = default) where T : DomainObject<TState> where TState : class, IDomainState<TState>, new()
{
var store = serviceProvider.GetRequiredService<IStore<TState>>();
@ -65,12 +63,13 @@ namespace Squidex.Infrastructure.Commands
await target(id);
}
}, ct);
}, batchSize, ct);
}
public virtual async Task InsertManyAsync<T, TState>(IEnumerable<DomainId> source, CancellationToken ct = default) where T : DomainObject<TState> where TState : class, IDomainState<TState>, new()
public virtual async Task InsertManyAsync<T, TState>(IEnumerable<DomainId> source, int batchSize, CancellationToken ct = default) where T : DomainObject<TState> where TState : class, IDomainState<TState>, new()
{
Guard.NotNull(source, nameof(source));
Guard.Between(batchSize, 1, 1000, nameof(batchSize));
var store = serviceProvider.GetRequiredService<IStore<TState>>();
@ -80,15 +79,13 @@ namespace Squidex.Infrastructure.Commands
{
await target(id);
}
}, ct);
}, batchSize, ct);
}
private async Task InsertManyAsync<T, TState>(IStore<TState> store, IdSource source, CancellationToken ct = default) where T : DomainObject<TState> where TState : class, IDomainState<TState>, new()
private async Task InsertManyAsync<T, TState>(IStore<TState> store, Func<Func<DomainId, Task>, Task> source, int batchSize, CancellationToken ct = default) where T : DomainObject<TState> where TState : class, IDomainState<TState>, new()
{
var parallelism = Environment.ProcessorCount;
const int BatchSize = 100;
var workerBlock = new ActionBlock<DomainId[]>(async ids =>
{
try
@ -127,9 +124,9 @@ namespace Squidex.Infrastructure.Commands
BoundedCapacity = parallelism
});
var batchBlock = new BatchBlock<DomainId>(BatchSize, new GroupingDataflowBlockOptions
var batchBlock = new BatchBlock<DomainId>(batchSize, new GroupingDataflowBlockOptions
{
BoundedCapacity = BatchSize
BoundedCapacity = batchSize
});
batchBlock.LinkTo(workerBlock, new DataflowLinkOptions

2
backend/src/Squidex/Areas/IdentityServer/Views/Account/AccessDenied.cshtml

@ -1,6 +1,4 @@
@{
ViewBag.ThemeColor = "white";
ViewBag.Title = T.Get("users.accessDenied.title");
}

3
backend/src/Squidex/Areas/IdentityServer/Views/Account/Consent.cshtml

@ -1,9 +1,6 @@
@model Squidex.Areas.IdentityServer.Controllers.Account.ConsentVM
@{
ViewBag.ThemeColor = "white";
ViewBag.ThemeSize = "profile-lg";
ViewBag.Title = T.Get("users.consent.title");
}

2
backend/src/Squidex/Areas/IdentityServer/Views/Account/LockedOut.cshtml

@ -1,6 +1,4 @@
@{
ViewBag.ThemeColor = "white";
ViewBag.Title = T.Get("users.lockedOutTitle");
}

2
backend/src/Squidex/Areas/IdentityServer/Views/Account/Login.cshtml

@ -1,8 +1,6 @@
@model Squidex.Areas.IdentityServer.Controllers.Account.LoginVM
@{
ViewBag.ThemeColor = "white";
var action = Model.IsLogin ? T.Get("common.login") : T.Get("common.signup");
ViewBag.Title = action;

2
backend/src/Squidex/Areas/IdentityServer/Views/Account/LogoutCompleted.cshtml

@ -1,6 +1,4 @@
@{
ViewBag.ThemeColor = "white";
ViewBag.Title = T.Get("users.logout.title");
}

6
backend/src/Squidex/Areas/IdentityServer/Views/Error/Error.cshtml

@ -1,8 +1,6 @@
@model Squidex.Areas.IdentityServer.Controllers.Error.ErrorVM
@{
ViewBag.ThemeColor = "white";
ViewBag.Title = T.Get("users.error.title");
}
@ -11,9 +9,9 @@
<h1 class="splash-h1">@T.Get("users.error.headline")</h1>
<p class="splash-text">
@if (Model.ErrorMessage != null)
@if (Model.Error?.ErrorDescription != null)
{
@Model.ErrorMessage
@Model.Error.ErrorDescription
}
else
{

5
backend/src/Squidex/Areas/IdentityServer/Views/Profile/Profile.cshtml

@ -1,9 +1,6 @@
@model Squidex.Areas.IdentityServer.Controllers.Profile.ProfileVM
@{
ViewBag.ThemeColor = "white";
ViewBag.ThemeSize = "profile-lg";
ViewBag.Title = T.Get("users.profile.title");
void RenderValidation(string field)
@ -279,7 +276,7 @@
}
document.addEventListener('click',
function(event) {
function (event) {
if (event.target.className.indexOf('remove-item') >= 0) {
event.target.parentNode.parentNode.remove();

215
backend/src/Squidex/Areas/IdentityServer/Views/Setup/Setup.cshtml

@ -1,9 +1,6 @@
@model Squidex.Areas.IdentityServer.Controllers.Setup.SetupVM
@{
ViewBag.ThemeColor = "gray";
ViewBag.ThemeSize = "profile-lg";
ViewBag.Title = T.Get("setup.title");
void RenderValidation(string field)
@ -68,134 +65,124 @@
}
}
<div class="card">
<div class="card-body">
<h1>@T.Get("setup.headline")</h1>
<img style="height: 250px" class="mt-2 mb-2" src="@Url.RootContentUrl("~/squid.svg?title=Welcome&text=Welcome%20to%20the%20Installation%20Process&face=happy")" />
<small class="form-text text-muted mt-2 mb-2">@T.Get("setup.hint")</small>
<div class="profile-section">
<h2>@T.Get("setup.rules.headline")</h2>
@if (Model.IsValidHttps)
{
RenderRuleAsSuccess(T.Get("setup.ruleHttps.success"));
}
else
{
RenderRuleAsCritical(T.Get("setup.ruleHttps.failure"));
}
@if (Model.BaseUrlConfigured == Model.BaseUrlCurrent)
{
RenderRuleAsSuccess(T.Get("setup.ruleUrl.success"));
}
else
{
RenderRuleAsCritical(T.Get("setup.ruleUrl.failure", new { actual = Model.BaseUrlCurrent, configured = Model.BaseUrlConfigured }));
}
@if (Model.EverybodyCanCreateApps)
{
RenderRuleAsWarning(T.Get("setup.ruleAppCreation.warningAdmins"));
}
else
{
RenderRuleAsWarning(T.Get("setup.ruleAppCreation.warningAll"));
}
@if (Model.IsAssetStoreFtp)
{
RenderRuleAsWarning(T.Get("setup.ruleFtp.warning"));
}
@if (Model.IsAssetStoreFile)
{
RenderRuleAsWarning(T.Get("setup.ruleFolder.warning"));
}
</div>
<h1>@T.Get("setup.headline")</h1>
<hr />
<img style="height: 250px" class="mt-2 mb-2" src="@Url.RootContentUrl("~/squid.svg?title=Welcome&text=Welcome%20to%20the%20Installation%20Process&face=happy")" />
<div class="profile-section">
<h2>@T.Get("setup.createUser.headline")</h2>
<small class="form-text text-muted mt-2 mb-2">@T.Get("setup.hint")</small>
@if (Model.HasExternalLogin)
{
<div>
<small class="form-text text-muted mt-2 mb-2">@T.Get("setup.createUser.loginHint")</small>
<div class="profile-section">
<h2>@T.Get("setup.rules.headline")</h2>
<div class="mt-3">
<a class="btn btn-primary" asp-controller="Account" asp-action="Login">
@T.Get("setup.createUser.loginLink")
</a>
</div>
</div>
}
@if (Model.IsValidHttps)
{
RenderRuleAsSuccess(T.Get("setup.ruleHttps.success"));
}
else
{
RenderRuleAsCritical(T.Get("setup.ruleHttps.failure"));
}
@if (Model.HasExternalLogin && Model.HasPasswordAuth)
{
<div class="profile-separator">
<div class="profile-separator-text">@T.Get("setup.createUser.separator")</div>
</div>
}
@if (Model.BaseUrlConfigured == Model.BaseUrlCurrent)
{
RenderRuleAsSuccess(T.Get("setup.ruleUrl.success"));
}
else
{
RenderRuleAsCritical(T.Get("setup.ruleUrl.failure", new { actual = Model.BaseUrlCurrent, configured = Model.BaseUrlConfigured }));
}
@if (Model.EverybodyCanCreateApps)
{
RenderRuleAsWarning(T.Get("setup.ruleAppCreation.warningAdmins"));
}
else
{
RenderRuleAsWarning(T.Get("setup.ruleAppCreation.warningAll"));
}
@if (Model.IsAssetStoreFtp)
{
RenderRuleAsWarning(T.Get("setup.ruleFtp.warning"));
}
@if (Model.IsAssetStoreFile)
{
RenderRuleAsWarning(T.Get("setup.ruleFolder.warning"));
}
</div>
<hr />
@if (Model.HasPasswordAuth)
{
<h3>@T.Get("setup.createUser.headlineCreate")</h3>
<div class="profile-section">
<h2>@T.Get("setup.createUser.headline")</h2>
@if (!string.IsNullOrWhiteSpace(Model.ErrorMessage))
{
<div class="form-alert form-alert-error">
@Model.ErrorMessage
</div>
}
@if (Model.HasExternalLogin)
{
<div>
<small class="form-text text-muted mt-2 mb-2">@T.Get("setup.createUser.loginHint")</small>
<div class="mt-3">
<a class="btn btn-primary" asp-controller="Account" asp-action="Login">
@T.Get("setup.createUser.loginLink")
</a>
</div>
</div>
}
@if (Model.HasExternalLogin && Model.HasPasswordAuth)
{
<div class="profile-separator">
<div class="profile-separator-text">@T.Get("setup.createUser.separator")</div>
</div>
}
@if (Model.HasPasswordAuth)
{
<h3>@T.Get("setup.createUser.headlineCreate")</h3>
@if (!string.IsNullOrWhiteSpace(Model.ErrorMessage))
{
<div class="form-alert form-alert-error">
@Model.ErrorMessage
</div>
}
<form class="profile-form" asp-controller="Setup" asp-action="Setup" method="post">
<div class="form-group">
<label for="email">@T.Get("common.email")</label>
<form class="profile-form" asp-controller="Setup" asp-action="Setup" method="post">
<div class="form-group">
<label for="email">@T.Get("common.email")</label>
@{ RenderValidation("Email"); }
@{ RenderValidation("Email"); }
<input type="text" class="form-control" name="email" id="email" />
</div>
<input type="text" class="form-control" name="email" id="email" />
</div>
<div class="form-group">
<label for="password">@T.Get("common.password")</label>
<div class="form-group">
<label for="password">@T.Get("common.password")</label>
@{ RenderValidation("Password"); }
@{ RenderValidation("Password"); }
<input type="password" class="form-control" name="password" id="password" />
</div>
<input type="password" class="form-control" name="password" id="password" />
</div>
<div class="form-group">
<label for="passwordConfirm">@T.Get("setup.createUser.confirmPassword")</label>
<div class="form-group">
<label for="passwordConfirm">@T.Get("setup.createUser.confirmPassword")</label>
@{ RenderValidation("PasswordConfirm"); }
@{ RenderValidation("PasswordConfirm"); }
<input type="password" class="form-control" name="passwordConfirm" id="passwordConfirm" />
</div>
<input type="password" class="form-control" name="passwordConfirm" id="passwordConfirm" />
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">@T.Get("setup.createUser.button")</button>
</div>
</form>
}
<div class="form-group">
<button type="submit" class="btn btn-success">@T.Get("setup.createUser.button")</button>
</div>
</form>
}
@if (!Model.HasExternalLogin && !Model.HasPasswordAuth)
{
<div>
@T.Get("setup.createUser.failure")
</div>
}
@if (!Model.HasExternalLogin && !Model.HasPasswordAuth)
{
<div>
@T.Get("setup.createUser.failure")
</div>
</div>
</div>
<div class="text-center mt-4 mb-2">
<small class="text-muted">
@T.Get("setup.madeBy")<br />@T.Get("setup.madeByCopyright")
</small>
}
</div>

16
backend/src/Squidex/Areas/IdentityServer/Views/_Layout.cshtml

@ -17,11 +17,21 @@
@await RenderSectionAsync("header")
}
</head>
<body class="@ViewBag.ThemeColor">
<div class="profile @ViewBag.ThemeSize">
<body class="profile">
<div class="profile-container">
<img class="profile-logo" alt="@T.Get("common.product")S" title="@T.Get("common.product")" src="@Url.RootContentUrl("~/images/logo.svg")" />
@RenderBody()
<div class="profile-card card">
<div class="profile-card-body card-body">
@RenderBody()
</div>
</div>
<div class="profile-footer text-center mt-4 mb-2">
<small class="text-muted">
@T.Get("setup.madeBy")<br />@T.Get("setup.madeByCopyright")
</small>
</div>
</div>
<environment names="Development">

Loading…
Cancel
Save