Added user management for groups. Improved user experience slightly. Added some error checks for request acks.

This commit is contained in:
Tom
2025-03-20 12:33:27 +00:00
parent 2f2215b041
commit 1acda7978e
40 changed files with 623 additions and 52 deletions

View File

@ -38,7 +38,7 @@
}
</mat-form-field>
</mat-card-content>
<mat-card-actions>
<mat-card-actions align="end">
<button mat-button
[disabled]="waitForResponse || formGroup.invalid"
(click)="add()">

View File

@ -55,7 +55,13 @@ export class GroupItemEditComponent implements OnInit {
this.waitForResponse = true;
this._client.first((d: any) => d.op == 4 && d.d.request.type == 'create_group' && d.d.data.name == this.nameForm.value)
.subscribe({
next: (d) => this._dialogRef.close(d.d.data),
next: (d) => {
if (d.d.error) {
// TODO: update & show response error message.
} else {
this._dialogRef.close(d.d.data);
}
},
error: () => this.waitForResponse = false,
complete: () => this.waitForResponse = false,
});

View File

@ -4,10 +4,17 @@
<small class="tag">auto-generated</small>
}
</section>
<section class="">{{item().group.priority}}</section>
<section class="">
{{item().group.priority}}
<small class="muted block">priority</small>
</section>
<section>
@if (special) {
<p class="muted">Unknown</p>
} @else {
{{item().chatters.length}}
<small class="muted block">user{{item().chatters.length == 1 ? '' : 's'}}</small>
}
</section>
<section>
{{item().policies.length}}

View File

@ -1,13 +1,12 @@
import { Component, inject, input, Input, OnInit } from '@angular/core';
import { Component, inject, input, OnInit } from '@angular/core';
import { Group } from '../../shared/models/group';
import { MatCardModule } from '@angular/material/card';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { Policy } from '../../shared/models/policy';
import { GroupItemEditComponent } from '../group-item-edit/group-item-edit.component';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { GroupChatter } from '../../shared/models/group-chatter';
import { SpecialGroups } from '../../shared/utils/groups';
@Component({
selector: 'group-item',
@ -24,12 +23,10 @@ export class GroupItemComponent implements OnInit {
readonly router = inject(Router);
item = input.required<{ group: Group, chatters: GroupChatter[], policies: Policy[] }>();
link: string = '';
special: boolean = true;
ngOnInit() {
this.special = ['everyone', 'subscribers', 'moderators', 'vip', 'broadcaster'].includes(this.item().group.name);
this.special = SpecialGroups.includes(this.item().group.name);
this.link = 'groups/' + this.item().group.id;
}
}

View File

@ -1,6 +1,19 @@
<div>
<h2>{{group?.name}}</h2>
@if (!isSpecialGroup) {
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>Users</mat-panel-title>
<mat-panel-description class="muted">
{{chatters.length}} user{{chatters.length == 1 ? '' : 's'}}
</mat-panel-description>
</mat-expansion-panel-header>
<twitch-user-list [twitchUsers]="chatters"
[group]="group" />
</mat-expansion-panel>
}
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>Policies</mat-panel-title>
@ -12,9 +25,7 @@
[groups]="groups"
[policies]="policies"
[group]="group?.id" />
@if (policies.length > 0) {
<policy-table [policies]="policies" />
}
</mat-expansion-panel>
<mat-expansion-panel>

View File

@ -1,4 +1,4 @@
import { Component, inject } from '@angular/core';
import { Component, inject, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Group } from '../../shared/models/group';
import { Policy } from '../../shared/models/policy';
@ -13,9 +13,10 @@ import { PolicyTableComponent } from "../../policies/policy-table/policy-table.c
import { PolicyAddButtonComponent } from '../../policies/policy-add-button/policy-add-button.component';
import { HermesClientService } from '../../hermes-client.service';
import { GroupChatter } from '../../shared/models/group-chatter';
import { TwitchUsersModule } from "../../twitch-users/twitch-users.module";
import { SpecialGroups } from '../../shared/utils/groups';
@Component({
selector: 'group-page',
imports: [
MatButtonModule,
MatExpansionModule,
@ -25,7 +26,9 @@ import { GroupChatter } from '../../shared/models/group-chatter';
PoliciesModule,
PolicyAddButtonComponent,
ReactiveFormsModule,
PolicyTableComponent
PolicyTableComponent,
PolicyTableComponent,
TwitchUsersModule,
],
templateUrl: './group-page.component.html',
styleUrl: './group-page.component.scss'
@ -38,6 +41,7 @@ export class GroupPageComponent {
private _chatters: GroupChatter[];
private _policies: Policy[];
isSpecialGroup = false;
groups: Group[] = [];
constructor() {
@ -57,6 +61,7 @@ export class GroupPageComponent {
}
this._group = group;
this.isSpecialGroup = SpecialGroups.includes(this.group!.name);
this._chatters = [...data['chatters'].filter((c: GroupChatter) => c.group_id == group_id)];
this._policies = [...data['policies'].filter((p: Policy) => p.group_id == group_id)];
});
@ -79,7 +84,7 @@ export class GroupPageComponent {
if (!this.group)
return;
this._client.first(d => d.d.request.type == 'delete_group' && d.d.request.data.id == this.group!.id)
this._client.first(d => d.d.request.type == 'delete_group' && d.d.request.data.group == this.group!.id)
.subscribe(async () => await this._router.navigate(['groups']));
this._client.deleteGroup(this.group.id);
}

View File

@ -6,16 +6,12 @@
<mat-menu #menu="matMenu">
<button mat-menu-item
(click)="openDialog('')">Custom Group</button>
@for (group of specialGroups; track $index) {
@if (!exists(group)) {
<button mat-menu-item
(click)="openDialog('everyone')">Everyone Group</button>
<button mat-menu-item
(click)="openDialog('subscribers')">Subscriber Group</button>
<button mat-menu-item
(click)="openDialog('moderators')">Moderator Group</button>
<button mat-menu-item
(click)="openDialog('vip')">VIP Group</button>
<button mat-menu-item
(click)="openDialog('broadcaster')">Broadcaster Group</button>
(click)="openDialog(group)">{{group[0].toUpperCase() + group.substring(1)}} Group</button>
}
}
</mat-menu>
<group-list class="groups"
[groups]="items" />

View File

@ -12,6 +12,7 @@ import { GroupItemEditComponent } from '../group-item-edit/group-item-edit.compo
import { MatMenuModule } from '@angular/material/menu';
import { HermesClientService } from '../../hermes-client.service';
import { GroupChatter } from '../../shared/models/group-chatter';
import { SpecialGroups } from '../../shared/utils/groups';
@Component({
selector: 'groups',
@ -31,6 +32,8 @@ export class GroupsComponent {
private readonly _client = inject(HermesClientService);
private readonly _route = inject(ActivatedRoute);
private readonly _dialog = inject(MatDialog);
readonly specialGroups = SpecialGroups;
items: { group: Group, chatters: GroupChatter[], policies: Policy[] }[] = [];
@ -116,4 +119,8 @@ export class GroupsComponent {
compare(a: Group, b: Group) {
return a.name.localeCompare(b.name);
}
exists(groupName: string) {
return this.items.some(g => g.group.name == groupName);
}
}