Skip to content

Commit

Permalink
Merge 72400ff into 7435a56
Browse files Browse the repository at this point in the history
  • Loading branch information
zusorio authored Dec 16, 2024
2 parents 7435a56 + 72400ff commit f01bb9a
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 68 deletions.
136 changes: 75 additions & 61 deletions frontend/src/app/users/user-settings/user-settings.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,80 +11,94 @@ <h2 class="text-xl font-medium">Manage Users</h2>
<span class="text-sm">{{ users.length }} registered users</span>
}
</div>
<form [formGroup]="form">
<mat-form-field class="mb-[-10px] mt-[10px] w-full" appearance="outline">
<mat-label>Search</mat-label>
<input
formControlName="search"
matInput
placeholder="Username"
class="mr-2"
/>
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>

<mat-form-field class="mb-[-20px] mt-[10px] w-full" appearance="outline">
<mat-label>Search</mat-label>
<input
[(ngModel)]="search"
matInput
placeholder="Username"
class="mr-2"
/>
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
<div>
<mat-chip-listbox formControlName="userType">
<mat-chip-option value="regular">Regular User</mat-chip-option>
<mat-chip-option value="beta">
<div class="flex items-center gap-1">
<mat-icon inline>science</mat-icon><span>Beta Tester</span>
</div>
</mat-chip-option>
</mat-chip-listbox>
</div>
</form>

<div class="max-h-[50vh] overflow-y-scroll">
@for (role of userRoles; track role) {
<div class="mt-2.5 pl-1 text-lg font-bold text-gray-400">
{{ getUsersByRole(userWrapperService.users$ | async, role)?.length }}
{{ roleMapping[role] + "(s)" }}
</div>
@for (
user of getUsersByRole(userWrapperService.users$ | async, role);
track user.id
) {
<div class="mx-1.5 my-2.5 flex items-center justify-between">
<a [routerLink]="['/user', user.id]" class="flex">
<div class="ml-0 mr-4 flex items-center">
<mat-icon class="my-auto !h-8 !w-8 text-3xl" mat-list-icon
>account_circle</mat-icon
>
</div>
<div>
<div class="break-all text-[17.5px]">{{ user.name }}</div>
<div class="text-[14px] text-gray-500">
{{ roleMapping[user.role] }}
@let users = getUsersByRole(userWrapperService.users$ | async, role);
@if (users) {
<div class="mt-2.5 pl-1 text-lg font-bold text-gray-400">
{{ users.length }}
{{ roleMapping[role] }}{{ users.length !== 1 ? "s" : "" }}
</div>
@for (user of users; track user.id) {
<div class="mx-1.5 my-2.5 flex items-center justify-between gap-1">
<a [routerLink]="['/user', user.id]" class="flex gap-3">
<div class="flex items-center">
<mat-icon class="text-3xl" mat-list-icon
>account_circle</mat-icon
>
</div>
</div>
</a>
<div class="ml-1 mr-0 flex items-center">
@if (user.role === "administrator") {
@if (user.id !== ownUserService.user?.id) {
<div>
<div class="break-all text-[17.5px]">{{ user.name }}</div>
<div class="text-[14px] text-gray-500">
{{ roleMapping[user.role]
}}{{ user.beta_tester ? ", Beta Tester" : "" }}
</div>
</div>
</a>
<div class="flex items-center">
@if (user.role === "administrator") {
@if (user.id !== ownUserService.user?.id) {
<button
mat-icon-button
color="primary"
(click)="downgradeToUser(user)"
matTooltip="Downgrade user to normal user"
class="!mx-0 !px-0 text-sm"
>
<mat-icon>arrow_downward</mat-icon>
</button>
}
} @else {
<button
class="mx-0 px-0"
mat-icon-button
color="primary"
(click)="downgradeToUser(user)"
matTooltip="Downgrade user to normal user"
class="!mx-0 !px-0 text-sm"
(click)="upgradeToAdministrator(user)"
matTooltip="Upgrade user to administrator"
>
<mat-icon>arrow_downward</mat-icon>
<mat-icon>arrow_upward</mat-icon>
</button>
}
} @else {
<button
class="mx-0 px-0"
mat-icon-button
color="primary"
(click)="upgradeToAdministrator(user)"
matTooltip="Upgrade user to administrator"
>
<mat-icon>arrow_upward</mat-icon>
</button>
}
@if (user.id !== ownUserService.user?.id) {
<button
class="mx-0 px-0"
mat-icon-button
color="warn"
(click)="deleteUser(user)"
matTooltip="Permanently delete user"
>
<mat-icon color="warn">delete</mat-icon>
</button>
}
@if (user.id !== ownUserService.user?.id) {
<button
class="mx-0 px-0"
mat-icon-button
color="warn"
(click)="deleteUser(user)"
matTooltip="Permanently delete user"
>
<mat-icon color="warn">delete</mat-icon>
</button>
}
</div>
</div>
</div>
}
}

@if ((userWrapperService.users$ | async) === undefined) {
<ngx-skeleton-loader
appearance="circle"
Expand Down
25 changes: 18 additions & 7 deletions frontend/src/app/users/user-settings/user-settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
AsyncValidatorFn,
} from '@angular/forms';
import { MatIconButton, MatButton } from '@angular/material/button';
import { MatChipListbox, MatChipOption } from '@angular/material/chips';
import { MatDialog } from '@angular/material/dialog';
import {
MatFormField,
Expand Down Expand Up @@ -59,11 +60,11 @@ import { UserWrapperService } from 'src/app/users/user-wrapper/user-wrapper.serv
MatButton,
AsyncPipe,
NgxSkeletonLoaderModule,
MatChipListbox,
MatChipOption,
],
})
export class UserSettingsComponent implements OnInit {
search = '';

public readonly roleMapping = {
user: 'Global User',
administrator: 'Global Administrator',
Expand All @@ -80,6 +81,11 @@ export class UserSettingsComponent implements OnInit {
}),
});

form = new FormGroup({
search: new FormControl<string>(''),
userType: new FormControl<string | null>(null),
});

constructor(
public ownUserService: OwnUserWrapperService,
public userWrapperService: UserWrapperService,
Expand Down Expand Up @@ -252,10 +258,15 @@ export class UserSettingsComponent implements OnInit {
users: User[] | null | undefined,
role: UserRole,
): User[] | undefined {
return users?.filter(
(user) =>
user.role == role &&
user.name.toLowerCase().includes(this.search.toLowerCase()),
);
return users?.filter((user) => {
const roleMatches = user.role == role;
const searchMatches = user.name
.toLowerCase()
.includes(this.form.value.search?.toLowerCase() || '');
const userTypeMatches =
this.form.value.userType == null ||
user.beta_tester == (this.form.value.userType == 'beta');
return roleMatches && searchMatches && userTypeMatches;
});
}
}
6 changes: 6 additions & 0 deletions frontend/src/app/users/user-settings/user-settings.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,19 @@ export const Overview: Story = {
...mockUser,
role: 'administrator',
name: 'globalAdministrator2',
beta_tester: true,
},
loggedInUser,
mockUser,
{
...mockUser,
name: 'userWithReallyLongNameThatHasToBeWrapped',
},
{
...mockUser,
name: 'userThatsAlsoABetaTester',
beta_tester: true,
},
]),
mockOwnUserWrapperServiceProvider(loggedInUser),
],
Expand Down

0 comments on commit f01bb9a

Please sign in to comment.