Skip to content

Commit

Permalink
Add user email prefix to the console user create (#2623)
Browse files Browse the repository at this point in the history
  • Loading branch information
ptkach authored Dec 13, 2024
1 parent e5ebc5a commit f649d96
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 130 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,10 @@ <h1 class="mat-headline-4">Editing {{ userDetails().emailAddress }}</h1>
<mat-icon>arrow_back</mat-icon>
</button>
</div>
<form (ngSubmit)="saveEdit()">
<p>
<mat-form-field appearance="outline">
<mat-label
>User Role:
<mat-icon
matTooltip="Viewer role doesn't allow making updates; Editor role allows updates, like Contacts delete or SSL certificate change"
>help_outline</mat-icon
></mat-label
>
<mat-select [(ngModel)]="userRole" name="userRole">
<mat-option value="PRIMARY_CONTACT">Editor</mat-option>
<mat-option value="ACCOUNT_MANAGER">Viewer</mat-option>
</mat-select>
</mat-form-field>
</p>
<button
mat-flat-button
color="primary"
aria-label="Save user"
type="submit"
>
Save
</button>
</form>
<app-user-edit-form
[user]="userDetails()"
(onEditComplete)="saveEdit($event)"
/>
} @else { @if(isNewUser) {
<h1 class="mat-headline-4">
{{ userDetails().emailAddress + " successfully created" }}
Expand All @@ -53,7 +32,7 @@ <h1 class="mat-headline-4">User details</h1>
mat-flat-button
color="primary"
aria-label="Edit User"
(click)="userRole = userDetails().role; isEditing = true"
(click)="isEditing = true"
>
<mat-icon>edit</mat-icon>
Edit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,30 @@ import { SelectedRegistrarModule } from '../app.module';
import { MaterialModule } from '../material.module';
import { RegistrarService } from '../registrar/registrar.service';
import { SnackBarModule } from '../snackbar.module';
import { UsersService, roleToDescription } from './users.service';
import { UsersService, roleToDescription, User } from './users.service';
import { FormsModule } from '@angular/forms';
import { UserEditFormComponent } from './userEditForm.component';

@Component({
selector: 'app-user-edit',
templateUrl: './userEdit.component.html',
styleUrls: ['./userEdit.component.scss'],
templateUrl: './userDetails.component.html',
styleUrls: ['./userDetails.component.scss'],
standalone: true,
imports: [
FormsModule,
MaterialModule,
SnackBarModule,
CommonModule,
SelectedRegistrarModule,
UserEditFormComponent,
],
providers: [],
})
export class UserEditComponent {
export class UserDetailsComponent {
isEditing = false;
isPasswordVisible = false;
isNewUser = false;
isLoading = false;
userRole = '';

userDetails = computed(() => {
return this.usersService
Expand Down Expand Up @@ -84,22 +85,17 @@ export class UserEditComponent {
this.usersService.currentlyOpenUserEmail.set('');
}

saveEdit() {
saveEdit(user: User) {
this.isLoading = true;
this.usersService
.updateUser({
role: this.userRole,
emailAddress: this.userDetails().emailAddress,
})
.subscribe({
error: (err) => {
this._snackBar.open(err.error || err.message);
this.isLoading = false;
},
complete: () => {
this.isLoading = false;
this.isEditing = false;
},
});
this.usersService.updateUser(user).subscribe({
error: (err) => {
this._snackBar.open(err.error || err.message);
this.isLoading = false;
},
complete: () => {
this.isLoading = false;
this.isEditing = false;
},
});
}
}
39 changes: 39 additions & 0 deletions console-webapp/src/app/users/userEditForm.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<form (ngSubmit)="saveEdit($event)" #form>
<p *ngIf="isNew()">
<mat-form-field appearance="outline">
<mat-label
>User name prefix:
<mat-icon
matTooltip="Prefix will be combined with registrar ID to create a unique user name - {prefix}.{registrarId}@registry.google"
>help_outline</mat-icon
></mat-label
>
<input
matInput
minlength="3"
maxlength="3"
[required]="true"
[(ngModel)]="user().emailAddress"
[ngModelOptions]="{ standalone: true }"
/>
</mat-form-field>
</p>
<p>
<mat-form-field appearance="outline">
<mat-label
>User Role:
<mat-icon
matTooltip="Viewer role doesn't allow making updates; Editor role allows updates, like Contacts delete or SSL certificate change"
>help_outline</mat-icon
></mat-label
>
<mat-select [(ngModel)]="user().role" name="userRole">
<mat-option value="PRIMARY_CONTACT">Editor</mat-option>
<mat-option value="ACCOUNT_MANAGER">Viewer</mat-option>
</mat-select>
</mat-form-field>
</p>
<button mat-flat-button color="primary" aria-label="Save user" type="submit">
Save
</button>
</form>
Empty file.
58 changes: 58 additions & 0 deletions console-webapp/src/app/users/userEditForm.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2024 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { CommonModule } from '@angular/common';
import {
Component,
ElementRef,
EventEmitter,
input,
Output,
ViewChild,
} from '@angular/core';
import { MaterialModule } from '../material.module';
import { FormsModule } from '@angular/forms';
import { User } from './users.service';

@Component({
selector: 'app-user-edit-form',
templateUrl: './userEditForm.component.html',
styleUrls: ['./userEditForm.component.scss'],
standalone: true,
imports: [FormsModule, MaterialModule, CommonModule],
providers: [],
})
export class UserEditFormComponent {
@ViewChild('form') form!: ElementRef;
isNew = input<boolean>(false);
user = input<User>(
{
emailAddress: '',
role: 'ACCOUNT_MANAGER',
},
// @ts-ignore - legit option, typescript fails to match it to a proper type
{ transform: (user: User) => structuredClone(user) }
);

@Output() onEditComplete = new EventEmitter<User>();

saveEdit(e: SubmitEvent) {
e.preventDefault();
if (this.form.nativeElement.checkValidity()) {
this.onEditComplete.emit(this.user());
} else {
this.form.nativeElement.reportValidity();
}
}
}
19 changes: 15 additions & 4 deletions console-webapp/src/app/users/users.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
<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
Expand Down Expand Up @@ -61,6 +59,19 @@ <h1>Select registrar from which to add a new user</h1>
</div>
} @else if(usersService.currentlyOpenUserEmail()) {
<app-user-edit></app-user-edit>
} @else if(isNew) {
<h1 class="mat-headline-4">New User Form</h1>
<div class="spacer"></div>
<p>
<button
mat-icon-button
aria-label="Back to users list"
(click)="isNew = false"
>
<mat-icon>arrow_back</mat-icon>
</button>
</p>
<app-user-edit-form [isNew]="true" (onEditComplete)="createNewUser($event)" />
} @else {
<div class="console-app__users">
<div class="console-app__users-header">
Expand All @@ -79,11 +90,11 @@ <h1 class="mat-headline-4">Users</h1>
</button>
<button
mat-flat-button
(click)="createNewUser()"
(click)="isNew = true"
aria-label="Create new user"
color="primary"
>
Create a Viewer User
Create New User
</button>
</div>
</div>
Expand Down
11 changes: 7 additions & 4 deletions console-webapp/src/app/users/users.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ 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 { UserDetailsComponent } from './userDetails.component';
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';
import { UserEditFormComponent } from './userEditForm.component';

@Component({
selector: 'app-users',
Expand All @@ -39,12 +40,14 @@ import { MatSelectChange } from '@angular/material/select';
CommonModule,
SelectedRegistrarModule,
UsersListComponent,
UserEditComponent,
UserEditFormComponent,
UserDetailsComponent,
],
providers: [UsersService],
})
export class UsersComponent {
isLoading = false;
isNew = false;
selectingExistingUser = false;
selectedRegistrarId = '';
usersSelection: User[] = [];
Expand Down Expand Up @@ -87,9 +90,9 @@ export class UsersComponent {
});
}

createNewUser() {
createNewUser(user: User) {
this.isLoading = true;
this.usersService.createOrAddNewUser(null).subscribe({
this.usersService.createOrAddNewUser(user).subscribe({
error: (err: HttpErrorResponse) => {
this._snackBar.open(err.error || err.message);
this.isLoading = false;
Expand Down
4 changes: 2 additions & 2 deletions console-webapp/src/app/users/users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ export class UsersService {
);
}

createOrAddNewUser(maybeExistingUser: User | null) {
createOrAddNewUser(user: User) {
return this.backendService
.createUser(this.registrarService.registrarId(), maybeExistingUser)
.createUser(this.registrarService.registrarId(), user)
.pipe(
tap((newUser: User) => {
if (newUser) {
Expand Down
Loading

0 comments on commit f649d96

Please sign in to comment.