Skip to content

Commit

Permalink
Allow adding existing users to registrar (#2616)
Browse files Browse the repository at this point in the history
  • Loading branch information
ptkach authored Nov 27, 2024
1 parent 21950f7 commit fa37773
Show file tree
Hide file tree
Showing 14 changed files with 417 additions and 107 deletions.
4 changes: 2 additions & 2 deletions console-webapp/src/app/shared/services/backend.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,9 @@ export class BackendService {
.pipe(catchError((err) => this.errorCatcher<User[]>(err)));
}

createUser(registrarId: string): Observable<User> {
createUser(registrarId: string, maybeUser: User | null): Observable<User> {
return this.http
.post<User>(`/console-api/users?registrarId=${registrarId}`, {})
.post<User>(`/console-api/users?registrarId=${registrarId}`, maybeUser)
.pipe(catchError((err) => this.errorCatcher<User>(err)));
}

Expand Down
1 change: 1 addition & 0 deletions console-webapp/src/app/shared/services/userData.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface UserData {
supportEmail: string;
supportPhoneNumber: string;
technicalDocsUrl: string;
userRoles?: Map<string, string>;
}

@Injectable({
Expand Down
2 changes: 1 addition & 1 deletion console-webapp/src/app/users/userEdit.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { SelectedRegistrarModule } from '../app.module';
import { MaterialModule } from '../material.module';
import { RegistrarService } from '../registrar/registrar.service';
import { SnackBarModule } from '../snackbar.module';
import { User, UsersService, roleToDescription } from './users.service';
import { UsersService, roleToDescription } from './users.service';
import { FormsModule } from '@angular/forms';

@Component({
Expand Down
112 changes: 80 additions & 32 deletions console-webapp/src/app/users/users.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,94 @@
<div class="console-app__users-spinner">
<mat-spinner />
</div>
} @else if(selectingExistingUser) {

<div class="console-app__users">
<h1 class="mat-headline-4">Add existing user</h1>

<p>
<button
mat-icon-button
aria-label="Back to users list"
(click)="selectingExistingUser = false"
>
<mat-icon>arrow_back</mat-icon>
</button>
</p>
<h1>Select registrar from which to add a new user</h1>
<p>
<mat-form-field appearance="outline">
<mat-label>Registrar</mat-label>
<mat-select
[(ngModel)]="selectedRegistrarId"
name="selectedRegistrarId"
(selectionChange)="onRegistrarSelectionChange($event)"
>
@for (registrar of registrarService.registrars(); track registrar) {
<mat-option [value]="registrar.registrarId">{{
registrar.registrarId
}}</mat-option>
}
</mat-select>
</mat-form-field>
</p>
@if(usersSelection.length) {
<app-users-list
[users]="usersSelection"
(onSelect)="existingUserSelected($event)"
/>
<p class="console-app__users-add-existing">
<button
mat-flat-button
color="primary"
aria-label="Add user"
(click)="submitExistingUser()"
[disabled]="!selectedExistingUser"
>
Add user
</button>
<button
mat-stroked-button
aria-label="Cancel adding existing user"
(click)="selectingExistingUser = false"
>
Cancel
</button>
</p>
}
</div>
} @else if(usersService.currentlyOpenUserEmail()) {
<app-user-edit></app-user-edit>
} @else {
<div class="console-app__users">
<div class="console-app__users-header">
<h1 class="mat-headline-4">Users</h1>
<div class="spacer"></div>
<button
mat-flat-button
(click)="createNewUser()"
aria-label="Create new user"
color="primary"
>
Create a Viewer User
</button>
<div class="console-app__users-header-buttons">
<button
class="console-app__users-header-add"
mat-stroked-button
(click)="addExistingUser()"
aria-label="Create new user"
color="primary"
>
<mat-icon>add</mat-icon>
Add existing user
</button>
<button
mat-flat-button
(click)="createNewUser()"
aria-label="Create new user"
color="primary"
>
Create a Viewer User
</button>
</div>
</div>
<mat-table
[dataSource]="dataSource"
class="mat-elevation-z0"
class="console-app__users-table"
matSort
>
<ng-container
*ngFor="let column of columns"
[matColumnDef]="column.columnDef"
>
<mat-header-cell *matHeaderCellDef>
{{ column.header }}
</mat-header-cell>
<mat-cell
*matCellDef="let row"
[innerHTML]="column.cell(row)"
></mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row
*matRowDef="let row; columns: displayedColumns"
(click)="openDetails(row.emailAddress)"
></mat-row>
</mat-table>
<app-users-list
[users]="usersService.users()"
(onSelect)="openDetails($event)"
/>
</div>
}
</app-selected-registrar-wrapper>
27 changes: 19 additions & 8 deletions console-webapp/src/app/users/users.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,37 @@
// limitations under the License.

.console-app {
&__users {
max-width: 1024px;
overflow-x: auto;
}

&__users-spinner {
align-items: center;
display: flex;
justify-content: center;
}

$min-width: 756px;
$max-width: 1024px;

&__users-table {
min-width: $min-width !important;
max-width: $max-width;
}

&__users-new {
margin-left: 20px;
}

&__users-add-existing {
margin-top: 20px;
> button {
margin-right: 15px;
}
}
&__users-header {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
&-buttons {
display: flex;
flex-wrap: wrap;
button {
margin: 0 15px 15px 0;
}
}
}
}
89 changes: 57 additions & 32 deletions console-webapp/src/app/users/users.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,71 +14,64 @@

import { CommonModule } from '@angular/common';
import { HttpErrorResponse } from '@angular/common/http';
import { Component, effect, ViewChild } from '@angular/core';
import { Component, effect } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { SelectedRegistrarModule } from '../app.module';
import { MaterialModule } from '../material.module';
import { RegistrarService } from '../registrar/registrar.service';
import { SnackBarModule } from '../snackbar.module';
import { UserEditComponent } from './userEdit.component';
import { roleToDescription, User, UsersService } from './users.service';

export const columns = [
{
columnDef: 'emailAddress',
header: 'User email',
cell: (record: User) => `${record.emailAddress || ''}`,
},
{
columnDef: 'role',
header: 'User role',
cell: (record: User) => `${roleToDescription(record.role)}`,
},
];
import { User, UsersService } from './users.service';
import { UserDataService } from '../shared/services/userData.service';
import { FormsModule } from '@angular/forms';
import { UsersListComponent } from './usersList.component';
import { MatSelectChange } from '@angular/material/select';

@Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.scss'],
standalone: true,
imports: [
FormsModule,
MaterialModule,
SnackBarModule,
CommonModule,
SelectedRegistrarModule,
UsersListComponent,
UserEditComponent,
],
providers: [UsersService],
})
export class UsersComponent {
dataSource: MatTableDataSource<User>;
columns = columns;
displayedColumns = this.columns.map((c) => c.columnDef);
isLoading = false;

@ViewChild(MatSort) sort!: MatSort;
selectingExistingUser = false;
selectedRegistrarId = '';
usersSelection: User[] = [];
selectedExistingUser: User | undefined;

constructor(
protected registrarService: RegistrarService,
protected usersService: UsersService,
private userDataService: UserDataService,
private _snackBar: MatSnackBar
) {
this.dataSource = new MatTableDataSource<User>(usersService.users());

effect(() => {
if (registrarService.registrarId()) {
this.loadUsers();
}
});
effect(() => {
this.dataSource.data = usersService.users();
});
}

ngAfterViewInit() {
this.dataSource.sort = this.sort;
addExistingUser() {
this.selectingExistingUser = true;
this.selectedRegistrarId = '';
this.usersSelection = [];
this.selectedExistingUser = undefined;
}

existingUserSelected(user: User) {
this.selectedExistingUser = user;
}

loadUsers() {
Expand All @@ -96,7 +89,7 @@ export class UsersComponent {

createNewUser() {
this.isLoading = true;
this.usersService.createNewUser().subscribe({
this.usersService.createOrAddNewUser(null).subscribe({
error: (err: HttpErrorResponse) => {
this._snackBar.open(err.error || err.message);
this.isLoading = false;
Expand All @@ -107,7 +100,39 @@ export class UsersComponent {
});
}

openDetails(emailAddress: string) {
this.usersService.currentlyOpenUserEmail.set(emailAddress);
openDetails(user: User) {
this.usersService.currentlyOpenUserEmail.set(user.emailAddress);
}

onRegistrarSelectionChange(e: MatSelectChange) {
if (e.value) {
this.usersService.fetchUsersForRegistrar(e.value).subscribe({
error: (err) => {
this._snackBar.open(err.error || err.message);
},
next: (users) => {
this.usersSelection = users;
},
});
}
}

submitExistingUser() {
this.isLoading = true;
if (this.selectedExistingUser) {
this.usersService
.createOrAddNewUser(this.selectedExistingUser)
.subscribe({
error: (err) => {
this._snackBar.open(err.error || err.message);
this.isLoading = false;
},
complete: () => {
this.isLoading = false;
this.selectingExistingUser = false;
this.loadUsers();
},
});
}
}
}
16 changes: 11 additions & 5 deletions console-webapp/src/app/users/users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export class UsersService {
private registrarService: RegistrarService
) {}

fetchUsersForRegistrar(registrarId: string) {
return this.backendService.getUsers(registrarId);
}

fetchUsers() {
return this.backendService
.getUsers(this.registrarService.registrarId())
Expand All @@ -56,14 +60,16 @@ export class UsersService {
);
}

createNewUser() {
createOrAddNewUser(maybeExistingUser: User | null) {
return this.backendService
.createUser(this.registrarService.registrarId())
.createUser(this.registrarService.registrarId(), maybeExistingUser)
.pipe(
tap((newUser: User) => {
this.users.set([...this.users(), newUser]);
this.currentlyOpenUserEmail.set(newUser.emailAddress);
this.isNewUser = true;
if (newUser) {
this.users.set([...this.users(), newUser]);
this.currentlyOpenUserEmail.set(newUser.emailAddress);
this.isNewUser = true;
}
})
);
}
Expand Down
Loading

0 comments on commit fa37773

Please sign in to comment.