diff --git a/src/app/auth/impersonation/impersonation.component.html b/src/app/auth/impersonation/impersonation.component.html
index 3afe00c..985aa74 100644
--- a/src/app/auth/impersonation/impersonation.component.html
+++ b/src/app/auth/impersonation/impersonation.component.html
@@ -1,14 +1,12 @@
@if (isAdmin()) {
-
-
- User to impersonate
-
- {{getUsername()}}
- @for (user of users; track user.id) {
- {{ user.name }}
- }
-
-
-
+
+ User to impersonate
+
+ {{getUsername()}}
+ @for (user of (users$ | async | excludeById : auth.getUserId()); track user.id) {
+ {{ user.name }}
+ }
+
+
}
\ No newline at end of file
diff --git a/src/app/auth/impersonation/impersonation.component.ts b/src/app/auth/impersonation/impersonation.component.ts
index 256233f..ff23851 100644
--- a/src/app/auth/impersonation/impersonation.component.ts
+++ b/src/app/auth/impersonation/impersonation.component.ts
@@ -1,21 +1,22 @@
-import { Component, inject, Inject, OnInit, PLATFORM_ID } from '@angular/core';
+import { Component, inject, OnInit } from '@angular/core';
import { ApiAuthenticationService } from '../../shared/services/api/api-authentication.service';
import { MatCardModule } from '@angular/material/card';
import { MatSelectModule } from '@angular/material/select';
import { HttpClient } from '@angular/common/http';
-import { isPlatformBrowser } from '@angular/common';
import { environment } from '../../../environments/environment';
import EventService from '../../shared/services/EventService';
import { HermesClientService } from '../../hermes-client.service';
-import { Router } from '@angular/router';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
-import { User } from '../../shared/models/user';
import { UserService } from '../../shared/services/user.service';
+import { AsyncPipe } from '@angular/common';
+import { ExcludeByIdPipe } from '../../shared/pipes/exclude-by-id.pipe';
@Component({
selector: 'impersonation',
standalone: true,
imports: [
+ AsyncPipe,
+ ExcludeByIdPipe,
MatCardModule,
MatSelectModule,
ReactiveFormsModule,
@@ -24,34 +25,33 @@ import { UserService } from '../../shared/services/user.service';
styleUrl: './impersonation.component.scss'
})
export class ImpersonationComponent implements OnInit {
- private readonly events = inject(EventService);
+ private readonly client = inject(HermesClientService);
private readonly userService = inject(UserService);
+ private readonly events = inject(EventService);
+ private readonly http = inject(HttpClient);
- impersonationControl = new FormControl(undefined);
- users: User[];
+ readonly auth = inject(ApiAuthenticationService);
- constructor(private client: HermesClientService, private auth: ApiAuthenticationService, private router: Router, private http: HttpClient, @Inject(PLATFORM_ID) private platformId: Object) {
- this.users = [];
- }
+ impersonationControl = new FormControl(this.auth.getUserId());
+ users$ = this.userService.fetch();
ngOnInit(): void {
- if (!isPlatformBrowser(this.platformId)) {
+ if (!this.auth.isAdmin()) {
return;
}
- this.userService.fetch().subscribe(users => {
- this.users = users.filter((d: any) => d.name != this.auth.getUsername());
+ this.users$.subscribe(users => {
const id = this.auth.getImpersonatedId();
- if (id && this.users.find(u => u.id == id)) {
+ if (id && users.find(u => u.id == id)) {
this.impersonationControl.setValue(id);
}
});
this.impersonationControl.valueChanges.subscribe((impersonationId) => {
- if (!this.auth.isAdmin() || impersonationId == this.auth.getImpersonatedId())
+ if (impersonationId == this.auth.getImpersonatedId())
return;
- if (!impersonationId) {
+ if (impersonationId == this.auth.getUserId()) {
this.http.delete(environment.API_HOST + '/admin/impersonate', {
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('jwt')
@@ -73,7 +73,6 @@ export class ImpersonationComponent implements OnInit {
}).subscribe(async (data: any) => {
this.client.disconnect(true);
this.events.emit('impersonation', impersonationId);
- await this.router.navigate(['tts-login']);
});
}
});
diff --git a/src/app/navigation/topbar/topbar.component.ts b/src/app/navigation/topbar/topbar.component.ts
index 6773f66..a7c1794 100644
--- a/src/app/navigation/topbar/topbar.component.ts
+++ b/src/app/navigation/topbar/topbar.component.ts
@@ -6,7 +6,6 @@ import { MatButtonModule } from '@angular/material/button';
import { AuthModule } from '../../auth/auth.module';
import { ApiAuthenticationService } from '../../shared/services/api/api-authentication.service';
import { ImpersonationComponent } from '../../auth/impersonation/impersonation.component';
-import { HermesClientService } from '../../hermes-client.service';
import EventService from '../../shared/services/EventService';
import { Subscription } from 'rxjs';
import { ThemeComponent } from "../../theme/theme.component";
@@ -32,14 +31,13 @@ import { LoginButtonComponent } from "../../auth/login-button/login-button.compo
})
export class Topbar implements OnDestroy {
private readonly auth = inject(ApiAuthenticationService);
- private readonly client = inject(HermesClientService);
private readonly events = inject(EventService);
private subscriptions: (Subscription | null)[] = [];
private _showImpersonation: boolean = false
constructor() {
- this.subscriptions.push(this.events.listen('impersonation', () => this.showImpersonation = false));
+ this.subscriptions.push(this.events.listen('impersonation', () => { this.auth.update(localStorage.getItem('jwt')); this.showImpersonation = false; }));
}
ngOnDestroy(): void {
diff --git a/src/app/redemptions/redemption-list/redemption-list.component.ts b/src/app/redemptions/redemption-list/redemption-list.component.ts
index b47ccff..5b354e9 100644
--- a/src/app/redemptions/redemption-list/redemption-list.component.ts
+++ b/src/app/redemptions/redemption-list/redemption-list.component.ts
@@ -44,7 +44,6 @@ export class RedemptionListComponent {
alias: 'twitchRedemptions',
transform: toTwitchRedemptionDict,
});
- //twitchRedemptions = computed<{ [id: string]: string } | null>(() => ({}));
actions = input.required();
diff --git a/src/app/shared/pipes/exclude-by-id.pipe.ts b/src/app/shared/pipes/exclude-by-id.pipe.ts
new file mode 100644
index 0000000..8b7e34d
--- /dev/null
+++ b/src/app/shared/pipes/exclude-by-id.pipe.ts
@@ -0,0 +1,13 @@
+import {Pipe, PipeTransform} from '@angular/core';
+
+@Pipe({
+ name: 'excludeById',
+})
+export class ExcludeByIdPipe implements PipeTransform {
+ transform(values: any[] | null, id: string): any[] | null {
+ if (!values) {
+ return values;
+ }
+ return values.filter(value => value.id != id);
+ }
+}
\ No newline at end of file
diff --git a/src/app/shared/services/api/api-authentication.service.ts b/src/app/shared/services/api/api-authentication.service.ts
index 214c45c..f0bbc53 100644
--- a/src/app/shared/services/api/api-authentication.service.ts
+++ b/src/app/shared/services/api/api-authentication.service.ts
@@ -36,6 +36,10 @@ export class ApiAuthenticationService {
return this.user?.impersonation?.name;
}
+ getUserId() {
+ return this.user?.id;
+ }
+
getUsername() {
return this.user?.name;
}
diff --git a/src/app/shared/services/permission.service.ts b/src/app/shared/services/permission.service.ts
index 36fd72d..a0ba83a 100644
--- a/src/app/shared/services/permission.service.ts
+++ b/src/app/shared/services/permission.service.ts
@@ -2,7 +2,7 @@ import { inject, Injectable } from '@angular/core';
import { HermesClientService } from '../../hermes-client.service';
import EventService from './EventService';
import { Permission } from '../models/permission';
-import { map, Observable, of } from 'rxjs';
+import { filter, map, merge, Observable, of, startWith } from 'rxjs';
@Injectable({
providedIn: 'root'
@@ -12,6 +12,7 @@ export class PermissionService {
private readonly events = inject(EventService);
private data: Permission[] = [];
private loaded = false;
+ changes$: Observable;
create$: Observable | undefined;
update$: Observable | undefined;
delete$: Observable | undefined;
@@ -20,6 +21,12 @@ export class PermissionService {
this.create$ = this.client.filterByRequestType('create_group_permission');
this.update$ = this.client.filterByRequestType('update_group_permission');
this.delete$ = this.client.filterByRequestType('delete_group_permission');
+ this.changes$ = merge(this.create$, this.update$, this.delete$)
+ .pipe(
+ startWith(null),
+ filter(d => !d.error),
+ map(_ => this.data.slice()),
+ );
this.create$?.subscribe(d => {
if (d.error) {
diff --git a/src/app/shared/services/redeemable-action.service.ts b/src/app/shared/services/redeemable-action.service.ts
index 49579d2..ce67b5f 100644
--- a/src/app/shared/services/redeemable-action.service.ts
+++ b/src/app/shared/services/redeemable-action.service.ts
@@ -25,7 +25,7 @@ export default class RedeemableActionService {
this.changes$ = merge(this.create$, this.update$, this.delete$)
.pipe(
startWith(null),
- map(d => this.data.slice()),
+ map(_ => this.data.slice()),
);
this.create$?.subscribe(d => this.data.push(d.data));
diff --git a/src/app/shared/services/redemption.service.ts b/src/app/shared/services/redemption.service.ts
index d941381..c2a7fa9 100644
--- a/src/app/shared/services/redemption.service.ts
+++ b/src/app/shared/services/redemption.service.ts
@@ -24,7 +24,7 @@ export default class RedemptionService {
this.changes$ = merge(this.create$, this.update$, this.delete$)
.pipe(
startWith(null),
- map(d => this.data.slice()),
+ map(_ => this.data.slice()),
);
this.create$?.subscribe(d => this.data.push(d.data));