Some fixes from last release (#1884)

* Removed SecurityEvent middleware solution. It was out of scope originally.

* Fixed manage users still calling pending when the api is no more

* Added back the online indicator on manage users
This commit is contained in:
Joe Milazzo 2023-03-16 19:03:56 -05:00 committed by GitHub
parent 93bd7d7c19
commit d070da2834
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 1940 additions and 177 deletions

View file

@ -36,10 +36,6 @@ export class MemberService {
return this.httpClient.get<boolean>(this.baseUrl + 'users/has-reading-progress?libraryId=' + librayId);
}
getPendingInvites() {
return this.httpClient.get<Array<Member>>(this.baseUrl + 'users/pending');
}
addSeriesToWantToRead(seriesIds: Array<number>) {
return this.httpClient.post<Array<Member>>(this.baseUrl + 'want-to-read/add-series', {seriesIds});
}

View file

@ -96,7 +96,7 @@ export class MessageHubService {
private hubConnection!: HubConnection;
private messagesSource = new ReplaySubject<Message<any>>(1);
private onlineUsersSource = new BehaviorSubject<number[]>([]); // UserIds
private onlineUsersSource = new BehaviorSubject<string[]>([]); // UserNames
/**
* Any events that come from the backend
@ -142,7 +142,7 @@ export class MessageHubService {
.start()
.catch(err => console.error(err));
this.hubConnection.on(EVENTS.OnlineUsers, (usernames: number[]) => {
this.hubConnection.on(EVENTS.OnlineUsers, (usernames: string[]) => {
this.onlineUsersSource.next(usernames);
});

View file

@ -5,7 +5,7 @@
</div>
<div class="modal-body scrollable-modal">
<p>
Invite a user to your server. Enter their email in and we will send them an email to create an account. If you do not want to use our email service, you can <a href="https://wiki.kavitareader.com/en/guides/misc/email" rel="noopener noreferrer" target="_blank" rel="noopener noreferrer">host your own</a>
Invite a user to your server. Enter their email in and we will send them an email to create an account. If you do not want to use our email service, you can <a href="https://wiki.kavitareader.com/en/guides/misc/email" rel="noopener noreferrer" target="_blank">host your own</a>
email service or use a fake email (Forgot User will not work). A link will be presented regardless and can be used to setup the account manually.
</p>

View file

@ -10,7 +10,6 @@
<li *ngFor="let member of members; let idx = index;" class="list-group-item no-hover">
<div>
<h4>
<i class="presence fa fa-circle" title="Active" aria-hidden="true" *ngIf="false && (messageHub.onlineUsers$ | async)?.includes(member.id)"></i>
<span id="member-name--{{idx}}">{{member.username | titlecase}} </span>
<span *ngIf="member.username === loggedInUsername">
<i class="fas fa-star" aria-hidden="true"></i>
@ -30,7 +29,7 @@
<div>Last Active:
<span *ngIf="member.lastActive === '0001-01-01T00:00:00'; else activeDate">Never</span>
<ng-template #activeDate>
{{member.lastActive | date: 'short'}}
{{member.lastActive | date: 'short'}} <i class="presence fa fa-circle ms-1" title="Online Now" aria-hidden="true" *ngIf="(messageHub.onlineUsers$ | async)?.includes(member.username)"></i>
</ng-template>
</div>
<div *ngIf="!hasAdminRole(member)">Sharing: {{formatLibraries(member)}}</div>

View file

@ -1,5 +1,6 @@
.presence {
font-size: 12px;
color: var(--primary-color);
}
.user-info > div {

View file

@ -1,9 +1,8 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { catchError, take } from 'rxjs/operators';
import { take } from 'rxjs/operators';
import { MemberService } from 'src/app/_services/member.service';
import { Member } from 'src/app/_models/auth/member';
import { User } from 'src/app/_models/user';
import { AccountService } from 'src/app/_services/account.service';
import { ToastrService } from 'ngx-toastr';
import { ResetPasswordModalComponent } from '../_modals/reset-password-modal/reset-password-modal.component';
@ -23,7 +22,6 @@ import { Router } from '@angular/router';
export class ManageUsersComponent implements OnInit, OnDestroy {
members: Member[] = [];
pendingInvites: Member[] = [];
loggedInUsername = '';
loadingMembers = false;
@ -47,8 +45,6 @@ export class ManageUsersComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.loadMembers();
this.loadPendingInvites();
}
ngOnDestroy() {
@ -75,24 +71,6 @@ export class ManageUsersComponent implements OnInit, OnDestroy {
});
}
loadPendingInvites() {
this.pendingInvites = [];
this.memberService.getPendingInvites().subscribe(members => {
this.pendingInvites = members;
// Show logged in user at the top of the list
this.pendingInvites.sort((a: Member, b: Member) => {
if (a.username === this.loggedInUsername) return 1;
if (b.username === this.loggedInUsername) return 1;
const nameA = a.username.toUpperCase();
const nameB = b.username.toUpperCase();
if (nameA < nameB) return -1;
if (nameA > nameB) return 1;
return 0;
})
});
}
canEditMember(member: Member): boolean {
return this.loggedInUsername !== member.username;
}
@ -111,7 +89,6 @@ export class ManageUsersComponent implements OnInit, OnDestroy {
this.memberService.deleteMember(member.username).subscribe(() => {
setTimeout(() => {
this.loadMembers();
this.loadPendingInvites();
this.toastr.success(member.username + ' has been deleted.');
}, 30); // SetTimeout because I've noticed this can run super fast and not give enough time for data to flush
});
@ -121,10 +98,12 @@ export class ManageUsersComponent implements OnInit, OnDestroy {
inviteUser() {
const modalRef = this.modalService.open(InviteUserComponent, {size: 'lg'});
modalRef.closed.subscribe((successful: boolean) => {
this.loadPendingInvites();
this.loadMembers();
});
}
log(o: any) {console.log(o)}
resendEmail(member: Member) {
this.serverService.isServerAccessible().subscribe(canAccess => {
this.accountService.resendConfirmationEmail(member.id).subscribe(async (email) => {

View file

@ -5,9 +5,17 @@
</ng-container>
<ng-template #useLink>
<a class="side-nav-item" href="javascript:void(0);" [ngClass]="{'closed': (navService.sideNavCollapsed$ | async), 'active': highlighted}" [routerLink]="link">
<ng-container [ngTemplateOutlet]="inner"></ng-container>
</a>
<ng-container *ngIf="external; else internal">
<a class="side-nav-item" [href]="link" [ngClass]="{'closed': (navService.sideNavCollapsed$ | async), 'active': highlighted}" rel="noopener noreferrer" target="_blank">
<ng-container [ngTemplateOutlet]="inner"></ng-container>
</a>
</ng-container>
<ng-template #internal>
<a class="side-nav-item" href="javascript:void(0);" [ngClass]="{'closed': (navService.sideNavCollapsed$ | async), 'active': highlighted}" [routerLink]="link">
<ng-container [ngTemplateOutlet]="inner"></ng-container>
</a>
</ng-template>
</ng-template>

View file

@ -25,6 +25,10 @@ export class SideNavItemComponent implements OnInit, OnDestroy {
* If a link should be generated when clicked. By default (undefined), no link will be generated
*/
@Input() link: string | undefined;
/**
* If external, link will be used as full href and rel will be applied
*/
@Input() external: boolean = false;
@Input() comparisonMethod: 'startsWith' | 'equals' = 'equals';

View file

@ -17,6 +17,7 @@
</app-side-nav-item>
<app-side-nav-item icon="fa-bookmark" title="Bookmarks" link="/bookmarks/"></app-side-nav-item>
<app-side-nav-item icon="fa-regular fa-rectangle-list" title="All Series" link="/all-series/" *ngIf="libraries.length > 0"></app-side-nav-item>
<app-side-nav-item icon="fa-heart" title="Donate" link="https://opencollective.com/kavita" [external]="true"></app-side-nav-item>
<div class="mb-2 mt-3 ms-2 me-2" *ngIf="libraries.length > 10 && (navService?.sideNavCollapsed$ | async) === false">
<label for="filter" class="form-label visually-hidden">Filter</label>
<div class="form-group">