Update angular @21 (#2965)
@@ -15,7 +15,7 @@
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:application",
|
||||
"builder": "@angular/build:application",
|
||||
"options": {
|
||||
"outputPath": {
|
||||
"base": "staged/dist/",
|
||||
@@ -112,7 +112,7 @@
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"builder": "@angular/build:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "console-webapp:build:production"
|
||||
@@ -136,16 +136,18 @@
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"builder": "@angular/build:extract-i18n",
|
||||
"options": {
|
||||
"buildTarget": "console-webapp:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"builder": "@angular/build:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"polyfills": [
|
||||
"src/polyfills.ts"
|
||||
],
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"inlineStyleLanguage": "scss",
|
||||
@@ -183,5 +185,31 @@
|
||||
"schematicCollections": [
|
||||
"@angular-eslint/schematics"
|
||||
]
|
||||
},
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"type": "component"
|
||||
},
|
||||
"@schematics/angular:directive": {
|
||||
"type": "directive"
|
||||
},
|
||||
"@schematics/angular:service": {
|
||||
"type": "service"
|
||||
},
|
||||
"@schematics/angular:guard": {
|
||||
"typeSeparator": "."
|
||||
},
|
||||
"@schematics/angular:interceptor": {
|
||||
"typeSeparator": "."
|
||||
},
|
||||
"@schematics/angular:module": {
|
||||
"typeSeparator": "."
|
||||
},
|
||||
"@schematics/angular:pipe": {
|
||||
"typeSeparator": "."
|
||||
},
|
||||
"@schematics/angular:resolver": {
|
||||
"typeSeparator": "."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"/console-api":
|
||||
{
|
||||
"target": "http://[::1]:8080",
|
||||
"target": "http://localhost:8080",
|
||||
"secure": false,
|
||||
"logLevel": "debug",
|
||||
"changeOrigin": true
|
||||
|
||||
@@ -21,7 +21,7 @@ module.exports = function (config) {
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
|
||||
@@ -16,29 +16,29 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^19.1.4",
|
||||
"@angular/cdk": "^19.1.2",
|
||||
"@angular/common": "^19.1.4",
|
||||
"@angular/compiler": "^19.1.4",
|
||||
"@angular/core": "^19.1.4",
|
||||
"@angular/forms": "^19.1.4",
|
||||
"@angular/material": "^19.1.2",
|
||||
"@angular/platform-browser": "^19.1.4",
|
||||
"@angular/platform-browser-dynamic": "^19.1.4",
|
||||
"@angular/router": "^19.1.4",
|
||||
"@angular/animations": "^21.1.5",
|
||||
"@angular/cdk": "^21.1.5",
|
||||
"@angular/common": "^21.1.5",
|
||||
"@angular/compiler": "^21.1.5",
|
||||
"@angular/core": "^21.1.5",
|
||||
"@angular/forms": "^21.1.5",
|
||||
"@angular/material": "^21.1.5",
|
||||
"@angular/platform-browser": "^21.1.5",
|
||||
"@angular/platform-browser-dynamic": "^21.1.5",
|
||||
"@angular/router": "^21.1.5",
|
||||
"rxjs": "~7.5.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.15.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^19.1.5",
|
||||
"@angular-eslint/builder": "19.0.2",
|
||||
"@angular-eslint/eslint-plugin": "19.0.2",
|
||||
"@angular-eslint/eslint-plugin-template": "19.0.2",
|
||||
"@angular-eslint/schematics": "19.0.2",
|
||||
"@angular-eslint/template-parser": "19.0.2",
|
||||
"@angular/cli": "~19.1.5",
|
||||
"@angular/compiler-cli": "^19.1.4",
|
||||
"@angular/build": "^21.1.4",
|
||||
"@angular/cli": "~21.1.4",
|
||||
"@angular/compiler-cli": "^21.1.5",
|
||||
"@types/jasmine": "~4.0.0",
|
||||
"@types/node": "^18.19.74",
|
||||
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
||||
@@ -52,6 +52,6 @@
|
||||
"karma-jasmine": "~5.1.0",
|
||||
"karma-jasmine-html-reporter": "~2.0.0",
|
||||
"prettier": "2.8.7",
|
||||
"typescript": "^5.7.3"
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
<div class="console-app mat-typography">
|
||||
<app-header (toggleNavOpen)="toggleSidenav()"></app-header>
|
||||
<div class="console-app__global-spinner">
|
||||
<mat-progress-bar
|
||||
mode="indeterminate"
|
||||
*ngIf="globalLoader.isLoading"
|
||||
></mat-progress-bar>
|
||||
@if (globalLoader.isLoading) {
|
||||
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||
}
|
||||
</div>
|
||||
<mat-sidenav-container class="console-app__container">
|
||||
<mat-sidenav-content class="console-app__content-wrapper">
|
||||
|
||||
@@ -143,13 +143,14 @@
|
||||
<ng-container matColumnDef="domainName">
|
||||
<mat-header-cell *matHeaderCellDef>Domain Name</mat-header-cell>
|
||||
<mat-cell *matCellDef="let element">
|
||||
@if (getOperationMessage(element.domainName)) {
|
||||
<mat-icon
|
||||
*ngIf="getOperationMessage(element.domainName)"
|
||||
[matTooltip]="getOperationMessage(element.domainName)"
|
||||
matTooltipPosition="above"
|
||||
class="primary-text"
|
||||
>info</mat-icon
|
||||
>
|
||||
}
|
||||
<span>{{ element.domainName }}</span>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
@@ -209,9 +210,9 @@
|
||||
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
|
||||
|
||||
<!-- Row shown when there is no matching data. -->
|
||||
<mat-row *matNoDataRow>
|
||||
<mat-cell colspan="6">No domains found</mat-cell>
|
||||
</mat-row>
|
||||
<tr class="mat-row" *matNoDataRow>
|
||||
<td class="mat-cell" colspan="6">No domains found</td>
|
||||
</tr>
|
||||
</mat-table>
|
||||
<mat-paginator
|
||||
[length]="totalResults"
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
MatDialogRef,
|
||||
} from '@angular/material/dialog';
|
||||
import { RESTRICTED_ELEMENTS } from '../shared/directives/userLevelVisiblity.directive';
|
||||
import { CdkColumnDef } from '@angular/cdk/table';
|
||||
|
||||
interface DomainResponse {
|
||||
message: string;
|
||||
@@ -114,6 +115,7 @@ export class ReasonDialogComponent {
|
||||
templateUrl: './domainList.component.html',
|
||||
styleUrls: ['./domainList.component.scss'],
|
||||
standalone: false,
|
||||
providers: [CdkColumnDef],
|
||||
})
|
||||
export class DomainListComponent {
|
||||
public static PATH = 'domain-list';
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<p class="console-app__header">
|
||||
<mat-toolbar>
|
||||
@if (breakpointObserver.isMobileView()) {
|
||||
<button
|
||||
mat-icon-button
|
||||
aria-label="Open navigation menu"
|
||||
(click)="toggleNavPane()"
|
||||
*ngIf="breakpointObserver.isMobileView()"
|
||||
class="console-app__menu-btn"
|
||||
>
|
||||
<mat-icon>menu</mat-icon>
|
||||
</button>
|
||||
}
|
||||
<a
|
||||
[routerLink]="'/home'"
|
||||
routerLinkActive="active"
|
||||
@@ -65,7 +66,9 @@
|
||||
</svg>
|
||||
</a>
|
||||
<span class="spacer"></span>
|
||||
<app-registrar-selector *ngIf="!breakpointObserver.isMobileView()" />
|
||||
@if (!breakpointObserver.isMobileView()) {
|
||||
<app-registrar-selector />
|
||||
}
|
||||
<button
|
||||
class="console-app__header-user-icon"
|
||||
mat-mini-fab
|
||||
@@ -79,5 +82,7 @@
|
||||
<button mat-menu-item (click)="logOut()">Log out</button>
|
||||
</mat-menu>
|
||||
</mat-toolbar>
|
||||
<app-registrar-selector *ngIf="breakpointObserver.isMobileView()" />
|
||||
@if (breakpointObserver.isMobileView()) {
|
||||
<app-registrar-selector />
|
||||
}
|
||||
</p>
|
||||
|
||||
@@ -9,41 +9,36 @@
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<mat-list role="list">
|
||||
<ng-container *ngFor="let item of historyRecords; let last = last">
|
||||
<mat-list-item class="history-list__item">
|
||||
<mat-icon
|
||||
[ngClass]="getIconClass(item.type)"
|
||||
class="history-list__icon"
|
||||
>
|
||||
{{ getIconForType(item.type) }}
|
||||
</mat-icon>
|
||||
|
||||
<div class="history-list__content">
|
||||
<div class="history-list__description">
|
||||
<span class="history-list__description--main">{{
|
||||
item.type
|
||||
}}</span>
|
||||
<div>
|
||||
<mat-chip
|
||||
*ngIf="parseDescription(item.description).detail"
|
||||
class="history-list__chip"
|
||||
>
|
||||
{{ parseDescription(item.description).detail }}
|
||||
</mat-chip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="history-list__user">
|
||||
<b>User - {{ item.actingUser.emailAddress }}</b>
|
||||
@for (item of historyRecords; track item; let last = $last) {
|
||||
<mat-list-item class="history-list__item">
|
||||
<mat-icon
|
||||
[ngClass]="getIconClass(item.type)"
|
||||
class="history-list__icon"
|
||||
>
|
||||
{{ getIconForType(item.type) }}
|
||||
</mat-icon>
|
||||
<div class="history-list__content">
|
||||
<div class="history-list__description">
|
||||
<span class="history-list__description--main">{{ item.type }}</span>
|
||||
<div>
|
||||
@if (parseDescription(item.description).detail) {
|
||||
<mat-chip class="history-list__chip">
|
||||
{{ parseDescription(item.description).detail }}
|
||||
</mat-chip>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span class="history-list__timestamp">
|
||||
{{ item.modificationTime | date : "MMM d, y, h:mm a" }}
|
||||
</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider *ngIf="!last"></mat-divider>
|
||||
</ng-container>
|
||||
<div class="history-list__user">
|
||||
<b>User - {{ item.actingUser.emailAddress }}</b>
|
||||
</div>
|
||||
</div>
|
||||
<span class="history-list__timestamp">
|
||||
{{ item.modificationTime | date : "MMM d, y, h:mm a" }}
|
||||
</span>
|
||||
</mat-list-item>
|
||||
@if (!last) {
|
||||
<mat-divider></mat-divider>
|
||||
} }
|
||||
</mat-list>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
@@ -17,6 +17,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { HomeComponent } from './home.component';
|
||||
import { MaterialModule } from '../material.module';
|
||||
import { AppModule } from '../app.module';
|
||||
import { BackendService } from '../shared/services/backend.service';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
import { provideHttpClientTesting } from '@angular/common/http/testing';
|
||||
|
||||
describe('HomeComponent', () => {
|
||||
let component: HomeComponent;
|
||||
@@ -26,6 +29,11 @@ describe('HomeComponent', () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [MaterialModule, AppModule],
|
||||
declarations: [HomeComponent],
|
||||
providers: [
|
||||
BackendService,
|
||||
provideHttpClient(),
|
||||
provideHttpClientTesting(),
|
||||
],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(HomeComponent);
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
[class.active]="router.url.includes(node.path)"
|
||||
[elementId]="getElementId(node)"
|
||||
>
|
||||
<mat-icon class="console-app__nav-icon" *ngIf="node.iconName">
|
||||
@if (node.iconName) {
|
||||
<mat-icon class="console-app__nav-icon">
|
||||
{{ node.iconName }}
|
||||
</mat-icon>
|
||||
}
|
||||
{{ node.title }}
|
||||
</mat-tree-node>
|
||||
<mat-nested-tree-node
|
||||
@@ -34,9 +36,11 @@
|
||||
{{ treeControl.isExpanded(node) ? "expand_more" : "chevron_right" }}
|
||||
</mat-icon>
|
||||
</button>
|
||||
<mat-icon class="console-app__nav-icon" *ngIf="node.iconName">
|
||||
@if (node.iconName) {
|
||||
<mat-icon class="console-app__nav-icon">
|
||||
{{ node.iconName }}
|
||||
</mat-icon>
|
||||
}
|
||||
{{ node.title }}
|
||||
</div>
|
||||
<div
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
<h1 class="mat-headline-4">OT&E Status Check</h1>
|
||||
@if(registrarId() === null) {
|
||||
<h1>Missing registrarId param</h1>
|
||||
} @else if(isOte()) {
|
||||
<h1 *ngIf="oteStatusResponse().length">
|
||||
} @else if(isOte()) { @if (oteStatusResponse().length) {
|
||||
<h1>
|
||||
Status:
|
||||
<span>{{ oteStatusUnfinished().length ? "Unfinished" : "Completed" }}</span>
|
||||
</h1>
|
||||
}
|
||||
<div class="console-app__ote-status">
|
||||
@if(oteStatusCompleted().length) {
|
||||
<div class="console-app__ote-status_completed">
|
||||
<h1>Completed</h1>
|
||||
<div *ngFor="let entry of oteStatusCompleted()">
|
||||
<mat-icon>check_box</mat-icon>{{ entry.description }}
|
||||
</div>
|
||||
@for (entry of oteStatusCompleted(); track entry) {
|
||||
<div><mat-icon>check_box</mat-icon>{{ entry.description }}</div>
|
||||
}
|
||||
</div>
|
||||
} @if(oteStatusUnfinished().length) {
|
||||
<div class="console-app__ote-status_unfinished">
|
||||
<h1>Unfinished</h1>
|
||||
<div *ngFor="let entry of oteStatusUnfinished()">
|
||||
@for (entry of oteStatusUnfinished(); track entry) {
|
||||
<div>
|
||||
<mat-icon>check_box_outline_blank</mat-icon>{{ entry.description }}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,7 @@ import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { RegistrarService } from '../registrar/registrar.service';
|
||||
import { MaterialModule } from '../material.module';
|
||||
import { SnackBarModule } from '../snackbar.module';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { ActivatedRoute, ParamMap } from '@angular/router';
|
||||
import { take } from 'rxjs';
|
||||
|
||||
@@ -31,7 +31,7 @@ export interface OteStatusResponse {
|
||||
|
||||
@Component({
|
||||
selector: 'app-ote-status',
|
||||
imports: [MaterialModule, SnackBarModule, CommonModule],
|
||||
imports: [MaterialModule, SnackBarModule],
|
||||
templateUrl: './oteStatus.component.html',
|
||||
styleUrls: ['./oteStatus.component.scss'],
|
||||
})
|
||||
|
||||
@@ -11,9 +11,8 @@
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
</button>
|
||||
<div class="spacer"></div>
|
||||
@if(!inEdit && !registrarNotFound) {
|
||||
@if(!inEdit && !registrarNotFound) { @if (oteButtonVisible) {
|
||||
<button
|
||||
*ngIf="oteButtonVisible"
|
||||
mat-stroked-button
|
||||
(click)="checkOteStatus()"
|
||||
aria-label="Check OT&E account status"
|
||||
@@ -21,6 +20,7 @@
|
||||
>
|
||||
Check OT&E Status
|
||||
</button>
|
||||
}
|
||||
<button
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
@@ -39,10 +39,11 @@
|
||||
<h1>Registrar not found</h1>
|
||||
} @else {
|
||||
<h1>{{ registrarInEdit.registrarId }}</h1>
|
||||
<h2 *ngIf="registrarInEdit.registrarName !== registrarInEdit.registrarId">
|
||||
@if (registrarInEdit.registrarName !== registrarInEdit.registrarId) {
|
||||
<h2>
|
||||
{{ registrarInEdit.registrarName }}
|
||||
</h2>
|
||||
@if(inEdit) {
|
||||
} @if(inEdit) {
|
||||
<form (ngSubmit)="saveAndClose()">
|
||||
<div>
|
||||
<mat-form-field appearance="outline">
|
||||
@@ -60,15 +61,14 @@
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Onboarded TLDs: </mat-label>
|
||||
<mat-chip-grid #chipGrid aria-label="Enter TLD">
|
||||
<mat-chip-row
|
||||
*ngFor="let tld of registrarInEdit.allowedTlds"
|
||||
(removed)="removeTLD(tld)"
|
||||
>
|
||||
@for (tld of registrarInEdit.allowedTlds; track tld) {
|
||||
<mat-chip-row (removed)="removeTLD(tld)">
|
||||
{{ tld }}
|
||||
<button matChipRemove aria-label="'remove ' + tld">
|
||||
<mat-icon>cancel</mat-icon>
|
||||
</button>
|
||||
</mat-chip-row>
|
||||
}
|
||||
</mat-chip-grid>
|
||||
<input
|
||||
placeholder="New tld..."
|
||||
|
||||
@@ -5,15 +5,16 @@
|
||||
<div class="console-app__registrars-header">
|
||||
<h1 class="mat-headline-4" forceFocus>Registrars</h1>
|
||||
<div class="spacer"></div>
|
||||
@if (oteButtonVisible) {
|
||||
<button
|
||||
mat-stroked-button
|
||||
*ngIf="oteButtonVisible"
|
||||
(click)="createOteAccount()"
|
||||
aria-label="Generate OT&E accounts"
|
||||
[elementId]="getElementIdForOteBlock()"
|
||||
>
|
||||
Create OT&E accounts
|
||||
</button>
|
||||
}
|
||||
<button
|
||||
class="console-app__registrars-new"
|
||||
mat-flat-button
|
||||
@@ -43,10 +44,8 @@
|
||||
class="console-app__registrars-table"
|
||||
matSort
|
||||
>
|
||||
<ng-container
|
||||
*ngFor="let column of columns"
|
||||
[matColumnDef]="column.columnDef"
|
||||
>
|
||||
@for (column of columns; track column) {
|
||||
<ng-container [matColumnDef]="column.columnDef">
|
||||
<mat-header-cell *matHeaderCellDef>
|
||||
{{ column.header }}
|
||||
</mat-header-cell>
|
||||
@@ -55,6 +54,7 @@
|
||||
[innerHTML]="column.cell(row)"
|
||||
></mat-cell>
|
||||
</ng-container>
|
||||
}
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row
|
||||
*matRowDef="let row; columns: displayedColumns"
|
||||
|
||||
@@ -22,13 +22,12 @@
|
||||
</div>
|
||||
} @else {
|
||||
<mat-table [dataSource]="dataSource" class="mat-elevation-z0">
|
||||
<ng-container
|
||||
*ngFor="let column of columns"
|
||||
[matColumnDef]="column.columnDef"
|
||||
>
|
||||
@for (column of columns; track column) {
|
||||
<ng-container [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"
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
<div
|
||||
class="console-app__contact"
|
||||
*ngIf="contactService.contactInEdit"
|
||||
cdkTrapFocus
|
||||
[cdkTrapFocusAutoCapture]="true"
|
||||
>
|
||||
@if (contactService.contactInEdit) {
|
||||
<div class="console-app__contact" cdkTrapFocus [cdkTrapFocusAutoCapture]="true">
|
||||
<div class="console-app__contact-controls">
|
||||
<button
|
||||
mat-icon-button
|
||||
@@ -32,7 +28,6 @@
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
@if(isEditing || contactService.isContactNewView) {
|
||||
<h1>Contact Details</h1>
|
||||
<form (ngSubmit)="save($event)">
|
||||
@@ -46,7 +41,6 @@
|
||||
[ngModelOptions]="{ standalone: true }"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Primary account email: </mat-label>
|
||||
<input
|
||||
@@ -64,7 +58,6 @@
|
||||
"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Phone: </mat-label>
|
||||
<input
|
||||
@@ -74,7 +67,6 @@
|
||||
placeholder="+0.0000000000"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Fax: </mat-label>
|
||||
<input
|
||||
@@ -84,7 +76,6 @@
|
||||
/>
|
||||
</mat-form-field>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Contact Type</h1>
|
||||
<p class="console-app__contact-required">
|
||||
@@ -92,21 +83,18 @@
|
||||
(primary contact can't be updated)
|
||||
</p>
|
||||
<div class="">
|
||||
<ng-container
|
||||
*ngFor="let contactType of contactTypeToTextMap | keyvalue"
|
||||
@for (contactType of contactTypeToTextMap | keyvalue; track contactType)
|
||||
{ @if (shouldDisplayCheckbox(contactType.key)) {
|
||||
<mat-checkbox
|
||||
[checked]="checkboxIsChecked(contactType.key)"
|
||||
(change)="checkboxOnChange($event, contactType.key)"
|
||||
[disabled]="checkboxIsDisabled(contactType.key)"
|
||||
>
|
||||
<mat-checkbox
|
||||
*ngIf="shouldDisplayCheckbox(contactType.key)"
|
||||
[checked]="checkboxIsChecked(contactType.key)"
|
||||
(change)="checkboxOnChange($event, contactType.key)"
|
||||
[disabled]="checkboxIsDisabled(contactType.key)"
|
||||
>
|
||||
{{ contactType.value }}
|
||||
</mat-checkbox>
|
||||
</ng-container>
|
||||
{{ contactType.value }}
|
||||
</mat-checkbox>
|
||||
} }
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>RDAP Preferences</h1>
|
||||
<div>
|
||||
@@ -116,7 +104,6 @@
|
||||
>Show in Registrar RDAP record as admin contact</mat-checkbox
|
||||
>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-checkbox
|
||||
[(ngModel)]="contactService.contactInEdit.visibleInRdapAsTech"
|
||||
@@ -124,7 +111,6 @@
|
||||
>Show in Registrar RDAP record as technical contact</mat-checkbox
|
||||
>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-checkbox
|
||||
[(ngModel)]="contactService.contactInEdit.visibleInDomainRdapAsAbuse"
|
||||
@@ -198,15 +184,13 @@
|
||||
</mat-list-item>
|
||||
} @if(contactService.contactInEdit.visibleInRdapAsTech) {
|
||||
<mat-divider></mat-divider>
|
||||
<mat-list-item
|
||||
role="listitem"
|
||||
*ngIf="contactService.contactInEdit.visibleInRdapAsTech"
|
||||
>
|
||||
@if (contactService.contactInEdit.visibleInRdapAsTech) {
|
||||
<mat-list-item role="listitem">
|
||||
<span class="console-app__list-value"
|
||||
>Show in Registrar RDAP record as technical contact</span
|
||||
>
|
||||
</mat-list-item>
|
||||
} @if(contactService.contactInEdit.visibleInDomainRdapAsAbuse) {
|
||||
} } @if(contactService.contactInEdit.visibleInDomainRdapAsAbuse) {
|
||||
<mat-divider></mat-divider>
|
||||
<mat-list-item role="listitem">
|
||||
<span class="console-app__list-value"
|
||||
@@ -220,3 +204,4 @@
|
||||
</mat-card>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@if (registrarInEdit) {
|
||||
<div
|
||||
class="console-app__rdap-edit"
|
||||
*ngIf="registrarInEdit"
|
||||
cdkTrapFocus
|
||||
[cdkTrapFocusAutoCapture]="true"
|
||||
>
|
||||
@@ -12,7 +12,6 @@
|
||||
>
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
</button>
|
||||
|
||||
<div class="console-app__rdap-edit-controls">
|
||||
<span>
|
||||
General registrar information for your RDAP record. This information is
|
||||
@@ -20,10 +19,8 @@
|
||||
</span>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
|
||||
<div class="console-app__rdap-edit">
|
||||
<h1>Personal info</h1>
|
||||
|
||||
<form (ngSubmit)="save($event)">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Email: </mat-label>
|
||||
@@ -34,7 +31,6 @@
|
||||
[ngModelOptions]="{ standalone: true }"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Phone: </mat-label>
|
||||
<input
|
||||
@@ -44,7 +40,6 @@
|
||||
[ngModelOptions]="{ standalone: true }"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Fax: </mat-label>
|
||||
<input
|
||||
@@ -54,7 +49,6 @@
|
||||
[ngModelOptions]="{ standalone: true }"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Street Address (line 1): </mat-label>
|
||||
<input
|
||||
@@ -64,7 +58,6 @@
|
||||
[(ngModel)]="registrarInEdit.localizedAddress.street![0]"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Street Address (line 2): </mat-label>
|
||||
<input
|
||||
@@ -74,7 +67,6 @@
|
||||
[(ngModel)]="registrarInEdit.localizedAddress.street![1]"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>City: </mat-label>
|
||||
<input
|
||||
@@ -84,7 +76,6 @@
|
||||
[(ngModel)]="(registrarInEdit.localizedAddress || {}).city"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>State or Province: </mat-label>
|
||||
<input
|
||||
@@ -94,7 +85,6 @@
|
||||
[(ngModel)]="(registrarInEdit.localizedAddress || {}).state"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Country: </mat-label>
|
||||
<input
|
||||
@@ -104,7 +94,6 @@
|
||||
[(ngModel)]="(registrarInEdit.localizedAddress || {}).countryCode"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Postal code: </mat-label>
|
||||
<input
|
||||
@@ -114,7 +103,6 @@
|
||||
[(ngModel)]="(registrarInEdit.localizedAddress || {}).zip"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<button
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
@@ -126,3 +114,4 @@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import { RegistrarService } from 'src/app/registrar/registrar.service';
|
||||
import { SecurityService } from './security.service';
|
||||
import { UserDataService } from 'src/app/shared/services/userData.service';
|
||||
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { MaterialModule } from 'src/app/material.module';
|
||||
import { filter, switchMap, take } from 'rxjs';
|
||||
import { BackendService } from 'src/app/shared/services/backend.service';
|
||||
@@ -41,7 +41,7 @@ import {
|
||||
<button mat-button color="warn" (click)="onSave()">Confirm</button>
|
||||
</mat-dialog-actions>
|
||||
`,
|
||||
imports: [CommonModule, MaterialModule],
|
||||
imports: [MaterialModule],
|
||||
})
|
||||
export class ResetEppPasswordComponent {
|
||||
constructor(public dialogRef: MatDialogRef<ResetEppPasswordComponent>) {}
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
>
|
||||
</mat-list-item>
|
||||
<mat-divider></mat-divider>
|
||||
@for (item of dataSource.ipAddressAllowList; track item.value) {
|
||||
@for (item of dataSource.ipAddressAllowList; track $index){
|
||||
<mat-list-item role="listitem">
|
||||
<span class="console-app__list-value">{{ item.value }}</span>
|
||||
</mat-list-item>
|
||||
|
||||
@@ -12,7 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import {
|
||||
ComponentFixture,
|
||||
fakeAsync,
|
||||
TestBed,
|
||||
tick,
|
||||
waitForAsync,
|
||||
} from '@angular/core/testing';
|
||||
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
import { provideHttpClientTesting } from '@angular/common/http/testing';
|
||||
@@ -30,43 +36,32 @@ import { MOCK_REGISTRAR_SERVICE } from 'src/testdata/registrar/registrar.service
|
||||
describe('SecurityComponent', () => {
|
||||
let component: SecurityComponent;
|
||||
let fixture: ComponentFixture<SecurityComponent>;
|
||||
let fetchSecurityDetailsSpy: Function;
|
||||
let saveSpy: Function;
|
||||
let securityServiceStub: Partial<SecurityService>;
|
||||
|
||||
beforeEach(async () => {
|
||||
const securityServiceSpy = jasmine.createSpyObj(SecurityService, [
|
||||
'fetchSecurityDetails',
|
||||
'saveChanges',
|
||||
]);
|
||||
|
||||
fetchSecurityDetailsSpy =
|
||||
securityServiceSpy.fetchSecurityDetails.and.returnValue(of());
|
||||
|
||||
saveSpy = securityServiceSpy.saveChanges.and.returnValue(of());
|
||||
securityServiceStub = {
|
||||
isEditingSecurity: false,
|
||||
isEditingPassword: false,
|
||||
saveChanges: jasmine.createSpy('saveChanges').and.returnValue(of({})),
|
||||
};
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [SecurityEditComponent, SecurityComponent],
|
||||
imports: [MaterialModule, BrowserAnimationsModule, FormsModule],
|
||||
providers: [
|
||||
BackendService,
|
||||
SecurityService,
|
||||
{ provide: SecurityService, useValue: securityServiceStub },
|
||||
{ provide: RegistrarService, useValue: MOCK_REGISTRAR_SERVICE },
|
||||
provideHttpClient(),
|
||||
provideHttpClientTesting(),
|
||||
],
|
||||
})
|
||||
.overrideComponent(SecurityComponent, {
|
||||
set: {
|
||||
providers: [
|
||||
{ provide: SecurityService, useValue: securityServiceSpy },
|
||||
],
|
||||
},
|
||||
})
|
||||
.compileComponents();
|
||||
}).compileComponents();
|
||||
|
||||
saveSpy = securityServiceStub.saveChanges as jasmine.Spy;
|
||||
|
||||
fixture = TestBed.createComponent(SecurityComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
@@ -93,17 +88,36 @@ describe('SecurityComponent', () => {
|
||||
});
|
||||
}));
|
||||
|
||||
it('should remove ip', waitForAsync(() => {
|
||||
component.dataSource.ipAddressAllowList =
|
||||
component.dataSource.ipAddressAllowList?.splice(1);
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
let listElems: Array<HTMLElement> = Array.from(
|
||||
fixture.nativeElement.querySelectorAll('span.console-app__list-value')
|
||||
);
|
||||
expect(listElems.map((e) => e.textContent)).toContain(
|
||||
'No IP addresses on file.'
|
||||
);
|
||||
it('should remove ip', fakeAsync(() => {
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
const editBtn = fixture.nativeElement.querySelector(
|
||||
'button[aria-label="Edit security settings"]'
|
||||
);
|
||||
editBtn.click();
|
||||
|
||||
tick();
|
||||
fixture.detectChanges();
|
||||
|
||||
const removeIpBtn = fixture.nativeElement.querySelector(
|
||||
'.console-app__removeIp'
|
||||
);
|
||||
removeIpBtn.click();
|
||||
|
||||
tick();
|
||||
fixture.detectChanges();
|
||||
|
||||
const saveBtn = fixture.nativeElement.querySelector(
|
||||
'.settings-security__edit-save'
|
||||
);
|
||||
saveBtn.click();
|
||||
|
||||
tick();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(saveSpy).toHaveBeenCalledWith({
|
||||
ipAddressAllowList: [],
|
||||
});
|
||||
}));
|
||||
|
||||
@@ -119,21 +133,34 @@ describe('SecurityComponent', () => {
|
||||
expect(component.securityService.isEditingPassword).toBeTrue();
|
||||
});
|
||||
|
||||
it('should call save', waitForAsync(async () => {
|
||||
component.editSecurity();
|
||||
await fixture.whenStable();
|
||||
it('should call save', fakeAsync(() => {
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
const editBtn = fixture.nativeElement.querySelector(
|
||||
'button[aria-label="Edit security settings"]'
|
||||
);
|
||||
editBtn.click();
|
||||
|
||||
tick();
|
||||
fixture.detectChanges();
|
||||
|
||||
const el = fixture.nativeElement.querySelector(
|
||||
'.console-app__clientCertificateValue'
|
||||
);
|
||||
el.value = 'test';
|
||||
el.dispatchEvent(new Event('input'));
|
||||
|
||||
tick();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
fixture.nativeElement
|
||||
.querySelector('.settings-security__edit-save')
|
||||
.click();
|
||||
expect(saveSpy).toHaveBeenCalledOnceWith({
|
||||
|
||||
const saveBtn = fixture.nativeElement.querySelector(
|
||||
'.settings-security__edit-save'
|
||||
);
|
||||
saveBtn.click();
|
||||
|
||||
tick();
|
||||
expect(saveSpy).toHaveBeenCalledWith({
|
||||
ipAddressAllowList: [{ value: '123.123.123.123' }],
|
||||
clientCertificate: 'test',
|
||||
});
|
||||
|
||||
@@ -23,9 +23,11 @@
|
||||
<button
|
||||
matSuffix
|
||||
mat-icon-button
|
||||
class="console-app__removeIp"
|
||||
[attr.aria-label]="'Remove IP entry ' + ip.value"
|
||||
(click)="removeIpEntry(ip)"
|
||||
[disabled]="isUpdating"
|
||||
type="button"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
required
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
<mat-error *ngIf="hasError('oldPassword') as errorText">{{
|
||||
errorText
|
||||
}}</mat-error>
|
||||
@if (hasError('oldPassword'); as errorText) {
|
||||
<mat-error>{{ errorText }}</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
}
|
||||
@@ -30,9 +30,9 @@
|
||||
required
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<mat-error *ngIf="hasError('newPassword') as errorText">{{
|
||||
errorText
|
||||
}}</mat-error>
|
||||
@if (hasError('newPassword'); as errorText) {
|
||||
<mat-error>{{ errorText }}</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="console-app__password-input-form-field">
|
||||
@@ -45,9 +45,9 @@
|
||||
required
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<mat-error *ngIf="hasError('newPasswordRepeat') as errorText">{{
|
||||
errorText
|
||||
}}</mat-error>
|
||||
@if (hasError('newPasswordRepeat'); as errorText) {
|
||||
<mat-error>{{ errorText }}</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<button
|
||||
|
||||
@@ -50,15 +50,17 @@
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="isNewUser" class="console-app__user-details-save-password">
|
||||
@if (isNewUser) {
|
||||
<div class="console-app__user-details-save-password">
|
||||
<mat-icon>priority_high</mat-icon>
|
||||
Please save the password. For your security, we do not store passwords in a
|
||||
recoverable format.
|
||||
</div>
|
||||
|
||||
<p *ngIf="isLoading">
|
||||
} @if (isLoading) {
|
||||
<p>
|
||||
<mat-progress-bar mode="query"></mat-progress-bar>
|
||||
</p>
|
||||
}
|
||||
|
||||
<mat-card appearance="outlined">
|
||||
<mat-card-content>
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, computed } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { SelectedRegistrarModule } from '../app.module';
|
||||
@@ -31,7 +30,6 @@ import { UserEditFormComponent } from './userEditForm.component';
|
||||
FormsModule,
|
||||
MaterialModule,
|
||||
SnackBarModule,
|
||||
CommonModule,
|
||||
SelectedRegistrarModule,
|
||||
UserEditFormComponent,
|
||||
],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<div class="console-app__user-edit">
|
||||
<form (ngSubmit)="saveEdit($event)" #form>
|
||||
<p *ngIf="isNew()">
|
||||
@if (isNew()) {
|
||||
<p>
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label
|
||||
>User name prefix:
|
||||
@@ -19,6 +20,7 @@
|
||||
/>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
}
|
||||
<p>
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {
|
||||
Component,
|
||||
ElementRef,
|
||||
@@ -50,7 +49,7 @@ import { HttpErrorResponse } from '@angular/common/http';
|
||||
<button mat-button color="warn" (click)="onSave()">Confirm</button>
|
||||
</mat-dialog-actions>
|
||||
`,
|
||||
imports: [CommonModule, MaterialModule],
|
||||
imports: [MaterialModule],
|
||||
})
|
||||
export class ResetRegistryLockPasswordComponent {
|
||||
constructor(
|
||||
@@ -72,7 +71,7 @@ export class ResetRegistryLockPasswordComponent {
|
||||
selector: 'app-user-edit-form',
|
||||
templateUrl: './userEditForm.component.html',
|
||||
styleUrls: ['./userEditForm.component.scss'],
|
||||
imports: [FormsModule, MaterialModule, CommonModule],
|
||||
imports: [FormsModule, MaterialModule],
|
||||
providers: [],
|
||||
})
|
||||
export class UserEditFormComponent {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { Component, effect } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
@@ -35,7 +34,6 @@ import { UserEditFormComponent } from './userEditForm.component';
|
||||
FormsModule,
|
||||
MaterialModule,
|
||||
SnackBarModule,
|
||||
CommonModule,
|
||||
SelectedRegistrarModule,
|
||||
UsersListComponent,
|
||||
UserEditFormComponent,
|
||||
|
||||
@@ -5,15 +5,14 @@
|
||||
class="console-app__users-table"
|
||||
matSort
|
||||
>
|
||||
<ng-container
|
||||
*ngFor="let column of columns"
|
||||
[matColumnDef]="column.columnDef"
|
||||
>
|
||||
@for (column of columns; track column) {
|
||||
<ng-container [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"
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {
|
||||
Component,
|
||||
effect,
|
||||
@@ -43,7 +42,7 @@ export const columns = [
|
||||
selector: 'app-users-list',
|
||||
templateUrl: './usersList.component.html',
|
||||
styleUrls: ['./usersList.component.scss'],
|
||||
imports: [MaterialModule, CommonModule],
|
||||
imports: [MaterialModule],
|
||||
providers: [],
|
||||
})
|
||||
export class UsersListComponent {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { enableProdMode, provideZoneChangeDetection } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
@@ -23,5 +23,7 @@ if (environment.production || environment.sandbox) {
|
||||
}
|
||||
|
||||
platformBrowserDynamic()
|
||||
.bootstrapModule(AppModule)
|
||||
.bootstrapModule(AppModule, {
|
||||
applicationProviders: [provideZoneChangeDetection()],
|
||||
})
|
||||
.catch((err) => console.error(err));
|
||||
|
||||
@@ -14,14 +14,10 @@
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"moduleResolution": "bundler",
|
||||
"importHelpers": true,
|
||||
"target": "ES2022",
|
||||
"module": "es2020",
|
||||
"lib": [
|
||||
"es2020",
|
||||
"dom"
|
||||
],
|
||||
"useDefineForClassFields": false
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
|
||||
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
@@ -50,7 +50,7 @@ npm cache clean -f
|
||||
npm install -g n
|
||||
# Retrying because fails are possible for node.js intallation. See
|
||||
# https://github.com/nodejs/build/issues/1993
|
||||
for i in {1..5}; do n 22.7.0 && break || sleep 15; done
|
||||
for i in {1..5}; do n 22.12.0 && break || sleep 15; done
|
||||
|
||||
# Install gp_dump
|
||||
apt-get install postgresql-client-17 procps -y
|
||||
|
||||