mirror of
https://github.com/google/nomulus.git
synced 2025-07-24 19:48:32 +02:00
Add resources widget front-end (#2151)
This commit is contained in:
parent
759143535f
commit
dded258864
18 changed files with 151 additions and 29 deletions
|
@ -24,6 +24,10 @@ import SettingsSecurityComponent from './settings/security/security.component';
|
||||||
import { RegistrarGuard } from './registrar/registrar.guard';
|
import { RegistrarGuard } from './registrar/registrar.guard';
|
||||||
import { RegistrarComponent } from './registrar/registrarsTable.component';
|
import { RegistrarComponent } from './registrar/registrarsTable.component';
|
||||||
import { EmptyRegistrar } from './registrar/emptyRegistrar.component';
|
import { EmptyRegistrar } from './registrar/emptyRegistrar.component';
|
||||||
|
import ContactComponent from './settings/contact/contact.component';
|
||||||
|
import WhoisComponent from './settings/whois/whois.component';
|
||||||
|
import SecurityComponent from './settings/security/security.component';
|
||||||
|
import UsersComponent from './settings/users/users.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: '', redirectTo: '/home', pathMatch: 'full' },
|
{ path: '', redirectTo: '/home', pathMatch: 'full' },
|
||||||
|
@ -32,7 +36,7 @@ const routes: Routes = [
|
||||||
{ path: 'home', component: HomeComponent, canActivate: [RegistrarGuard] },
|
{ path: 'home', component: HomeComponent, canActivate: [RegistrarGuard] },
|
||||||
{ path: 'tlds', component: TldsComponent, canActivate: [RegistrarGuard] },
|
{ path: 'tlds', component: TldsComponent, canActivate: [RegistrarGuard] },
|
||||||
{
|
{
|
||||||
path: 'settings',
|
path: SettingsComponent.PATH,
|
||||||
component: SettingsComponent,
|
component: SettingsComponent,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -41,32 +45,27 @@ const routes: Routes = [
|
||||||
pathMatch: 'full',
|
pathMatch: 'full',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'contact',
|
path: ContactComponent.PATH,
|
||||||
component: SettingsContactComponent,
|
component: SettingsContactComponent,
|
||||||
canActivate: [RegistrarGuard],
|
canActivate: [RegistrarGuard],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'whois',
|
path: WhoisComponent.PATH,
|
||||||
component: SettingsWhoisComponent,
|
component: SettingsWhoisComponent,
|
||||||
canActivate: [RegistrarGuard],
|
canActivate: [RegistrarGuard],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'security',
|
path: SecurityComponent.PATH,
|
||||||
component: SettingsSecurityComponent,
|
component: SettingsSecurityComponent,
|
||||||
canActivate: [RegistrarGuard],
|
canActivate: [RegistrarGuard],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'epp-password',
|
path: UsersComponent.PATH,
|
||||||
component: SettingsSecurityComponent,
|
|
||||||
canActivate: [RegistrarGuard],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'users',
|
|
||||||
component: SettingsUsersComponent,
|
component: SettingsUsersComponent,
|
||||||
canActivate: [RegistrarGuard],
|
canActivate: [RegistrarGuard],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'registrars',
|
path: RegistrarComponent.PATH,
|
||||||
component: RegistrarComponent,
|
component: RegistrarComponent,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { RegistrarService } from './registrar/registrar.service';
|
import { RegistrarService } from './registrar/registrar.service';
|
||||||
|
import { UserDataService } from './shared/services/userData.service';
|
||||||
import { GlobalLoaderService } from './shared/services/globalLoader.service';
|
import { GlobalLoaderService } from './shared/services/globalLoader.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -25,6 +26,7 @@ export class AppComponent {
|
||||||
renderRouter: boolean = true;
|
renderRouter: boolean = true;
|
||||||
constructor(
|
constructor(
|
||||||
protected registrarService: RegistrarService,
|
protected registrarService: RegistrarService,
|
||||||
|
protected userDataService: UserDataService,
|
||||||
protected globalLoader: GlobalLoaderService
|
protected globalLoader: GlobalLoaderService
|
||||||
) {
|
) {
|
||||||
registrarService.activeRegistrarIdChange.subscribe(() => {
|
registrarService.activeRegistrarIdChange.subscribe(() => {
|
||||||
|
|
|
@ -46,6 +46,7 @@ import { EppWidgetComponent } from './home/widgets/epp-widget.component';
|
||||||
import { BillingWidgetComponent } from './home/widgets/billing-widget.component';
|
import { BillingWidgetComponent } from './home/widgets/billing-widget.component';
|
||||||
import { DomainsWidgetComponent } from './home/widgets/domains-widget.component';
|
import { DomainsWidgetComponent } from './home/widgets/domains-widget.component';
|
||||||
import { SettingsWidgetComponent } from './home/widgets/settings-widget.component';
|
import { SettingsWidgetComponent } from './home/widgets/settings-widget.component';
|
||||||
|
import { UserDataService } from './shared/services/userData.service';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
|
@ -81,6 +82,7 @@ import { SettingsWidgetComponent } from './home/widgets/settings-widget.componen
|
||||||
BackendService,
|
BackendService,
|
||||||
GlobalLoaderService,
|
GlobalLoaderService,
|
||||||
RegistrarGuard,
|
RegistrarGuard,
|
||||||
|
UserDataService,
|
||||||
{
|
{
|
||||||
provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,
|
provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,
|
||||||
useValue: {
|
useValue: {
|
||||||
|
|
|
@ -13,13 +13,13 @@
|
||||||
Give us a Call
|
Give us a Call
|
||||||
</button>
|
</button>
|
||||||
<p class="secondary-text">
|
<p class="secondary-text">
|
||||||
Call Google Registry support at +1 (404) 978 8419
|
Call Google Registry support at <b>+1 (404) 978 8419</b>
|
||||||
</p>
|
</p>
|
||||||
<button mat-button color="primary" class="console-app__widget-link">
|
<button mat-button color="primary" class="console-app__widget-link">
|
||||||
Send us an Email
|
Send us an Email
|
||||||
</button>
|
</button>
|
||||||
<p class="secondary-text">
|
<p class="secondary-text">
|
||||||
Email Google Registry at support@google.com
|
Email Google Registry at <b>support@google.com</b>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
<mat-card>
|
<mat-card>
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<div class="console-app__widget">
|
<div class="console-app__widget">
|
||||||
<div class="console-app__widget_left">
|
<a
|
||||||
|
class="console-app__widget_left"
|
||||||
|
href="{{ userDataService.userData?.technicalDocsUrl }}"
|
||||||
|
>
|
||||||
<mat-icon class="console-app__widget-icon">menu_book</mat-icon>
|
<mat-icon class="console-app__widget-icon">menu_book</mat-icon>
|
||||||
<h1 class="console-app__widget-title">Resources</h1>
|
<h1 class="console-app__widget-title">Resources</h1>
|
||||||
<h4 class="secondary-text text-center">
|
<h4 class="secondary-text text-center">
|
||||||
Use Google Drive to view onboarding FAQs, and technical documentation.
|
Use Google Drive to view onboarding FAQs, and technical documentation.
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
|
|
@ -13,11 +13,12 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
import { UserDataService } from 'src/app/shared/services/userData.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-resources-widget]',
|
selector: '[app-resources-widget]',
|
||||||
templateUrl: './resources-widget.component.html',
|
templateUrl: './resources-widget.component.html',
|
||||||
})
|
})
|
||||||
export class ResourcesWidgetComponent {
|
export class ResourcesWidgetComponent {
|
||||||
constructor() {}
|
constructor(public userDataService: UserDataService) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,21 @@
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="console-app__widget_right">
|
<div class="console-app__widget_right">
|
||||||
<button mat-button color="primary" class="console-app__widget-link">
|
<button
|
||||||
|
mat-button
|
||||||
|
color="primary"
|
||||||
|
class="console-app__widget-link"
|
||||||
|
(click)="openContactsPage()"
|
||||||
|
>
|
||||||
Contact Information
|
Contact Information
|
||||||
</button>
|
</button>
|
||||||
<p class="secondary-text">Manage Primary, Technical, etc contacts.</p>
|
<p class="secondary-text">Manage Primary, Technical, etc contacts.</p>
|
||||||
<button mat-button color="primary" class="console-app__widget-link">
|
<button
|
||||||
|
mat-button
|
||||||
|
color="primary"
|
||||||
|
class="console-app__widget-link"
|
||||||
|
(click)="openSecurityPage()"
|
||||||
|
>
|
||||||
Security
|
Security
|
||||||
</button>
|
</button>
|
||||||
<p class="secondary-text">
|
<p class="secondary-text">
|
||||||
|
@ -28,7 +38,12 @@
|
||||||
User Management
|
User Management
|
||||||
</button>
|
</button>
|
||||||
<p class="secondary-text">Create and manage console user accounts</p>
|
<p class="secondary-text">Create and manage console user accounts</p>
|
||||||
<button mat-button color="primary" class="console-app__widget-link">
|
<button
|
||||||
|
mat-button
|
||||||
|
color="primary"
|
||||||
|
class="console-app__widget-link"
|
||||||
|
(click)="openRegistrarsPage()"
|
||||||
|
>
|
||||||
Registrar Management
|
Registrar Management
|
||||||
</button>
|
</button>
|
||||||
<p class="secondary-text">Create and manage registrar accounts</p>
|
<p class="secondary-text">Create and manage registrar accounts</p>
|
||||||
|
|
|
@ -13,11 +13,32 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { RegistrarComponent } from 'src/app/registrar/registrarsTable.component';
|
||||||
|
import ContactComponent from 'src/app/settings/contact/contact.component';
|
||||||
|
import SecurityComponent from 'src/app/settings/security/security.component';
|
||||||
|
import { SettingsComponent } from 'src/app/settings/settings.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-settings-widget]',
|
selector: '[app-settings-widget]',
|
||||||
templateUrl: './settings-widget.component.html',
|
templateUrl: './settings-widget.component.html',
|
||||||
})
|
})
|
||||||
export class SettingsWidgetComponent {
|
export class SettingsWidgetComponent {
|
||||||
constructor() {}
|
constructor(private router: Router) {}
|
||||||
|
|
||||||
|
openRegistrarsPage() {
|
||||||
|
this.navigate(RegistrarComponent.PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
openSecurityPage() {
|
||||||
|
this.navigate(SecurityComponent.PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
openContactsPage() {
|
||||||
|
this.navigate(ContactComponent.PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
private navigate(route: string) {
|
||||||
|
this.router.navigate([SettingsComponent.PATH, route]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {
|
||||||
GlobalLoader,
|
GlobalLoader,
|
||||||
GlobalLoaderService,
|
GlobalLoaderService,
|
||||||
} from '../shared/services/globalLoader.service';
|
} from '../shared/services/globalLoader.service';
|
||||||
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
|
|
||||||
interface Address {
|
interface Address {
|
||||||
street?: string[];
|
street?: string[];
|
||||||
|
@ -52,7 +53,8 @@ export class RegistrarService implements GlobalLoader {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private backend: BackendService,
|
private backend: BackendService,
|
||||||
private globalLoader: GlobalLoaderService
|
private globalLoader: GlobalLoaderService,
|
||||||
|
private _snackBar: MatSnackBar
|
||||||
) {
|
) {
|
||||||
this.loadRegistrars().subscribe((r) => {
|
this.loadRegistrars().subscribe((r) => {
|
||||||
this.globalLoader.stopGlobalLoader(this);
|
this.globalLoader.stopGlobalLoader(this);
|
||||||
|
@ -82,6 +84,8 @@ export class RegistrarService implements GlobalLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
loadingTimeout() {
|
loadingTimeout() {
|
||||||
// TODO: Decide what to do when timeout happens
|
this._snackBar.open('Timeout loading registrars', undefined, {
|
||||||
|
duration: 1500,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import { Registrar, RegistrarService } from './registrar.service';
|
||||||
styleUrls: ['./registrarsTable.component.scss'],
|
styleUrls: ['./registrarsTable.component.scss'],
|
||||||
})
|
})
|
||||||
export class RegistrarComponent {
|
export class RegistrarComponent {
|
||||||
|
public static PATH = 'registrars';
|
||||||
columns = [
|
columns = [
|
||||||
{
|
{
|
||||||
columnDef: 'registrarId',
|
columnDef: 'registrarId',
|
||||||
|
|
|
@ -143,6 +143,8 @@ export class ContactDetailsDialogComponent {
|
||||||
styleUrls: ['./contact.component.scss'],
|
styleUrls: ['./contact.component.scss'],
|
||||||
})
|
})
|
||||||
export default class ContactComponent {
|
export default class ContactComponent {
|
||||||
|
public static PATH = 'contact';
|
||||||
|
|
||||||
loading: boolean = false;
|
loading: boolean = false;
|
||||||
constructor(
|
constructor(
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
|
|
|
@ -29,6 +29,8 @@ import { RegistrarService } from 'src/app/registrar/registrar.service';
|
||||||
providers: [SecurityService],
|
providers: [SecurityService],
|
||||||
})
|
})
|
||||||
export default class SecurityComponent {
|
export default class SecurityComponent {
|
||||||
|
public static PATH = 'security';
|
||||||
|
|
||||||
loading: boolean = false;
|
loading: boolean = false;
|
||||||
inEdit: boolean = false;
|
inEdit: boolean = false;
|
||||||
dataSource: SecuritySettings = {};
|
dataSource: SecuritySettings = {};
|
||||||
|
|
|
@ -20,4 +20,6 @@ import { Component, ViewEncapsulation } from '@angular/core';
|
||||||
styleUrls: ['./settings.component.scss'],
|
styleUrls: ['./settings.component.scss'],
|
||||||
encapsulation: ViewEncapsulation.None,
|
encapsulation: ViewEncapsulation.None,
|
||||||
})
|
})
|
||||||
export class SettingsComponent {}
|
export class SettingsComponent {
|
||||||
|
public static PATH = 'settings';
|
||||||
|
}
|
||||||
|
|
|
@ -19,4 +19,6 @@ import { Component } from '@angular/core';
|
||||||
templateUrl: './users.component.html',
|
templateUrl: './users.component.html',
|
||||||
styleUrls: ['./users.component.scss'],
|
styleUrls: ['./users.component.scss'],
|
||||||
})
|
})
|
||||||
export default class UsersComponent {}
|
export default class UsersComponent {
|
||||||
|
public static PATH = 'users';
|
||||||
|
}
|
||||||
|
|
|
@ -19,4 +19,6 @@ import { Component } from '@angular/core';
|
||||||
templateUrl: './whois.component.html',
|
templateUrl: './whois.component.html',
|
||||||
styleUrls: ['./whois.component.scss'],
|
styleUrls: ['./whois.component.scss'],
|
||||||
})
|
})
|
||||||
export default class WhoisComponent {}
|
export default class WhoisComponent {
|
||||||
|
public static PATH = 'whois';
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { SecuritySettingsBackendModel } from 'src/app/settings/security/security
|
||||||
|
|
||||||
import { Contact } from '../../settings/contact/contact.service';
|
import { Contact } from '../../settings/contact/contact.service';
|
||||||
import { Registrar } from '../../registrar/registrar.service';
|
import { Registrar } from '../../registrar/registrar.service';
|
||||||
|
import { UserData } from './userData.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class BackendService {
|
export class BackendService {
|
||||||
|
@ -90,4 +91,10 @@ export class BackendService {
|
||||||
securitySettings
|
securitySettings
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getUserData(): Observable<UserData> {
|
||||||
|
return this.http
|
||||||
|
.get<UserData>(`/console-api/userdata`)
|
||||||
|
.pipe(catchError((err) => this.errorCatcher<UserData>(err)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
56
console-webapp/src/app/shared/services/userData.service.ts
Normal file
56
console-webapp/src/app/shared/services/userData.service.ts
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright 2023 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 { Injectable } from '@angular/core';
|
||||||
|
import { Observable, tap } from 'rxjs';
|
||||||
|
import { BackendService } from './backend.service';
|
||||||
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
|
import { GlobalLoader, GlobalLoaderService } from './globalLoader.service';
|
||||||
|
|
||||||
|
export interface UserData {
|
||||||
|
isAdmin: boolean;
|
||||||
|
globalRole: string;
|
||||||
|
technicalDocsUrl: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class UserDataService implements GlobalLoader {
|
||||||
|
public userData?: UserData;
|
||||||
|
constructor(
|
||||||
|
private backend: BackendService,
|
||||||
|
protected globalLoader: GlobalLoaderService,
|
||||||
|
private _snackBar: MatSnackBar
|
||||||
|
) {
|
||||||
|
this.getUserData().subscribe(() => {
|
||||||
|
this.globalLoader.stopGlobalLoader(this);
|
||||||
|
});
|
||||||
|
this.globalLoader.startGlobalLoader(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserData(): Observable<UserData> {
|
||||||
|
return this.backend.getUserData().pipe(
|
||||||
|
tap((userData: UserData) => {
|
||||||
|
this.userData = userData;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadingTimeout() {
|
||||||
|
this._snackBar.open('Timeout loading user data', undefined, {
|
||||||
|
duration: 1500,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,15 +45,16 @@ body {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
height: 20px !important;
|
height: 20px !important;
|
||||||
|
min-width: auto !important;
|
||||||
}
|
}
|
||||||
&-title {
|
&-title {
|
||||||
color: var(--primary) !important;
|
color: var(--primary) !important;
|
||||||
}
|
}
|
||||||
&-icon {
|
&-icon {
|
||||||
font-size: 4rem;
|
font-size: 5rem;
|
||||||
line-height: 4rem;
|
line-height: 5rem;
|
||||||
height: 4rem !important;
|
height: 5rem !important;
|
||||||
width: 4rem !important;
|
width: 5rem !important;
|
||||||
}
|
}
|
||||||
&_left {
|
&_left {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue