Browse Source

Notifo fixes (#965)

* Fixes to notifo.

* Simplify contributors pages.
pull/966/head
Sebastian Stehle 3 years ago
committed by GitHub
parent
commit
dc5da0810c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      backend/src/Squidex.Domain.Apps.Entities/History/NotifoService.cs
  2. 13
      backend/src/Squidex.Domain.Users/UserWithClaims.cs
  3. 7
      backend/src/Squidex.Infrastructure/Reflection/SimpleMapper.cs
  4. 2
      frontend/src/app/features/content/pages/content/content-page.component.html
  5. 22
      frontend/src/app/features/settings/pages/contributors/contributors-page.component.html
  6. 26
      frontend/src/app/features/teams/pages/contributors/contributors-page.component.html
  7. 10
      frontend/src/app/shared/components/notifo.component.scss

14
backend/src/Squidex.Domain.Apps.Entities/History/NotifoService.cs

@ -66,20 +66,14 @@ public class NotifoService : IUserEvents
} }
} }
public async Task OnUserCreatedAsync(IUser user) public Task OnUserCreatedAsync(IUser user)
{ {
if (!string.IsNullOrWhiteSpace(user.Email)) return UpsertUserAsync(user);
{
await UpsertUserAsync(user);
}
} }
public async Task OnUserUpdatedAsync(IUser user, IUser previous) public Task OnUserUpdatedAsync(IUser user, IUser previous)
{ {
if (!string.Equals(user.Email, previous?.Email, StringComparison.OrdinalIgnoreCase)) return UpsertUserAsync(user);
{
await UpsertUserAsync(user);
}
} }
private async Task UpsertUserAsync(IUser user) private async Task UpsertUserAsync(IUser user)

13
backend/src/Squidex.Domain.Users/UserWithClaims.cs

@ -7,27 +7,30 @@
using System.Security.Claims; using System.Security.Claims;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Squidex.Infrastructure.Reflection;
using Squidex.Shared.Users; using Squidex.Shared.Users;
namespace Squidex.Domain.Users; namespace Squidex.Domain.Users;
internal sealed class UserWithClaims : IUser internal sealed class UserWithClaims : IUser
{ {
private readonly IdentityUser snapshot;
public IdentityUser Identity { get; } public IdentityUser Identity { get; }
public string Id public string Id
{ {
get => Identity.Id; get => snapshot.Id;
} }
public string Email public string Email
{ {
get => Identity.Email!; get => snapshot.Email!;
} }
public bool IsLocked public bool IsLocked
{ {
get => Identity.LockoutEnd > DateTime.UtcNow; get => snapshot.LockoutEnd > DateTime.UtcNow;
} }
public IReadOnlyList<Claim> Claims { get; } public IReadOnlyList<Claim> Claims { get; }
@ -38,6 +41,10 @@ internal sealed class UserWithClaims : IUser
{ {
Identity = user; Identity = user;
// Clone the user so that we capture the previous values, even when the user is updated.
snapshot = SimpleMapper.Map(user, new IdentityUser());
// Claims are immutable so we do not need a copy of them.
Claims = claims; Claims = claims;
} }
} }

7
backend/src/Squidex.Infrastructure/Reflection/SimpleMapper.cs

@ -206,13 +206,6 @@ public static class SimpleMapper
} }
} }
public static TTarget Map<TSource, TTarget>(TSource source)
where TSource : class
where TTarget : class, new()
{
return Map(source, new TTarget(), CultureInfo.CurrentCulture);
}
public static TTarget Map<TSource, TTarget>(TSource source, TTarget target) public static TTarget Map<TSource, TTarget>(TSource source, TTarget target)
where TSource : class where TSource : class
where TTarget : class where TTarget : class

2
frontend/src/app/features/content/pages/content/content-page.component.html

@ -53,7 +53,7 @@
<ng-container *ngIf="content; else noContentMenu"> <ng-container *ngIf="content; else noContentMenu">
<sqx-watching-users resource="{{schema.id}}/{{content.id}}"></sqx-watching-users> <sqx-watching-users resource="{{schema.id}}/{{content.id}}"></sqx-watching-users>
<sqx-notifo topic="apps/{{contentsState.appId}}/schemas/{{schema.name}}/contents/{{content.id}}"></sqx-notifo> <sqx-notifo topic="apps/{{contentsState.appId}}/schemas/{{schema.id}}/contents/{{content.id}}"></sqx-notifo>
<sqx-language-selector class="languages-buttons" <sqx-language-selector class="languages-buttons"
(languageChange)="changeLanguage($event)" (languageChange)="changeLanguage($event)"

22
frontend/src/app/features/settings/pages/contributors/contributors-page.component.html

@ -2,20 +2,18 @@
<sqx-layout layout="main" titleText="i18n:common.contributors" titleIcon="contributors" [innerWidth]="55"> <sqx-layout layout="main" titleText="i18n:common.contributors" titleIcon="contributors" [innerWidth]="55">
<ng-container menu> <ng-container menu>
<div class="d-flex justify-content-end"> <sqx-notifo topic="apps/{{contributorsState.appId}}/settings/contributors"></sqx-notifo>
<sqx-notifo topic="apps/{{contributorsState.appId}}/settings/contributors"></sqx-notifo>
<button type="button" class="btn btn-text-secondary me-2" (click)="reload()" title="i18n:contributors.refreshTooltip" shortcut="CTRL + B"> <button type="button" class="btn btn-text-secondary me-2" (click)="reload()" title="i18n:contributors.refreshTooltip" shortcut="CTRL + B">
<i class="icon-reset"></i> {{ 'common.refresh' | sqxTranslate }} <i class="icon-reset"></i> {{ 'common.refresh' | sqxTranslate }}
</button> </button>
<div class="form-inline"> <div class="form-inline">
<input class="form-control" placeholder="{{ 'contributors.search' | sqxTranslate }}" <input class="form-control" placeholder="{{ 'contributors.search' | sqxTranslate }}"
[ngModel]="contributorsState.query | async" [ngModel]="contributorsState.query | async"
(ngModelChange)="search($event)" (ngModelChange)="search($event)"
shortcut="CTRL + I" shortcut="CTRL + I"
shortcutAction="focus"> shortcutAction="focus">
</div>
</div> </div>
</ng-container> </ng-container>

26
frontend/src/app/features/teams/pages/contributors/contributors-page.component.html

@ -2,20 +2,18 @@
<sqx-layout layout="main" titleText="i18n:common.contributors" titleIcon="contributors" [innerWidth]="55"> <sqx-layout layout="main" titleText="i18n:common.contributors" titleIcon="contributors" [innerWidth]="55">
<ng-container menu> <ng-container menu>
<div class="d-flex justify-content-end"> <sqx-notifo topic="apps/{{contributorsState.teamId}}/settings/contributors"></sqx-notifo>
<sqx-notifo topic="apps/{{contributorsState.teamId}}/settings/contributors"></sqx-notifo>
<button type="button" class="btn btn-text-secondary me-2" (click)="reload()" title="i18n:contributors.refreshTooltip" shortcut="CTRL + B">
<button type="button" class="btn btn-text-secondary me-2" (click)="reload()" title="i18n:contributors.refreshTooltip" shortcut="CTRL + B"> <i class="icon-reset"></i> {{ 'common.refresh' | sqxTranslate }}
<i class="icon-reset"></i> {{ 'common.refresh' | sqxTranslate }} </button>
</button>
<div class="form-inline">
<div class="form-inline"> <input class="form-control" placeholder="{{ 'contributors.search' | sqxTranslate }}"
<input class="form-control" placeholder="{{ 'contributors.search' | sqxTranslate }}" [ngModel]="contributorsState.query | async"
[ngModel]="contributorsState.query | async" (ngModelChange)="search($event)"
(ngModelChange)="search($event)" shortcut="CTRL + I"
shortcut="CTRL + I" shortcutAction="focus">
shortcutAction="focus">
</div>
</div> </div>
</ng-container> </ng-container>

10
frontend/src/app/shared/components/notifo.component.scss

@ -21,11 +21,11 @@
fill: $color-text-decent; fill: $color-text-decent;
} }
} }
}
.notifo-container { .notifo-container {
display: inline-block; display: inline-block;
max-width: 5rem; max-width: 5rem;
min-width: 3rem; min-width: 3rem;
}
} }
} }
Loading…
Cancel
Save