diff --git a/console-webapp/src/app/app.component.less b/console-webapp/src/app/app.component.scss
similarity index 87%
rename from console-webapp/src/app/app.component.less
rename to console-webapp/src/app/app.component.scss
index baeb4a306..889cbf173 100644
--- a/console-webapp/src/app/app.component.less
+++ b/console-webapp/src/app/app.component.scss
@@ -13,8 +13,8 @@
// limitations under the License.
:host {
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
- Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+ font-family: Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji",
+ "Segoe UI Emoji", "Segoe UI Symbol" !important;
font-size: 14px;
color: #333;
box-sizing: border-box;
@@ -47,4 +47,7 @@
max-width: 1340px;
margin: 0 auto;
}
+ &__global-spinner {
+ margin-bottom: 2rem;
+ }
}
diff --git a/console-webapp/src/app/app.component.ts b/console-webapp/src/app/app.component.ts
index c7997158d..9fdaf0173 100644
--- a/console-webapp/src/app/app.component.ts
+++ b/console-webapp/src/app/app.component.ts
@@ -13,10 +13,25 @@
// limitations under the License.
import { Component } from '@angular/core';
+import { RegistrarService } from './registrar/registrar.service';
+import { GlobalLoaderService } from './shared/services/globalLoader.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
- styleUrls: ['./app.component.less'],
+ styleUrls: ['./app.component.scss'],
})
-export class AppComponent {}
+export class AppComponent {
+ renderRouter: boolean = true;
+ constructor(
+ protected registrarService: RegistrarService,
+ protected globalLoader: GlobalLoaderService
+ ) {
+ registrarService.activeRegistrarIdChange.subscribe(() => {
+ this.renderRouter = false;
+ setTimeout(() => {
+ this.renderRouter = true;
+ }, 400);
+ });
+ }
+}
diff --git a/console-webapp/src/app/app.module.ts b/console-webapp/src/app/app.module.ts
index 604637b85..d6d4fa1e3 100644
--- a/console-webapp/src/app/app.module.ts
+++ b/console-webapp/src/app/app.module.ts
@@ -31,9 +31,20 @@ import SettingsContactComponent, {
ContactDetailsDialogComponent,
} from './settings/contact/contact.component';
import { HttpClientModule } from '@angular/common/http';
-import { RegistrarComponent } from './registrar/registrar.component';
+import { RegistrarComponent } from './registrar/registrarsTable.component';
import { RegistrarGuard } from './registrar/registrar.guard';
import SecurityComponent from './settings/security/security.component';
+import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
+import { EmptyRegistrar } from './registrar/emptyRegistrar.component';
+import { RegistrarSelectorComponent } from './registrar/registrar-selector.component';
+import { GlobalLoaderService } from './shared/services/globalLoader.service';
+import { ContactWidgetComponent } from './home/widgets/contact-widget.component';
+import { PromotionsWidgetComponent } from './home/widgets/promotions-widget.component';
+import { TldsWidgetComponent } from './home/widgets/tlds-widget.component';
+import { ResourcesWidgetComponent } from './home/widgets/resources-widget.component';
+import { EppWidgetComponent } from './home/widgets/epp-widget.component';
+import { BillingWidgetComponent } from './home/widgets/billing-widget.component';
+import { DomainsWidgetComponent } from './home/widgets/domains-widget.component';
@NgModule({
declarations: [
@@ -46,6 +57,15 @@ import SecurityComponent from './settings/security/security.component';
ContactDetailsDialogComponent,
RegistrarComponent,
SecurityComponent,
+ EmptyRegistrar,
+ RegistrarSelectorComponent,
+ ContactWidgetComponent,
+ DomainsWidgetComponent,
+ PromotionsWidgetComponent,
+ TldsWidgetComponent,
+ ResourcesWidgetComponent,
+ EppWidgetComponent,
+ BillingWidgetComponent,
],
imports: [
HttpClientModule,
@@ -55,7 +75,17 @@ import SecurityComponent from './settings/security/security.component';
AppRoutingModule,
BrowserAnimationsModule,
],
- providers: [BackendService, RegistrarGuard],
+ providers: [
+ GlobalLoaderService,
+ BackendService,
+ RegistrarGuard,
+ {
+ provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,
+ useValue: {
+ subscriptSizing: 'dynamic',
+ },
+ },
+ ],
bootstrap: [AppComponent],
})
export class AppModule {}
diff --git a/console-webapp/src/app/header/header.component.html b/console-webapp/src/app/header/header.component.html
index 176c52888..c4c55736b 100644
--- a/console-webapp/src/app/header/header.component.html
+++ b/console-webapp/src/app/header/header.component.html
@@ -5,6 +5,7 @@
Google Registry
+
diff --git a/console-webapp/src/app/header/header.component.less b/console-webapp/src/app/header/header.component.scss
similarity index 93%
rename from console-webapp/src/app/header/header.component.less
rename to console-webapp/src/app/header/header.component.scss
index d952d86e3..a12cd4528 100644
--- a/console-webapp/src/app/header/header.component.less
+++ b/console-webapp/src/app/header/header.component.scss
@@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+.console-app__header {
+ margin-top: 0;
+}
.spacer {
flex: 1;
}
diff --git a/console-webapp/src/app/header/header.component.ts b/console-webapp/src/app/header/header.component.ts
index 602e48803..01258b105 100644
--- a/console-webapp/src/app/header/header.component.ts
+++ b/console-webapp/src/app/header/header.component.ts
@@ -17,7 +17,7 @@ import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
- styleUrls: ['./header.component.less'],
+ styleUrls: ['./header.component.scss'],
})
export class HeaderComponent {
private isNavOpen = false;
diff --git a/console-webapp/src/app/home/home.component.html b/console-webapp/src/app/home/home.component.html
index 7c27e9020..a362655df 100644
--- a/console-webapp/src/app/home/home.component.html
+++ b/console-webapp/src/app/home/home.component.html
@@ -1,21 +1,13 @@
-
Recent Activity
-
-
-
- {{ column.header }}
-
-
- {{ column.cell(row) }}
-
-
-
-
-
-
+
+
Welcome to the Google Registry Console
+
+
+
+
+
+
+
+
+
+
+
diff --git a/console-webapp/src/app/home/home.component.less b/console-webapp/src/app/home/home.component.less
deleted file mode 100644
index 2a8db28e9..000000000
--- a/console-webapp/src/app/home/home.component.less
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2022 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.
diff --git a/console-webapp/src/styles.less b/console-webapp/src/app/home/home.component.scss
similarity index 69%
rename from console-webapp/src/styles.less
rename to console-webapp/src/app/home/home.component.scss
index d02061a73..627b1d7ca 100644
--- a/console-webapp/src/styles.less
+++ b/console-webapp/src/app/home/home.component.scss
@@ -12,11 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-html,
-body {
- height: 100%;
-}
-body {
- margin: 0;
- font-family: Roboto, "Helvetica Neue", sans-serif;
+.console-app {
+ &__home {
+ margin-top: 1rem;
+ }
+ &__home-widgets {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
+ grid-gap: 20px;
+
+ mat-card {
+ height: 100%;
+ h1 {
+ margin-top: 1rem;
+ }
+ }
+ }
}
diff --git a/console-webapp/src/app/home/home.component.ts b/console-webapp/src/app/home/home.component.ts
index 60117c18d..6ce4e2b53 100644
--- a/console-webapp/src/app/home/home.component.ts
+++ b/console-webapp/src/app/home/home.component.ts
@@ -12,220 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { Component } from '@angular/core';
-
-export interface ActivityRecord {
- eventType: string;
- userName: string;
- registrarName: string;
- timestamp: string;
- details: string;
-}
-
-const MOCK_DATA: ActivityRecord[] = [
- {
- eventType: 'Export DUMS',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Update Contact',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Delete Domain',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Export DUMS',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Update Contact',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Delete Domain',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Export DUMS',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Update Contact',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Delete Domain',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Export DUMS',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Update Contact',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Delete Domain',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Export DUMS',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Update Contact',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Delete Domain',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Export DUMS',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Update Contact',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Delete Domain',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Export DUMS',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Update Contact',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Delete Domain',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Export DUMS',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Update Contact',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
- {
- eventType: 'Delete Domain',
- userName: 'user3',
- registrarName: 'registrar1',
- timestamp: '2022-03-15T19:46:39.007',
- details: 'All Domains under management exported as .csv file',
- },
-];
+import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
- styleUrls: ['./home.component.less'],
+ styleUrls: ['./home.component.scss'],
+ encapsulation: ViewEncapsulation.None,
})
-export class HomeComponent {
- columns = [
- {
- columnDef: 'eventType',
- header: 'Event Type',
- cell: (record: ActivityRecord) => `${record.eventType}`,
- },
- {
- columnDef: 'userName',
- header: 'User',
- cell: (record: ActivityRecord) => `${record.userName}`,
- },
- {
- columnDef: 'registrarName',
- header: 'Registrar',
- cell: (record: ActivityRecord) => `${record.registrarName}`,
- },
- {
- columnDef: 'timestamp',
- header: 'Timestamp',
- cell: (record: ActivityRecord) => `${record.timestamp}`,
- },
- {
- columnDef: 'details',
- header: 'Details',
- cell: (record: ActivityRecord) => `${record.details}`,
- },
- ];
- dataSource = MOCK_DATA;
- displayedColumns = this.columns.map((c) => c.columnDef);
-}
+export class HomeComponent {}
diff --git a/console-webapp/src/app/home/widgets/billing-widget.component.html b/console-webapp/src/app/home/widgets/billing-widget.component.html
new file mode 100644
index 000000000..6357fb923
--- /dev/null
+++ b/console-webapp/src/app/home/widgets/billing-widget.component.html
@@ -0,0 +1,13 @@
+
+
+
+
+ account_balance
+
Billing Info
+
+ View important billing and payments information.
+
+
+
+
+
diff --git a/console-webapp/src/app/settings/registrars/registrars.component.ts b/console-webapp/src/app/home/widgets/billing-widget.component.ts
similarity index 80%
rename from console-webapp/src/app/settings/registrars/registrars.component.ts
rename to console-webapp/src/app/home/widgets/billing-widget.component.ts
index db980cd18..80fde1e40 100644
--- a/console-webapp/src/app/settings/registrars/registrars.component.ts
+++ b/console-webapp/src/app/home/widgets/billing-widget.component.ts
@@ -15,8 +15,9 @@
import { Component } from '@angular/core';
@Component({
- selector: 'app-registrars',
- templateUrl: './registrars.component.html',
- styleUrls: ['./registrars.component.less'],
+ selector: '[app-billing-widget]',
+ templateUrl: './billing-widget.component.html',
})
-export default class RegistrarsComponent {}
+export class BillingWidgetComponent {
+ constructor() {}
+}
diff --git a/console-webapp/src/app/home/widgets/contact-widget.component.html b/console-webapp/src/app/home/widgets/contact-widget.component.html
new file mode 100644
index 000000000..5003d7c89
--- /dev/null
+++ b/console-webapp/src/app/home/widgets/contact-widget.component.html
@@ -0,0 +1,27 @@
+
+
+
+
+ call
+
Contact Support
+
+ View Google Registry support email and phone information
+
+
+
+
+
+ Call Google Registry support at +1 (404) 978 8419
+
+
+
+ Email Google Registry at support@google.com
+
+
+
+
+
diff --git a/console-webapp/src/app/home/widgets/contact-widget.component.ts b/console-webapp/src/app/home/widgets/contact-widget.component.ts
new file mode 100644
index 000000000..2d279bfaa
--- /dev/null
+++ b/console-webapp/src/app/home/widgets/contact-widget.component.ts
@@ -0,0 +1,23 @@
+// 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 { Component } from '@angular/core';
+
+@Component({
+ selector: '[app-contact-widget]',
+ templateUrl: './contact-widget.component.html',
+})
+export class ContactWidgetComponent {
+ constructor() {}
+}
diff --git a/console-webapp/src/app/home/widgets/domains-widget.component.html b/console-webapp/src/app/home/widgets/domains-widget.component.html
new file mode 100644
index 000000000..7df3b1621
--- /dev/null
+++ b/console-webapp/src/app/home/widgets/domains-widget.component.html
@@ -0,0 +1,25 @@
+
+
+
+
+ view_list
+
Domains
+
+ Manage domain names and registry lock settings.
+
+
+
+
+
Register a new domain name
+
+
+ Download a csv of all domains under management
+
+
+
+
+
diff --git a/console-webapp/src/app/home/widgets/domains-widget.component.ts b/console-webapp/src/app/home/widgets/domains-widget.component.ts
new file mode 100644
index 000000000..6995ce3c1
--- /dev/null
+++ b/console-webapp/src/app/home/widgets/domains-widget.component.ts
@@ -0,0 +1,23 @@
+// 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 { Component } from '@angular/core';
+
+@Component({
+ selector: '[app-domains-widget]',
+ templateUrl: './domains-widget.component.html',
+})
+export class DomainsWidgetComponent {
+ constructor() {}
+}
diff --git a/console-webapp/src/app/home/widgets/epp-widget.component.html b/console-webapp/src/app/home/widgets/epp-widget.component.html
new file mode 100644
index 000000000..c014b514d
--- /dev/null
+++ b/console-webapp/src/app/home/widgets/epp-widget.component.html
@@ -0,0 +1,13 @@
+
+
+
+
+ computer
+
EPP Console
+
+ Test run and execute EPP commands using XML files.
+
+
+
+
+
diff --git a/console-webapp/src/app/settings/whois/whois.component.less b/console-webapp/src/app/home/widgets/epp-widget.component.ts
similarity index 76%
rename from console-webapp/src/app/settings/whois/whois.component.less
rename to console-webapp/src/app/home/widgets/epp-widget.component.ts
index 5b5b64371..79c3b7845 100644
--- a/console-webapp/src/app/settings/whois/whois.component.less
+++ b/console-webapp/src/app/home/widgets/epp-widget.component.ts
@@ -11,3 +11,13 @@
// 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 { Component } from '@angular/core';
+
+@Component({
+ selector: '[app-epp-widget]',
+ templateUrl: './epp-widget.component.html',
+})
+export class EppWidgetComponent {
+ constructor() {}
+}
diff --git a/console-webapp/src/app/home/widgets/promotions-widget.component.html b/console-webapp/src/app/home/widgets/promotions-widget.component.html
new file mode 100644
index 000000000..cb0c5b8ba
--- /dev/null
+++ b/console-webapp/src/app/home/widgets/promotions-widget.component.html
@@ -0,0 +1,27 @@
+
+
+
+
+ subject
+
Promotions
+
+ Manage Google Registry promotions and view onboarding process.
+
+
+
+
+
+ Onboard or view current preferred partner status
+
+
+
+ Onboard or view current registry lock status
+
+
+
+
+
diff --git a/console-webapp/src/app/home/widgets/promotions-widget.component.ts b/console-webapp/src/app/home/widgets/promotions-widget.component.ts
new file mode 100644
index 000000000..5e068f0a8
--- /dev/null
+++ b/console-webapp/src/app/home/widgets/promotions-widget.component.ts
@@ -0,0 +1,23 @@
+// 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 { Component } from '@angular/core';
+
+@Component({
+ selector: '[app-promotions-widget]',
+ templateUrl: './promotions-widget.component.html',
+})
+export class PromotionsWidgetComponent {
+ constructor() {}
+}
diff --git a/console-webapp/src/app/home/widgets/resources-widget.component.html b/console-webapp/src/app/home/widgets/resources-widget.component.html
new file mode 100644
index 000000000..65cc39777
--- /dev/null
+++ b/console-webapp/src/app/home/widgets/resources-widget.component.html
@@ -0,0 +1,13 @@
+
+
+
+
+ menu_book
+
Resources
+
+ Use Google Drive to view onboarding FAQs, and technical documentation.
+
+
+
+
+
diff --git a/console-webapp/src/app/home/widgets/resources-widget.component.ts b/console-webapp/src/app/home/widgets/resources-widget.component.ts
new file mode 100644
index 000000000..acebf562a
--- /dev/null
+++ b/console-webapp/src/app/home/widgets/resources-widget.component.ts
@@ -0,0 +1,23 @@
+// 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 { Component } from '@angular/core';
+
+@Component({
+ selector: '[app-resources-widget]',
+ templateUrl: './resources-widget.component.html',
+})
+export class ResourcesWidgetComponent {
+ constructor() {}
+}
diff --git a/console-webapp/src/app/home/widgets/tlds-widget.component.html b/console-webapp/src/app/home/widgets/tlds-widget.component.html
new file mode 100644
index 000000000..99324ed7f
--- /dev/null
+++ b/console-webapp/src/app/home/widgets/tlds-widget.component.html
@@ -0,0 +1,13 @@
+
+
+
+
+ list_alt
+
TLDs
+
+ View launch phase information for all onboarded and available TLDs.
+
+
+
+
+
diff --git a/console-webapp/src/app/home/widgets/tlds-widget.component.ts b/console-webapp/src/app/home/widgets/tlds-widget.component.ts
new file mode 100644
index 000000000..25c3be0ac
--- /dev/null
+++ b/console-webapp/src/app/home/widgets/tlds-widget.component.ts
@@ -0,0 +1,23 @@
+// 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 { Component } from '@angular/core';
+
+@Component({
+ selector: '[app-tlds-widget]',
+ templateUrl: './tlds-widget.component.html',
+})
+export class TldsWidgetComponent {
+ constructor() {}
+}
diff --git a/console-webapp/src/app/material.module.ts b/console-webapp/src/app/material.module.ts
index d0eaf1585..a27951cde 100644
--- a/console-webapp/src/app/material.module.ts
+++ b/console-webapp/src/app/material.module.ts
@@ -44,6 +44,7 @@ import { CdkMenuModule } from '@angular/cdk/menu';
import { DialogModule } from '@angular/cdk/dialog';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatSnackBarModule } from '@angular/material/snack-bar';
+import { MatPaginatorModule } from '@angular/material/paginator';
@NgModule({
exports: [
@@ -79,6 +80,7 @@ import { MatSnackBarModule } from '@angular/material/snack-bar';
OverlayModule,
DialogModule,
MatSnackBarModule,
+ MatPaginatorModule,
],
})
export class MaterialModule {}
diff --git a/console-webapp/src/app/registrar/emptyRegistrar.component.html b/console-webapp/src/app/registrar/emptyRegistrar.component.html
new file mode 100644
index 000000000..e77cdc8b3
--- /dev/null
+++ b/console-webapp/src/app/registrar/emptyRegistrar.component.html
@@ -0,0 +1,7 @@
+
diff --git a/console-webapp/src/app/settings/security/security.component.less b/console-webapp/src/app/settings/security/security.component.scss
similarity index 100%
rename from console-webapp/src/app/settings/security/security.component.less
rename to console-webapp/src/app/settings/security/security.component.scss
diff --git a/console-webapp/src/app/settings/security/security.component.ts b/console-webapp/src/app/settings/security/security.component.ts
index 9eb602bda..a85551eae 100644
--- a/console-webapp/src/app/settings/security/security.component.ts
+++ b/console-webapp/src/app/settings/security/security.component.ts
@@ -20,7 +20,7 @@ import { MatSnackBar } from '@angular/material/snack-bar';
@Component({
selector: 'app-security',
templateUrl: './security.component.html',
- styleUrls: ['./security.component.less'],
+ styleUrls: ['./security.component.scss'],
providers: [SecurityService],
})
export default class SecurityComponent {
diff --git a/console-webapp/src/app/settings/settings.component.less b/console-webapp/src/app/settings/settings.component.scss
similarity index 100%
rename from console-webapp/src/app/settings/settings.component.less
rename to console-webapp/src/app/settings/settings.component.scss
diff --git a/console-webapp/src/app/settings/settings.component.ts b/console-webapp/src/app/settings/settings.component.ts
index c352e603e..2ac660a67 100644
--- a/console-webapp/src/app/settings/settings.component.ts
+++ b/console-webapp/src/app/settings/settings.component.ts
@@ -17,7 +17,7 @@ import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-settings',
templateUrl: './settings.component.html',
- styleUrls: ['./settings.component.less'],
+ styleUrls: ['./settings.component.scss'],
encapsulation: ViewEncapsulation.None,
})
export class SettingsComponent {}
diff --git a/console-webapp/src/app/settings/registrars/registrars.component.less b/console-webapp/src/app/settings/users/users.component.scss
similarity index 100%
rename from console-webapp/src/app/settings/registrars/registrars.component.less
rename to console-webapp/src/app/settings/users/users.component.scss
diff --git a/console-webapp/src/app/settings/users/users.component.ts b/console-webapp/src/app/settings/users/users.component.ts
index 0e432fd0a..4495d6281 100644
--- a/console-webapp/src/app/settings/users/users.component.ts
+++ b/console-webapp/src/app/settings/users/users.component.ts
@@ -17,6 +17,6 @@ import { Component } from '@angular/core';
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
- styleUrls: ['./users.component.less'],
+ styleUrls: ['./users.component.scss'],
})
export default class UsersComponent {}
diff --git a/console-webapp/src/app/settings/users/users.component.less b/console-webapp/src/app/settings/whois/whois.component.scss
similarity index 100%
rename from console-webapp/src/app/settings/users/users.component.less
rename to console-webapp/src/app/settings/whois/whois.component.scss
diff --git a/console-webapp/src/app/settings/whois/whois.component.ts b/console-webapp/src/app/settings/whois/whois.component.ts
index d53d5fda5..3b0a10533 100644
--- a/console-webapp/src/app/settings/whois/whois.component.ts
+++ b/console-webapp/src/app/settings/whois/whois.component.ts
@@ -17,6 +17,6 @@ import { Component } from '@angular/core';
@Component({
selector: 'app-whois',
templateUrl: './whois.component.html',
- styleUrls: ['./whois.component.less'],
+ styleUrls: ['./whois.component.scss'],
})
export default class WhoisComponent {}
diff --git a/console-webapp/src/app/shared/services/backend.service.ts b/console-webapp/src/app/shared/services/backend.service.ts
index d02cebcbd..a1e3132d1 100644
--- a/console-webapp/src/app/shared/services/backend.service.ts
+++ b/console-webapp/src/app/shared/services/backend.service.ts
@@ -18,6 +18,7 @@ import { catchError, Observable, of } from 'rxjs';
import { SecuritySettingsBackendModel } from 'src/app/settings/security/security.service';
import { Contact } from '../../settings/contact/contact.service';
+import { Registrar } from '../../registrar/registrar.service';
@Injectable()
export class BackendService {
@@ -60,10 +61,10 @@ export class BackendService {
);
}
- getRegistrars(): Observable {
+ getRegistrars(): Observable {
return this.http
- .get('/console-api/registrars')
- .pipe(catchError((err) => this.errorCatcher(err)));
+ .get('/console-api/registrars')
+ .pipe(catchError((err) => this.errorCatcher(err)));
}
getSecuritySettings(
diff --git a/console-webapp/src/app/shared/services/globalLoader.service.ts b/console-webapp/src/app/shared/services/globalLoader.service.ts
new file mode 100644
index 000000000..d8b0d7215
--- /dev/null
+++ b/console-webapp/src/app/shared/services/globalLoader.service.ts
@@ -0,0 +1,60 @@
+// 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, Subscription, timeout } from 'rxjs';
+
+export interface GlobalLoader {
+ loadingTimeout: () => void;
+}
+
+/**
+ * This class responsible for global application loading indicator
+ *
+ *
Only to be used for when the activity should indicate that the entire application is busy
+ * For instance - when initial user information is loading, which is crucial for any subsequent
+ * interaction with the application
+ */
+@Injectable({
+ providedIn: 'root',
+})
+export class GlobalLoaderService {
+ private static readonly TIMEOUT_MS = 3000;
+ private loaders = new Map();
+ public isLoading: boolean = false;
+
+ private syncLoading() {
+ this.isLoading = this.loaders.size > 0;
+ }
+
+ startGlobalLoader(c: GlobalLoader) {
+ const subscription = new Observable(() => {})
+ .pipe(timeout(GlobalLoaderService.TIMEOUT_MS))
+ .subscribe({
+ error: () => {
+ this.loaders.delete(c);
+ c.loadingTimeout();
+ this.syncLoading();
+ },
+ });
+ this.loaders.set(c, subscription);
+ this.syncLoading();
+ }
+
+ stopGlobalLoader(c: GlobalLoader) {
+ this.loaders.get(c)?.unsubscribe();
+ this.loaders.delete(c);
+ this.syncLoading();
+ }
+}
diff --git a/console-webapp/src/app/tlds/tlds.component.less b/console-webapp/src/app/tlds/tlds.component.scss
similarity index 100%
rename from console-webapp/src/app/tlds/tlds.component.less
rename to console-webapp/src/app/tlds/tlds.component.scss
diff --git a/console-webapp/src/app/tlds/tlds.component.ts b/console-webapp/src/app/tlds/tlds.component.ts
index 6eab16c45..0569536cb 100644
--- a/console-webapp/src/app/tlds/tlds.component.ts
+++ b/console-webapp/src/app/tlds/tlds.component.ts
@@ -17,6 +17,6 @@ import { Component } from '@angular/core';
@Component({
selector: 'app-tlds',
templateUrl: './tlds.component.html',
- styleUrls: ['./tlds.component.less'],
+ styleUrls: ['./tlds.component.scss'],
})
export class TldsComponent {}
diff --git a/console-webapp/src/styles.scss b/console-webapp/src/styles.scss
new file mode 100644
index 000000000..550e07bb1
--- /dev/null
+++ b/console-webapp/src/styles.scss
@@ -0,0 +1,63 @@
+// Copyright 2022 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.
+@use "@angular/material" as mat;
+@import "app/registrar/registrar-selector.component.scss";
+
+html,
+body {
+ height: 100%;
+}
+body {
+ margin: 0;
+ font-family: Roboto, "Helvetica Neue", sans-serif;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.console-app {
+ &__widget {
+ display: flex;
+ gap: 10px;
+ &-wrapper__wide {
+ grid-column: span 2;
+ }
+ &-link {
+ padding: 0 !important;
+ text-align: left;
+ margin-bottom: 0.5rem;
+ }
+ &-title {
+ color: var(--primary) !important;
+ }
+ &-icon {
+ font-size: 4rem;
+ line-height: 4rem;
+ height: 4rem !important;
+ width: 4rem !important;
+ }
+ &_left {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ }
+ &_right {
+ flex: 1;
+ border-left: 1px solid var(--secondary);
+ padding-left: 20px;
+ }
+ }
+}
diff --git a/console-webapp/src/theme.scss b/console-webapp/src/theme.scss
new file mode 100644
index 000000000..489a8178a
--- /dev/null
+++ b/console-webapp/src/theme.scss
@@ -0,0 +1,69 @@
+@use "sass:map";
+@use "@angular/material" as mat;
+
+/** Copied from docs section **/
+
+// Include the common styles for Angular Material. We include this here so that you only
+// have to load a single css file for Angular Material in your app.
+// Be sure that you only ever include this mixin once!
+@include mat.core();
+
+// Define the palettes for your theme using the Material Design palettes available in palette.scss
+// (imported above). For each palette, you can optionally specify a default, lighter, and darker
+// hue. Available color palettes: https://material.io/design/color/
+$theme-primary: mat.define-palette(mat.$indigo-palette);
+$theme-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
+
+// The warn palette is optional (defaults to red).
+$theme-warn: mat.define-palette(mat.$red-palette);
+
+// Create the theme object. A theme consists of configurations for individual
+// theming systems such as "color" or "typography".
+$theme: mat.define-light-theme(
+ (
+ color: (
+ primary: $theme-primary,
+ accent: $theme-accent,
+ warn: $theme-warn,
+ ),
+ density: 0,
+ )
+);
+
+/** Application specific section **/
+
+@mixin form-field-density($density) {
+ $field-typography: mat.define-typography-config(
+ $body-1: mat.define-typography-level(12px, 24px, 400),
+ );
+ @include mat.typography-level($field-typography, "body-1");
+ @include mat.form-field-density($density);
+}
+
+// Define lowest possible density class to be used in application
+// In the same manner -1...-5 classes can be defined
+.mat-form-field-density-5 {
+ @include form-field-density(-5);
+}
+
+$foreground: map.merge($theme, mat.$light-theme-foreground-palette);
+
+// Access and define a class with secondary color exposed
+.secondary-text {
+ color: map.get($foreground, "secondary-text");
+}
+
+:root {
+ --primary: #{mat.get-color-from-palette($theme-primary, 500)};
+ --secondary: #{map.get($foreground, "secondary-text")};
+}
+
+@include mat.all-component-themes($theme);
+@import "@angular/material/theming";
+
+// Define application specific typography settings, font-family, etc
+$typography-configuration: mat-typography-config(
+ $font-family: 'Roboto, "Helvetica Neue", sans-serif',
+);
+
+@include angular-material-typography($typography-configuration);