mirror of
https://github.com/goharbor/harbor.git
synced 2025-02-07 07:21:22 +01:00
Merge pull request #4963 from ninjadq/fix_tslint_warning
Fix tslint warning
This commit is contained in:
commit
1f7a4f18e5
@ -208,7 +208,7 @@ func (ctl *DefaultController) Replicate(policyID int64, metadata ...map[string]i
|
|||||||
// prepare candidates for replication
|
// prepare candidates for replication
|
||||||
candidates := getCandidates(&policy, ctl.sourcer, metadata...)
|
candidates := getCandidates(&policy, ctl.sourcer, metadata...)
|
||||||
if len(candidates) == 0 {
|
if len(candidates) == 0 {
|
||||||
log.Debugf("replicaton candidates are null, no further action needed")
|
log.Debugf("replication candidates are null, no further action needed")
|
||||||
}
|
}
|
||||||
|
|
||||||
targets := []*common_models.RepTarget{}
|
targets := []*common_models.RepTarget{}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "harbor-ui",
|
"name": "harbor-ui",
|
||||||
"version": "0.7.18-dev.6",
|
"version": "0.7.18-dev.8",
|
||||||
"description": "Harbor shared UI components based on Clarity and Angular4",
|
"description": "Harbor shared UI components based on Clarity and Angular4",
|
||||||
"author": "VMware",
|
"author": "VMware",
|
||||||
"module": "index.js",
|
"module": "index.js",
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Subject } from 'rxjs/Subject';
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
// tslint:disable-next-line:no-unused-variable
|
||||||
import { Observable } from "rxjs/Observable";
|
import { Observable } from "rxjs/Observable";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import { Component, OnInit, EventEmitter, Output, ViewChild, Input } from '@angular/core';
|
import { Component, OnInit, ViewChild, Input } from '@angular/core';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { Configuration, ComplexValueItem } from './config';
|
import { ConfirmationState, ConfirmationTargets } from '../shared/shared.const';
|
||||||
import { ConfigurationService, SystemInfoService, SystemInfo, ClairDBStatus } from '../service/index';
|
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
||||||
|
import { ConfirmationMessage } from '../confirmation-dialog/confirmation-message';
|
||||||
|
import { ConfirmationAcknowledgement } from '../confirmation-dialog/confirmation-state-message';
|
||||||
|
import { ConfigurationService, SystemInfoService, SystemInfo } from '../service/index';
|
||||||
import {
|
import {
|
||||||
toPromise,
|
toPromise,
|
||||||
compareValue,
|
compareValue,
|
||||||
@ -9,17 +13,8 @@ import {
|
|||||||
clone
|
clone
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
import { ErrorHandler } from '../error-handler/index';
|
import { ErrorHandler } from '../error-handler/index';
|
||||||
import {
|
import { SystemSettingsComponent, VulnerabilityConfigComponent } from './index';
|
||||||
SystemSettingsComponent,
|
import { Configuration } from './config';
|
||||||
VulnerabilityConfigComponent
|
|
||||||
} from './index';
|
|
||||||
|
|
||||||
import { ConfirmationState, ConfirmationTargets, ConfirmationButtons } from '../shared/shared.const';
|
|
||||||
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
|
||||||
import { ConfirmationMessage } from '../confirmation-dialog/confirmation-message';
|
|
||||||
import { ConfirmationAcknowledgement } from '../confirmation-dialog/confirmation-state-message';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-registry-config',
|
selector: 'hbr-registry-config',
|
||||||
@ -150,7 +145,7 @@ export class RegistryConfigComponent implements OnInit {
|
|||||||
reset(): void {
|
reset(): void {
|
||||||
// Reset to the values of copy
|
// Reset to the values of copy
|
||||||
let changes: { [key: string]: any | any[] } = this.getChanges();
|
let changes: { [key: string]: any | any[] } = this.getChanges();
|
||||||
for (let prop in changes) {
|
for (let prop of Object.keys(changes)) {
|
||||||
this.config[prop] = clone(this.configCopy[prop]);
|
this.config[prop] = clone(this.configCopy[prop]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,7 +156,7 @@ export class RegistryConfigComponent implements OnInit {
|
|||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let prop in this.config) {
|
for (let prop of Object.keys(this.config)) {
|
||||||
let field = this.configCopy[prop];
|
let field = this.configCopy[prop];
|
||||||
if (field && field.editable) {
|
if (field && field.editable) {
|
||||||
if (!compareValue(field.value, this.config[prop].value)) {
|
if (!compareValue(field.value, this.config[prop].value)) {
|
||||||
|
@ -21,7 +21,7 @@ export class ReplicationConfigComponent {
|
|||||||
this.configChange.emit(this.config);
|
this.configChange.emit(this.config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Input() showSubTitle: boolean = false
|
@Input() showSubTitle: boolean = false;
|
||||||
|
|
||||||
@ViewChild("replicationConfigFrom") replicationConfigForm: NgForm;
|
@ViewChild("replicationConfigFrom") replicationConfigForm: NgForm;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
import { ErrorHandler } from '../../error-handler/index';
|
import { ErrorHandler } from '../../error-handler/index';
|
||||||
import { toPromise } from '../../utils';
|
import { toPromise } from '../../utils';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { ClairDBStatus, ClairDetail } from '../../service/interface';
|
import { ClairDetail } from '../../service/interface';
|
||||||
|
|
||||||
const ONE_HOUR_SECONDS: number = 3600;
|
const ONE_HOUR_SECONDS: number = 3600;
|
||||||
const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS;
|
const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS;
|
||||||
@ -284,7 +284,7 @@ export class VulnerabilityConfigComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getSystemInfo(): Promise<SystemInfo> {
|
getSystemInfo(): Promise<void | SystemInfo> {
|
||||||
return toPromise<SystemInfo>(this.systemInfoService.getSystemInfo())
|
return toPromise<SystemInfo>(this.systemInfoService.getSystemInfo())
|
||||||
.then((info: SystemInfo) => this.systemInfo = info)
|
.then((info: SystemInfo) => this.systemInfo = info)
|
||||||
.catch(error => this.errorHandler.error(error));
|
.catch(error => this.errorHandler.error(error));
|
||||||
|
@ -11,10 +11,20 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { ConfirmationTargets, ConfirmationButtons } from '../shared/shared.const';
|
import {
|
||||||
|
ConfirmationTargets,
|
||||||
|
ConfirmationButtons
|
||||||
|
} from "../shared/shared.const";
|
||||||
|
|
||||||
export class ConfirmationMessage {
|
export class ConfirmationMessage {
|
||||||
public constructor(title: string, message: string, param: string, data: any, targetId: ConfirmationTargets, buttons?: ConfirmationButtons) {
|
public constructor(
|
||||||
|
title: string,
|
||||||
|
message: string,
|
||||||
|
param: string,
|
||||||
|
data: any,
|
||||||
|
targetId: ConfirmationTargets,
|
||||||
|
buttons?: ConfirmationButtons
|
||||||
|
) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Type } from '@angular/core';
|
import { Type } from "@angular/core";
|
||||||
|
|
||||||
import { ConfirmationDialogComponent } from './confirmation-dialog.component';
|
import { ConfirmationDialogComponent } from "./confirmation-dialog.component";
|
||||||
|
|
||||||
export * from "./confirmation-dialog.component";
|
export * from "./confirmation-dialog.component";
|
||||||
export * from "./confirmation-batch-message";
|
export * from "./confirmation-batch-message";
|
||||||
|
@ -1,35 +1,39 @@
|
|||||||
import { ComponentFixture, TestBed, async, fakeAsync, tick } from '@angular/core/testing';
|
import {
|
||||||
|
ComponentFixture,
|
||||||
|
TestBed,
|
||||||
|
async
|
||||||
|
} from "@angular/core/testing";
|
||||||
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
import { By } from '@angular/platform-browser';
|
|
||||||
import { DebugElement } from '@angular/core';
|
|
||||||
|
|
||||||
import { SharedModule } from '../shared/shared.module';
|
import { SharedModule } from "../shared/shared.module";
|
||||||
|
|
||||||
import { FilterComponent } from '../filter/filter.component';
|
import { FilterComponent } from "../filter/filter.component";
|
||||||
|
|
||||||
import { CreateEditEndpointComponent } from '../create-edit-endpoint/create-edit-endpoint.component';
|
|
||||||
import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
|
|
||||||
import { ErrorHandler } from '../error-handler/error-handler';
|
|
||||||
import { Endpoint } from '../service/interface';
|
|
||||||
import { EndpointService, EndpointDefaultService } from '../service/endpoint.service';
|
|
||||||
import { IServiceConfig, SERVICE_CONFIG } from '../service.config';
|
|
||||||
describe('CreateEditEndpointComponent (inline template)', () => {
|
|
||||||
|
|
||||||
|
import { CreateEditEndpointComponent } from "../create-edit-endpoint/create-edit-endpoint.component";
|
||||||
|
import { InlineAlertComponent } from "../inline-alert/inline-alert.component";
|
||||||
|
import { ErrorHandler } from "../error-handler/error-handler";
|
||||||
|
import { Endpoint } from "../service/interface";
|
||||||
|
import {
|
||||||
|
EndpointService,
|
||||||
|
EndpointDefaultService
|
||||||
|
} from "../service/endpoint.service";
|
||||||
|
import { IServiceConfig, SERVICE_CONFIG } from "../service.config";
|
||||||
|
describe("CreateEditEndpointComponent (inline template)", () => {
|
||||||
let mockData: Endpoint = {
|
let mockData: Endpoint = {
|
||||||
"id": 1,
|
id: 1,
|
||||||
"endpoint": "https://10.117.4.151",
|
endpoint: "https://10.117.4.151",
|
||||||
"name": "target_01",
|
name: "target_01",
|
||||||
"username": "admin",
|
username: "admin",
|
||||||
"password": "",
|
password: "",
|
||||||
"insecure": false,
|
insecure: false,
|
||||||
"type": 0
|
type: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
let comp: CreateEditEndpointComponent;
|
let comp: CreateEditEndpointComponent;
|
||||||
let fixture: ComponentFixture<CreateEditEndpointComponent>;
|
let fixture: ComponentFixture<CreateEditEndpointComponent>;
|
||||||
|
|
||||||
let config: IServiceConfig = {
|
let config: IServiceConfig = {
|
||||||
systemInfoEndpoint: '/api/endpoints/testing'
|
systemInfoEndpoint: "/api/endpoints/testing"
|
||||||
};
|
};
|
||||||
|
|
||||||
let endpointService: EndpointService;
|
let endpointService: EndpointService;
|
||||||
@ -38,14 +42,12 @@ describe('CreateEditEndpointComponent (inline template)', () => {
|
|||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [SharedModule, NoopAnimationsModule],
|
||||||
SharedModule,
|
|
||||||
NoopAnimationsModule
|
|
||||||
],
|
|
||||||
declarations: [
|
declarations: [
|
||||||
FilterComponent,
|
FilterComponent,
|
||||||
CreateEditEndpointComponent,
|
CreateEditEndpointComponent,
|
||||||
InlineAlertComponent ],
|
InlineAlertComponent
|
||||||
|
],
|
||||||
providers: [
|
providers: [
|
||||||
ErrorHandler,
|
ErrorHandler,
|
||||||
{ provide: SERVICE_CONFIG, useValue: config },
|
{ provide: SERVICE_CONFIG, useValue: config },
|
||||||
@ -59,19 +61,21 @@ describe('CreateEditEndpointComponent (inline template)', () => {
|
|||||||
comp = fixture.componentInstance;
|
comp = fixture.componentInstance;
|
||||||
|
|
||||||
endpointService = fixture.debugElement.injector.get(EndpointService);
|
endpointService = fixture.debugElement.injector.get(EndpointService);
|
||||||
spy = spyOn(endpointService, 'getEndpoint').and.returnValue(Promise.resolve(mockData));
|
spy = spyOn(endpointService, "getEndpoint").and.returnValue(
|
||||||
|
Promise.resolve(mockData)
|
||||||
|
);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
comp.openCreateEditTarget(true, 1);
|
comp.openCreateEditTarget(true, 1);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be created', () => {
|
it("should be created", () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(comp).toBeTruthy();
|
expect(comp).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get endpoint be called', async(() => {
|
it("should get endpoint be called", async(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@ -79,16 +83,16 @@ describe('CreateEditEndpointComponent (inline template)', () => {
|
|||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should get endpoint and open modal', async(() => {
|
it("should get endpoint and open modal", async(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(comp.target.name).toEqual('target_01');
|
expect(comp.target.name).toEqual("target_01");
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should endpoint be initialized', () => {
|
it("should endpoint be initialized", () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(config.systemInfoEndpoint).toEqual('/api/endpoints/testing');
|
expect(config.systemInfoEndpoint).toEqual("/api/endpoints/testing");
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -19,31 +19,27 @@ import {
|
|||||||
AfterViewChecked,
|
AfterViewChecked,
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
OnDestroy
|
OnDestroy
|
||||||
} from '@angular/core';
|
} from "@angular/core";
|
||||||
import { NgForm } from '@angular/forms';
|
import { NgForm } from "@angular/forms";
|
||||||
|
import { Subscription } from "rxjs/Subscription";
|
||||||
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
import { EndpointService } from '../service/endpoint.service';
|
import { EndpointService } from "../service/endpoint.service";
|
||||||
import { ErrorHandler } from '../error-handler/index';
|
import { ErrorHandler } from "../error-handler/index";
|
||||||
import { ActionType } from '../shared/shared.const';
|
import { InlineAlertComponent } from "../inline-alert/inline-alert.component";
|
||||||
|
import { Endpoint } from "../service/interface";
|
||||||
|
import { toPromise, clone, compareValue, isEmptyObject } from "../utils";
|
||||||
|
|
||||||
import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
|
|
||||||
|
|
||||||
import { Endpoint } from '../service/interface';
|
const FAKE_PASSWORD = "rjGcfuRu";
|
||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
import { toPromise, clone, compareValue, isEmptyObject } from '../utils';
|
|
||||||
|
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
|
||||||
|
|
||||||
const FAKE_PASSWORD = 'rjGcfuRu';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-create-edit-endpoint',
|
selector: "hbr-create-edit-endpoint",
|
||||||
templateUrl: './create-edit-endpoint.component.html',
|
templateUrl: "./create-edit-endpoint.component.html",
|
||||||
styleUrls: ['./create-edit-endpoint.component.scss']
|
styleUrls: ["./create-edit-endpoint.component.scss"]
|
||||||
})
|
})
|
||||||
export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy {
|
export class CreateEditEndpointComponent
|
||||||
|
implements AfterViewChecked, OnDestroy {
|
||||||
modalTitle: string;
|
modalTitle: string;
|
||||||
createEditDestinationOpened: boolean;
|
createEditDestinationOpened: boolean;
|
||||||
staticBackdrop: boolean = true;
|
staticBackdrop: boolean = true;
|
||||||
@ -54,15 +50,13 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
initVal: Endpoint;
|
initVal: Endpoint;
|
||||||
|
|
||||||
targetForm: NgForm;
|
targetForm: NgForm;
|
||||||
@ViewChild('targetForm')
|
@ViewChild("targetForm") currentForm: NgForm;
|
||||||
currentForm: NgForm;
|
|
||||||
|
|
||||||
testOngoing: boolean;
|
testOngoing: boolean;
|
||||||
onGoing: boolean;
|
onGoing: boolean;
|
||||||
endpointId: number | string;
|
endpointId: number | string;
|
||||||
|
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent) inlineAlert: InlineAlertComponent;
|
||||||
inlineAlert: InlineAlertComponent;
|
|
||||||
|
|
||||||
@Output() reload = new EventEmitter<boolean>();
|
@Output() reload = new EventEmitter<boolean>();
|
||||||
|
|
||||||
@ -78,12 +72,14 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
public get isValid(): boolean {
|
public get isValid(): boolean {
|
||||||
return !this.testOngoing &&
|
return (
|
||||||
|
!this.testOngoing &&
|
||||||
!this.onGoing &&
|
!this.onGoing &&
|
||||||
this.targetForm &&
|
this.targetForm &&
|
||||||
this.targetForm.valid &&
|
this.targetForm.valid &&
|
||||||
this.editable &&
|
this.editable &&
|
||||||
!compareValue(this.target, this.initVal);
|
!compareValue(this.target, this.initVal)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get inProgress(): boolean {
|
public get inProgress(): boolean {
|
||||||
@ -128,7 +124,7 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
this.target = this.initEndpoint();
|
this.target = this.initEndpoint();
|
||||||
this.initVal = this.initEndpoint();
|
this.initVal = this.initEndpoint();
|
||||||
this.formValues = null;
|
this.formValues = null;
|
||||||
this.endpointId = '';
|
this.endpointId = "";
|
||||||
|
|
||||||
this.inlineAlert.close();
|
this.inlineAlert.close();
|
||||||
}
|
}
|
||||||
@ -154,11 +150,11 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
this.reset();
|
this.reset();
|
||||||
if (targetId) {
|
if (targetId) {
|
||||||
this.endpointId = targetId;
|
this.endpointId = targetId;
|
||||||
this.translateService.get('DESTINATION.TITLE_EDIT').subscribe(res => this.modalTitle = res);
|
this.translateService
|
||||||
toPromise<Endpoint>(this.endpointService
|
.get("DESTINATION.TITLE_EDIT")
|
||||||
.getEndpoint(targetId))
|
.subscribe(res => (this.modalTitle = res));
|
||||||
.then(
|
toPromise<Endpoint>(this.endpointService.getEndpoint(targetId))
|
||||||
target => {
|
.then(target => {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
// Keep data cache
|
// Keep data cache
|
||||||
this.initVal = clone(target);
|
this.initVal = clone(target);
|
||||||
@ -171,8 +167,10 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
})
|
})
|
||||||
.catch(error => this.errorHandler.error(error));
|
.catch(error => this.errorHandler.error(error));
|
||||||
} else {
|
} else {
|
||||||
this.endpointId = '';
|
this.endpointId = "";
|
||||||
this.translateService.get('DESTINATION.TITLE_ADD').subscribe(res => this.modalTitle = res);
|
this.translateService
|
||||||
|
.get("DESTINATION.TITLE_ADD")
|
||||||
|
.subscribe(res => (this.modalTitle = res));
|
||||||
// Directly open the modal
|
// Directly open the modal
|
||||||
this.open();
|
this.open();
|
||||||
}
|
}
|
||||||
@ -187,7 +185,7 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
payload.insecure = this.target.insecure;
|
payload.insecure = this.target.insecure;
|
||||||
} else {
|
} else {
|
||||||
let changes: { [key: string]: any } = this.getChanges();
|
let changes: { [key: string]: any } = this.getChanges();
|
||||||
for (let prop in payload) {
|
for (let prop of Object.keys(payload)) {
|
||||||
delete payload[prop];
|
delete payload[prop];
|
||||||
}
|
}
|
||||||
payload.id = this.target.id;
|
payload.id = this.target.id;
|
||||||
@ -200,16 +198,16 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.testOngoing = true;
|
this.testOngoing = true;
|
||||||
toPromise<Endpoint>(this.endpointService
|
toPromise<Endpoint>(this.endpointService.pingEndpoint(payload))
|
||||||
.pingEndpoint(payload))
|
.then(response => {
|
||||||
.then(
|
this.inlineAlert.showInlineSuccess({
|
||||||
response => {
|
message: "DESTINATION.TEST_CONNECTION_SUCCESS"
|
||||||
this.inlineAlert.showInlineSuccess({ message: "DESTINATION.TEST_CONNECTION_SUCCESS" });
|
});
|
||||||
this.forceRefreshView(2000);
|
this.forceRefreshView(2000);
|
||||||
this.testOngoing = false;
|
this.testOngoing = false;
|
||||||
}).catch(
|
})
|
||||||
error => {
|
.catch(error => {
|
||||||
this.inlineAlert.showInlineError('DESTINATION.TEST_CONNECTION_FAILURE');
|
this.inlineAlert.showInlineError("DESTINATION.TEST_CONNECTION_FAILURE");
|
||||||
this.forceRefreshView(2000);
|
this.forceRefreshView(2000);
|
||||||
this.testOngoing = false;
|
this.testOngoing = false;
|
||||||
});
|
});
|
||||||
@ -229,27 +227,24 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.onGoing = true;
|
this.onGoing = true;
|
||||||
toPromise<number>(this.endpointService
|
toPromise<number>(this.endpointService.createEndpoint(this.target))
|
||||||
.createEndpoint(this.target))
|
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.translateService.get('DESTINATION.CREATED_SUCCESS')
|
this.translateService
|
||||||
|
.get("DESTINATION.CREATED_SUCCESS")
|
||||||
.subscribe(res => this.errorHandler.info(res));
|
.subscribe(res => this.errorHandler.info(res));
|
||||||
this.reload.emit(true);
|
this.reload.emit(true);
|
||||||
this.onGoing = false;
|
this.onGoing = false;
|
||||||
this.close();
|
this.close();
|
||||||
this.forceRefreshView(2000);
|
this.forceRefreshView(2000);
|
||||||
}).catch(error => {
|
})
|
||||||
|
.catch(error => {
|
||||||
this.onGoing = false;
|
this.onGoing = false;
|
||||||
let errorMessageKey = this.handleErrorMessageKey(error.status);
|
let errorMessageKey = this.handleErrorMessageKey(error.status);
|
||||||
this.translateService
|
this.translateService.get(errorMessageKey).subscribe(res => {
|
||||||
.get(errorMessageKey)
|
|
||||||
.subscribe(res => {
|
|
||||||
this.inlineAlert.showInlineError(res);
|
this.inlineAlert.showInlineError(res);
|
||||||
});
|
});
|
||||||
this.forceRefreshView(2000);
|
this.forceRefreshView(2000);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateEndpoint() {
|
updateEndpoint() {
|
||||||
@ -258,7 +253,7 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
}
|
}
|
||||||
|
|
||||||
let payload: Endpoint = this.initEndpoint();
|
let payload: Endpoint = this.initEndpoint();
|
||||||
for (let prop in payload) {
|
for (let prop of Object.keys(payload)) {
|
||||||
delete payload[prop];
|
delete payload[prop];
|
||||||
}
|
}
|
||||||
let changes: { [key: string]: any } = this.getChanges();
|
let changes: { [key: string]: any } = this.getChanges();
|
||||||
@ -271,50 +266,50 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
payload[key] = changes[key];
|
payload[key] = changes[key];
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!this.target.id) { return; }
|
if (!this.target.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.onGoing = true;
|
this.onGoing = true;
|
||||||
toPromise<number>(this.endpointService
|
toPromise<number>(
|
||||||
.updateEndpoint(this.target.id, payload))
|
this.endpointService.updateEndpoint(this.target.id, payload)
|
||||||
.then(
|
)
|
||||||
response => {
|
.then(response => {
|
||||||
this.translateService.get('DESTINATION.UPDATED_SUCCESS')
|
this.translateService
|
||||||
|
.get("DESTINATION.UPDATED_SUCCESS")
|
||||||
.subscribe(res => this.errorHandler.info(res));
|
.subscribe(res => this.errorHandler.info(res));
|
||||||
this.reload.emit(true);
|
this.reload.emit(true);
|
||||||
this.close();
|
this.close();
|
||||||
this.onGoing = false;
|
this.onGoing = false;
|
||||||
this.forceRefreshView(2000);
|
this.forceRefreshView(2000);
|
||||||
})
|
})
|
||||||
.catch(
|
.catch(error => {
|
||||||
error => {
|
|
||||||
let errorMessageKey = this.handleErrorMessageKey(error.status);
|
let errorMessageKey = this.handleErrorMessageKey(error.status);
|
||||||
this.translateService
|
this.translateService.get(errorMessageKey).subscribe(res => {
|
||||||
.get(errorMessageKey)
|
|
||||||
.subscribe(res => {
|
|
||||||
this.inlineAlert.showInlineError(res);
|
this.inlineAlert.showInlineError(res);
|
||||||
});
|
});
|
||||||
this.onGoing = false;
|
this.onGoing = false;
|
||||||
this.forceRefreshView(2000);
|
this.forceRefreshView(2000);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleErrorMessageKey(status: number): string {
|
handleErrorMessageKey(status: number): string {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 409:
|
case 409:
|
||||||
return 'DESTINATION.CONFLICT_NAME';
|
return "DESTINATION.CONFLICT_NAME";
|
||||||
case 400:
|
case 400:
|
||||||
return 'DESTINATION.INVALID_NAME';
|
return "DESTINATION.INVALID_NAME";
|
||||||
default:
|
default:
|
||||||
return 'UNKNOWN_ERROR';
|
return "UNKNOWN_ERROR";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onCancel() {
|
onCancel() {
|
||||||
let changes: { [key: string]: any } = this.getChanges();
|
let changes: { [key: string]: any } = this.getChanges();
|
||||||
if (!isEmptyObject(changes)) {
|
if (!isEmptyObject(changes)) {
|
||||||
this.inlineAlert.showInlineConfirmation({ message: 'ALERT.FORM_CHANGE_CONFIRMATION' });
|
this.inlineAlert.showInlineConfirmation({
|
||||||
|
message: "ALERT.FORM_CHANGE_CONFIRMATION"
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.close();
|
this.close();
|
||||||
if (this.targetForm) {
|
if (this.targetForm) {
|
||||||
@ -329,10 +324,11 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewChecked(): void {
|
ngAfterViewChecked(): void {
|
||||||
if (this.targetForm != this.currentForm) {
|
if (this.targetForm !== this.currentForm) {
|
||||||
this.targetForm = this.currentForm;
|
this.targetForm = this.currentForm;
|
||||||
if (this.targetForm) {
|
if (this.targetForm) {
|
||||||
this.valueChangesSub = this.targetForm.valueChanges.subscribe((data: { [key: string]: string } | any) => {
|
this.valueChangesSub = this.targetForm.valueChanges.subscribe(
|
||||||
|
(data: { [key: string]: string } | any) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
// To avoid invalid change publish events
|
// To avoid invalid change publish events
|
||||||
let keyNumber: number = 0;
|
let keyNumber: number = 0;
|
||||||
@ -351,7 +347,8 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
this.inlineAlert.close();
|
this.inlineAlert.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -360,7 +357,7 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
if (!this.target || !this.initVal) {
|
if (!this.target || !this.initVal) {
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
for (let prop in this.target) {
|
for (let prop of Object.keys(this.target)) {
|
||||||
let field: any = this.initVal[prop];
|
let field: any = this.initVal[prop];
|
||||||
if (!compareValue(field, this.target[prop])) {
|
if (!compareValue(field, this.target[prop])) {
|
||||||
changes[prop] = this.target[prop];
|
changes[prop] = this.target[prop];
|
||||||
@ -371,12 +368,11 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
|||||||
|
|
||||||
// Trim string value
|
// Trim string value
|
||||||
if (typeof field === "string") {
|
if (typeof field === "string") {
|
||||||
changes[prop] = ('' + changes[prop]).trim();
|
changes[prop] = ("" + changes[prop]).trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,16 @@
|
|||||||
|
import { ComponentFixture, TestBed, async } from "@angular/core/testing";
|
||||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
|
||||||
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
import { SharedModule } from '../shared/shared.module';
|
|
||||||
|
|
||||||
import { FilterComponent } from '../filter/filter.component';
|
import { SharedModule } from "../shared/shared.module";
|
||||||
|
import { FilterComponent } from "../filter/filter.component";
|
||||||
import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
|
import { InlineAlertComponent } from "../inline-alert/inline-alert.component";
|
||||||
import { ErrorHandler } from '../error-handler/error-handler';
|
import { ErrorHandler } from "../error-handler/error-handler";
|
||||||
import {Label} from '../service/interface';
|
import { Label } from "../service/interface";
|
||||||
import { IServiceConfig, SERVICE_CONFIG } from '../service.config';
|
import { IServiceConfig, SERVICE_CONFIG } from "../service.config";
|
||||||
import { CreateEditLabelComponent } from "./create-edit-label.component";
|
import { CreateEditLabelComponent } from "./create-edit-label.component";
|
||||||
import { LabelDefaultService, LabelService } from "../service/label.service";
|
import { LabelDefaultService, LabelService } from "../service/label.service";
|
||||||
|
|
||||||
describe('CreateEditLabelComponent (inline template)', () => {
|
describe("CreateEditLabelComponent (inline template)", () => {
|
||||||
|
|
||||||
let mockOneData: Label = {
|
let mockOneData: Label = {
|
||||||
color: "#9b0d54",
|
color: "#9b0d54",
|
||||||
creation_time: "",
|
creation_time: "",
|
||||||
@ -22,14 +19,14 @@ describe('CreateEditLabelComponent (inline template)', () => {
|
|||||||
name: "label0-g",
|
name: "label0-g",
|
||||||
project_id: 0,
|
project_id: 0,
|
||||||
scope: "g",
|
scope: "g",
|
||||||
update_time: "",
|
update_time: ""
|
||||||
}
|
};
|
||||||
|
|
||||||
let comp: CreateEditLabelComponent;
|
let comp: CreateEditLabelComponent;
|
||||||
let fixture: ComponentFixture<CreateEditLabelComponent>;
|
let fixture: ComponentFixture<CreateEditLabelComponent>;
|
||||||
|
|
||||||
let config: IServiceConfig = {
|
let config: IServiceConfig = {
|
||||||
systemInfoEndpoint: '/api/label/testing'
|
systemInfoEndpoint: "/api/label/testing"
|
||||||
};
|
};
|
||||||
|
|
||||||
let labelService: LabelService;
|
let labelService: LabelService;
|
||||||
@ -39,14 +36,12 @@ describe('CreateEditLabelComponent (inline template)', () => {
|
|||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [SharedModule, NoopAnimationsModule],
|
||||||
SharedModule,
|
|
||||||
NoopAnimationsModule
|
|
||||||
],
|
|
||||||
declarations: [
|
declarations: [
|
||||||
FilterComponent,
|
FilterComponent,
|
||||||
CreateEditLabelComponent,
|
CreateEditLabelComponent,
|
||||||
InlineAlertComponent ],
|
InlineAlertComponent
|
||||||
|
],
|
||||||
providers: [
|
providers: [
|
||||||
ErrorHandler,
|
ErrorHandler,
|
||||||
{ provide: SERVICE_CONFIG, useValue: config },
|
{ provide: SERVICE_CONFIG, useValue: config },
|
||||||
@ -61,8 +56,12 @@ describe('CreateEditLabelComponent (inline template)', () => {
|
|||||||
|
|
||||||
labelService = fixture.debugElement.injector.get(LabelService);
|
labelService = fixture.debugElement.injector.get(LabelService);
|
||||||
|
|
||||||
spy = spyOn(labelService, 'getLabels').and.returnValue(Promise.resolve(mockOneData));
|
spy = spyOn(labelService, "getLabels").and.returnValue(
|
||||||
spyOne = spyOn(labelService, 'createLabel').and.returnValue(Promise.resolve(mockOneData));
|
Promise.resolve(mockOneData)
|
||||||
|
);
|
||||||
|
spyOne = spyOn(labelService, "createLabel").and.returnValue(
|
||||||
|
Promise.resolve(mockOneData)
|
||||||
|
);
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
@ -70,16 +69,16 @@ describe('CreateEditLabelComponent (inline template)', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be created', () => {
|
it("should be created", () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(comp).toBeTruthy();
|
expect(comp).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get label and open modal', async(() => {
|
it("should get label and open modal", async(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(comp.labelModel.name).toEqual('');
|
expect(comp.labelModel.name).toEqual("");
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
@ -16,12 +16,16 @@ import {
|
|||||||
Output,
|
Output,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
Input, OnInit, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef
|
Input,
|
||||||
} from '@angular/core';
|
OnInit,
|
||||||
|
ViewChild,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorRef
|
||||||
|
} from "@angular/core";
|
||||||
|
|
||||||
import {Label} from '../service/interface';
|
import { Label } from "../service/interface";
|
||||||
|
|
||||||
import {toPromise, clone, compareValue} from '../utils';
|
import { toPromise, clone, compareValue } from "../utils";
|
||||||
|
|
||||||
import { LabelService } from "../service/label.service";
|
import { LabelService } from "../service/label.service";
|
||||||
import { ErrorHandler } from "../error-handler/error-handler";
|
import { ErrorHandler } from "../error-handler/error-handler";
|
||||||
@ -30,12 +34,11 @@ import {Subject} from "rxjs/Subject";
|
|||||||
import { LabelColor } from "../shared/shared.const";
|
import { LabelColor } from "../shared/shared.const";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-create-edit-label',
|
selector: "hbr-create-edit-label",
|
||||||
templateUrl: './create-edit-label.component.html',
|
templateUrl: "./create-edit-label.component.html",
|
||||||
styleUrls: ['./create-edit-label.component.scss'],
|
styleUrls: ["./create-edit-label.component.scss"],
|
||||||
changeDetection: ChangeDetectionStrategy.Default
|
changeDetection: ChangeDetectionStrategy.Default
|
||||||
})
|
})
|
||||||
|
|
||||||
export class CreateEditLabelComponent implements OnInit, OnDestroy {
|
export class CreateEditLabelComponent implements OnInit, OnDestroy {
|
||||||
formShow: boolean;
|
formShow: boolean;
|
||||||
inProgress: boolean;
|
inProgress: boolean;
|
||||||
@ -50,8 +53,7 @@ export class CreateEditLabelComponent implements OnInit, OnDestroy {
|
|||||||
nameChecker = new Subject<string>();
|
nameChecker = new Subject<string>();
|
||||||
|
|
||||||
labelForm: NgForm;
|
labelForm: NgForm;
|
||||||
@ViewChild('labelForm')
|
@ViewChild("labelForm") currentForm: NgForm;
|
||||||
currentForm: NgForm;
|
|
||||||
|
|
||||||
@Input() projectId: number;
|
@Input() projectId: number;
|
||||||
@Input() scope: string;
|
@Input() scope: string;
|
||||||
@ -66,8 +68,10 @@ export class CreateEditLabelComponent implements OnInit, OnDestroy {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.nameChecker.debounceTime(500).subscribe((name: string) => {
|
this.nameChecker.debounceTime(500).subscribe((name: string) => {
|
||||||
this.checkOnGoing = true;
|
this.checkOnGoing = true;
|
||||||
let labelName = this.currentForm.controls['name'].value;
|
let labelName = this.currentForm.controls["name"].value;
|
||||||
toPromise<Label[]>(this.labelService.getLabels(this.scope, this.projectId, labelName))
|
toPromise<Label[]>(
|
||||||
|
this.labelService.getLabels(this.scope, this.projectId, labelName)
|
||||||
|
)
|
||||||
.then(targets => {
|
.then(targets => {
|
||||||
if (targets && targets.length) {
|
if (targets && targets.length) {
|
||||||
this.isLabelNameExist = true;
|
this.isLabelNameExist = true;
|
||||||
@ -75,9 +79,10 @@ export class CreateEditLabelComponent implements OnInit, OnDestroy {
|
|||||||
this.isLabelNameExist = false;
|
this.isLabelNameExist = false;
|
||||||
}
|
}
|
||||||
this.checkOnGoing = false;
|
this.checkOnGoing = false;
|
||||||
}).catch(error => {
|
})
|
||||||
|
.catch(error => {
|
||||||
this.checkOnGoing = false;
|
this.checkOnGoing = false;
|
||||||
this.errorHandler.error(error)
|
this.errorHandler.error(error);
|
||||||
});
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setInterval(() => this.ref.markForCheck(), 100);
|
setInterval(() => this.ref.markForCheck(), 100);
|
||||||
@ -95,10 +100,10 @@ export class CreateEditLabelComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
initLabel(): Label {
|
initLabel(): Label {
|
||||||
return {
|
return {
|
||||||
name: '',
|
name: "",
|
||||||
description: '',
|
description: "",
|
||||||
color: '',
|
color: "",
|
||||||
scope: '',
|
scope: "",
|
||||||
project_id: 0
|
project_id: 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -129,7 +134,13 @@ export class CreateEditLabelComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get isValid(): boolean {
|
public get isValid(): boolean {
|
||||||
return !(this.checkOnGoing || this.isLabelNameExist || !(this.currentForm && this.currentForm.valid) || !this.hasChanged || this.inProgress);
|
return !(
|
||||||
|
this.checkOnGoing ||
|
||||||
|
this.isLabelNameExist ||
|
||||||
|
!(this.currentForm && this.currentForm.valid) ||
|
||||||
|
!this.hasChanged ||
|
||||||
|
this.inProgress
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
existValid(text: string): void {
|
existValid(text: string): void {
|
||||||
@ -148,22 +159,25 @@ export class CreateEditLabelComponent implements OnInit, OnDestroy {
|
|||||||
this.inProgress = false;
|
this.inProgress = false;
|
||||||
this.reload.emit();
|
this.reload.emit();
|
||||||
this.labelModel = this.initLabel();
|
this.labelModel = this.initLabel();
|
||||||
}).catch(err => {
|
})
|
||||||
|
.catch(err => {
|
||||||
this.inProgress = false;
|
this.inProgress = false;
|
||||||
this.errorHandler.error(err)
|
this.errorHandler.error(err);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
toPromise<Label>(this.labelService.updateLabel(this.labelId, this.labelModel))
|
toPromise<Label>(
|
||||||
|
this.labelService.updateLabel(this.labelId, this.labelModel)
|
||||||
|
)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
this.inProgress = false;
|
this.inProgress = false;
|
||||||
this.reload.emit();
|
this.reload.emit();
|
||||||
this.labelModel = this.initLabel();
|
this.labelModel = this.initLabel();
|
||||||
}).catch(err => {
|
})
|
||||||
|
.catch(err => {
|
||||||
this.inProgress = false;
|
this.inProgress = false;
|
||||||
this.errorHandler.error(err)
|
this.errorHandler.error(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onCancel(): void {
|
onCancel(): void {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Type } from '@angular/core';
|
import { Type } from "@angular/core";
|
||||||
import { CreateEditLabelComponent } from "./create-edit-label.component";
|
import { CreateEditLabelComponent } from "./create-edit-label.component";
|
||||||
|
|
||||||
export const CREATE_EDIT_LABEL_DIRECTIVES: Type<any>[] = [
|
export const CREATE_EDIT_LABEL_DIRECTIVES: Type<any>[] = [
|
||||||
|
@ -1,103 +1,117 @@
|
|||||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
import { ComponentFixture, TestBed, async } from "@angular/core/testing";
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from "@angular/platform-browser";
|
||||||
import { DebugElement } from '@angular/core';
|
import { DebugElement } from "@angular/core";
|
||||||
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
|
|
||||||
import { SharedModule } from '../shared/shared.module';
|
import { SharedModule } from "../shared/shared.module";
|
||||||
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation-dialog.component";
|
||||||
import { ReplicationComponent } from '../replication/replication.component';
|
import { ReplicationComponent } from "../replication/replication.component";
|
||||||
|
|
||||||
import { ListReplicationRuleComponent } from '../list-replication-rule/list-replication-rule.component';
|
import { ListReplicationRuleComponent } from "../list-replication-rule/list-replication-rule.component";
|
||||||
|
|
||||||
import { CreateEditRuleComponent } from './create-edit-rule.component';
|
import { CreateEditRuleComponent } from "./create-edit-rule.component";
|
||||||
import { DatePickerComponent } from '../datetime-picker/datetime-picker.component';
|
import { DatePickerComponent } from "../datetime-picker/datetime-picker.component";
|
||||||
import { DateValidatorDirective } from '../datetime-picker/date-validator.directive';
|
import { FilterComponent } from "../filter/filter.component";
|
||||||
import { FilterComponent } from '../filter/filter.component';
|
import { InlineAlertComponent } from "../inline-alert/inline-alert.component";
|
||||||
import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
|
import {
|
||||||
import { ReplicationRule, ReplicationJob, Endpoint, ReplicationJobItem } from '../service/interface';
|
ReplicationRule,
|
||||||
|
ReplicationJob,
|
||||||
|
Endpoint,
|
||||||
|
ReplicationJobItem
|
||||||
|
} from "../service/interface";
|
||||||
|
|
||||||
import { ErrorHandler } from '../error-handler/error-handler';
|
import { ErrorHandler } from "../error-handler/error-handler";
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import { SERVICE_CONFIG, IServiceConfig } from "../service.config";
|
||||||
import {
|
import {
|
||||||
ReplicationService,
|
ReplicationService,
|
||||||
ReplicationDefaultService,
|
ReplicationDefaultService,
|
||||||
JobLogService,
|
JobLogService,
|
||||||
JobLogDefaultService
|
JobLogDefaultService
|
||||||
} from '../service/index';
|
} from "../service/index";
|
||||||
import { EndpointService, EndpointDefaultService } from '../service/endpoint.service';
|
import {
|
||||||
import {ProjectDefaultService, ProjectService} from "../service/project.service";
|
EndpointService,
|
||||||
import { JobLogViewerComponent } from '../job-log-viewer/job-log-viewer.component';
|
EndpointDefaultService
|
||||||
import {Project} from "../project-policy-config/project";
|
} from "../service/endpoint.service";
|
||||||
|
import {
|
||||||
describe('CreateEditRuleComponent (inline template)', ()=>{
|
ProjectDefaultService,
|
||||||
|
ProjectService
|
||||||
|
} from "../service/project.service";
|
||||||
|
import { JobLogViewerComponent } from "../job-log-viewer/job-log-viewer.component";
|
||||||
|
|
||||||
|
describe("CreateEditRuleComponent (inline template)", () => {
|
||||||
let mockRules: ReplicationRule[] = [
|
let mockRules: ReplicationRule[] = [
|
||||||
{
|
{
|
||||||
"id": 1,
|
id: 1,
|
||||||
"name": "sync_01",
|
name: "sync_01",
|
||||||
"description": "",
|
description: "",
|
||||||
"projects": [{ "project_id": 1,
|
projects: [
|
||||||
"owner_id": 0,
|
{
|
||||||
"name": 'project_01',
|
project_id: 1,
|
||||||
"creation_time": '',
|
owner_id: 0,
|
||||||
"deleted": 0,
|
name: "project_01",
|
||||||
"owner_name": '',
|
creation_time: "",
|
||||||
"togglable": false,
|
deleted: 0,
|
||||||
"update_time": '',
|
owner_name: "",
|
||||||
"current_user_role_id": 0,
|
togglable: false,
|
||||||
"repo_count": 0,
|
update_time: "",
|
||||||
"has_project_admin_role": false,
|
current_user_role_id: 0,
|
||||||
"is_member": false,
|
repo_count: 0,
|
||||||
"role_name": '',
|
has_project_admin_role: false,
|
||||||
"metadata": {
|
is_member: false,
|
||||||
"public": '',
|
role_name: "",
|
||||||
"enable_content_trust": '',
|
metadata: {
|
||||||
"prevent_vul": '',
|
public: "",
|
||||||
"severity": '',
|
enable_content_trust: "",
|
||||||
"auto_scan": '',
|
prevent_vul: "",
|
||||||
|
severity: "",
|
||||||
|
auto_scan: ""
|
||||||
}
|
}
|
||||||
}],
|
}
|
||||||
"targets": [{
|
],
|
||||||
"id": 1,
|
targets: [
|
||||||
"endpoint": "https://10.117.4.151",
|
{
|
||||||
"name": "target_01",
|
id: 1,
|
||||||
"username": "admin",
|
endpoint: "https://10.117.4.151",
|
||||||
"password": "",
|
name: "target_01",
|
||||||
"insecure": false,
|
username: "admin",
|
||||||
"type": 0
|
password: "",
|
||||||
}],
|
insecure: false,
|
||||||
"trigger": {
|
type: 0
|
||||||
"kind": "Manual",
|
}
|
||||||
"schedule_param": null
|
],
|
||||||
|
trigger: {
|
||||||
|
kind: "Manual",
|
||||||
|
schedule_param: null
|
||||||
},
|
},
|
||||||
"filters": [],
|
filters: [],
|
||||||
"replicate_existing_image_now": false,
|
replicate_existing_image_now: false,
|
||||||
"replicate_deletion": false,
|
replicate_deletion: false
|
||||||
}]
|
}
|
||||||
|
];
|
||||||
let mockJobs: ReplicationJobItem[] = [
|
let mockJobs: ReplicationJobItem[] = [
|
||||||
{
|
{
|
||||||
"id": 1,
|
id: 1,
|
||||||
"status": "stopped",
|
status: "stopped",
|
||||||
"repository": "library/busybox",
|
repository: "library/busybox",
|
||||||
"policy_id": 1,
|
policy_id: 1,
|
||||||
"operation": "transfer",
|
operation: "transfer",
|
||||||
"tags": null
|
tags: null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
id: 2,
|
||||||
"status": "stopped",
|
status: "stopped",
|
||||||
"repository": "library/busybox",
|
repository: "library/busybox",
|
||||||
"policy_id": 1,
|
policy_id: 1,
|
||||||
"operation": "transfer",
|
operation: "transfer",
|
||||||
"tags": null
|
tags: null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
id: 3,
|
||||||
"status": "stopped",
|
status: "stopped",
|
||||||
"repository": "library/busybox",
|
repository: "library/busybox",
|
||||||
"policy_id": 2,
|
policy_id: 2,
|
||||||
"operation": "transfer",
|
operation: "transfer",
|
||||||
"tags": null
|
tags: null
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -108,107 +122,90 @@ describe('CreateEditRuleComponent (inline template)', ()=>{
|
|||||||
|
|
||||||
let mockEndpoints: Endpoint[] = [
|
let mockEndpoints: Endpoint[] = [
|
||||||
{
|
{
|
||||||
"id": 1,
|
id: 1,
|
||||||
"endpoint": "https://10.117.4.151",
|
endpoint: "https://10.117.4.151",
|
||||||
"name": "target_01",
|
name: "target_01",
|
||||||
"username": "admin",
|
username: "admin",
|
||||||
"password": "",
|
password: "",
|
||||||
"insecure": false,
|
insecure: false,
|
||||||
"type": 0
|
type: 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
id: 2,
|
||||||
"endpoint": "https://10.117.5.142",
|
endpoint: "https://10.117.5.142",
|
||||||
"name": "target_02",
|
name: "target_02",
|
||||||
"username": "AAA",
|
username: "AAA",
|
||||||
"password": "",
|
password: "",
|
||||||
"insecure": false,
|
insecure: false,
|
||||||
"type": 0
|
type: 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
id: 3,
|
||||||
"endpoint": "https://101.1.11.111",
|
endpoint: "https://101.1.11.111",
|
||||||
"name": "target_03",
|
name: "target_03",
|
||||||
"username": "admin",
|
username: "admin",
|
||||||
"password": "",
|
password: "",
|
||||||
"insecure": false,
|
insecure: false,
|
||||||
"type": 0
|
type: 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 4,
|
id: 4,
|
||||||
"endpoint": "http://4.4.4.4",
|
endpoint: "http://4.4.4.4",
|
||||||
"name": "target_04",
|
name: "target_04",
|
||||||
"username": "",
|
username: "",
|
||||||
"password": "",
|
password: "",
|
||||||
"insecure": true,
|
insecure: true,
|
||||||
"type": 0
|
type: 0
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
let mockRule: ReplicationRule = {
|
let mockRule: ReplicationRule = {
|
||||||
"id": 1,
|
id: 1,
|
||||||
"name": "sync_01",
|
name: "sync_01",
|
||||||
"description": "",
|
description: "",
|
||||||
"projects": [{ "project_id": 1,
|
projects: [
|
||||||
"owner_id": 0,
|
{
|
||||||
"name": 'project_01',
|
project_id: 1,
|
||||||
"creation_time": '',
|
owner_id: 0,
|
||||||
"deleted": 0,
|
name: "project_01",
|
||||||
"owner_name": '',
|
creation_time: "",
|
||||||
"togglable": false,
|
deleted: 0,
|
||||||
"update_time": '',
|
owner_name: "",
|
||||||
"current_user_role_id": 0,
|
togglable: false,
|
||||||
"repo_count": 0,
|
update_time: "",
|
||||||
"has_project_admin_role": false,
|
current_user_role_id: 0,
|
||||||
"is_member": false,
|
repo_count: 0,
|
||||||
"role_name": '',
|
has_project_admin_role: false,
|
||||||
"metadata": {
|
is_member: false,
|
||||||
"public": '',
|
role_name: "",
|
||||||
"enable_content_trust": '',
|
metadata: {
|
||||||
"prevent_vul": '',
|
public: "",
|
||||||
"severity": '',
|
enable_content_trust: "",
|
||||||
"auto_scan": '',
|
prevent_vul: "",
|
||||||
|
severity: "",
|
||||||
|
auto_scan: ""
|
||||||
}
|
}
|
||||||
}],
|
}
|
||||||
"targets": [{
|
],
|
||||||
"id": 1,
|
targets: [
|
||||||
"endpoint": "https://10.117.4.151",
|
{
|
||||||
"name": "target_01",
|
id: 1,
|
||||||
"username": "admin",
|
endpoint: "https://10.117.4.151",
|
||||||
"password": "",
|
name: "target_01",
|
||||||
"insecure": false,
|
username: "admin",
|
||||||
"type": 0
|
password: "",
|
||||||
}],
|
insecure: false,
|
||||||
"trigger": {
|
type: 0
|
||||||
"kind": "Manual",
|
}
|
||||||
"schedule_param": null
|
],
|
||||||
|
trigger: {
|
||||||
|
kind: "Manual",
|
||||||
|
schedule_param: null
|
||||||
},
|
},
|
||||||
"filters": [],
|
filters: [],
|
||||||
"replicate_existing_image_now": false,
|
replicate_existing_image_now: false,
|
||||||
"replicate_deletion": false,
|
replicate_deletion: false
|
||||||
}
|
};
|
||||||
let mockProjects: Project[] = [
|
|
||||||
{ "project_id": 1,
|
|
||||||
"owner_id": 0,
|
|
||||||
"name": 'project_01',
|
|
||||||
"creation_time": '',
|
|
||||||
"deleted": 0,
|
|
||||||
"owner_name": '',
|
|
||||||
"togglable": false,
|
|
||||||
"update_time": '',
|
|
||||||
"current_user_role_id": 0,
|
|
||||||
"repo_count": 0,
|
|
||||||
"has_project_admin_role": false,
|
|
||||||
"is_member": false,
|
|
||||||
"role_name": '',
|
|
||||||
"metadata": {
|
|
||||||
"public": '',
|
|
||||||
"enable_content_trust": '',
|
|
||||||
"prevent_vul": '',
|
|
||||||
"severity": '',
|
|
||||||
"auto_scan": '',
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
|
|
||||||
let fixture: ComponentFixture<ReplicationComponent>;
|
let fixture: ComponentFixture<ReplicationComponent>;
|
||||||
let fixtureCreate: ComponentFixture<CreateEditRuleComponent>;
|
let fixtureCreate: ComponentFixture<CreateEditRuleComponent>;
|
||||||
@ -226,16 +223,13 @@ describe('CreateEditRuleComponent (inline template)', ()=>{
|
|||||||
let spyEndpoint: jasmine.Spy;
|
let spyEndpoint: jasmine.Spy;
|
||||||
|
|
||||||
let config: IServiceConfig = {
|
let config: IServiceConfig = {
|
||||||
replicationJobEndpoint: '/api/jobs/replication/testing',
|
replicationJobEndpoint: "/api/jobs/replication/testing",
|
||||||
targetBaseEndpoint: '/api/targets/testing'
|
targetBaseEndpoint: "/api/targets/testing"
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [SharedModule, NoopAnimationsModule],
|
||||||
SharedModule,
|
|
||||||
NoopAnimationsModule
|
|
||||||
],
|
|
||||||
declarations: [
|
declarations: [
|
||||||
ReplicationComponent,
|
ReplicationComponent,
|
||||||
ListReplicationRuleComponent,
|
ListReplicationRuleComponent,
|
||||||
@ -267,47 +261,53 @@ describe('CreateEditRuleComponent (inline template)', ()=>{
|
|||||||
|
|
||||||
replicationService = fixture.debugElement.injector.get(ReplicationService);
|
replicationService = fixture.debugElement.injector.get(ReplicationService);
|
||||||
|
|
||||||
|
|
||||||
endpointService = fixtureCreate.debugElement.injector.get(EndpointService);
|
endpointService = fixtureCreate.debugElement.injector.get(EndpointService);
|
||||||
|
|
||||||
spyRules = spyOn(replicationService, 'getReplicationRules').and.returnValues(Promise.resolve(mockRules));
|
spyRules = spyOn(
|
||||||
spyOneRule = spyOn(replicationService, 'getReplicationRule').and.returnValue(Promise.resolve(mockRule));
|
replicationService,
|
||||||
spyJobs = spyOn(replicationService, 'getJobs').and.returnValues(Promise.resolve(mockJob));
|
"getReplicationRules"
|
||||||
|
).and.returnValues(Promise.resolve(mockRules));
|
||||||
|
spyOneRule = spyOn(
|
||||||
|
replicationService,
|
||||||
|
"getReplicationRule"
|
||||||
|
).and.returnValue(Promise.resolve(mockRule));
|
||||||
|
spyJobs = spyOn(replicationService, "getJobs").and.returnValues(
|
||||||
|
Promise.resolve(mockJob)
|
||||||
|
);
|
||||||
|
|
||||||
|
spyEndpoint = spyOn(endpointService, "getEndpoints").and.returnValues(
|
||||||
spyEndpoint = spyOn(endpointService, 'getEndpoints').and.returnValues(Promise.resolve(mockEndpoints));
|
Promise.resolve(mockEndpoints)
|
||||||
|
);
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should open creation modal and load endpoints', async(()=>{
|
it("Should open creation modal and load endpoints", async(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
compCreate.openCreateEditRule();
|
compCreate.openCreateEditRule();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let de: DebugElement = fixture.debugElement.query(By.css('input'));
|
let de: DebugElement = fixture.debugElement.query(By.css("input"));
|
||||||
expect(de).toBeTruthy();
|
expect(de).toBeTruthy();
|
||||||
let deSelect: DebugElement = fixture.debugElement.query(By.css('select'));
|
let deSelect: DebugElement = fixture.debugElement.query(By.css("select"));
|
||||||
expect(deSelect).toBeTruthy();
|
expect(deSelect).toBeTruthy();
|
||||||
let elSelect: HTMLElement = de.nativeElement;
|
let elSelect: HTMLElement = de.nativeElement;
|
||||||
expect(elSelect).toBeTruthy();
|
expect(elSelect).toBeTruthy();
|
||||||
expect(elSelect.childNodes.item(0).textContent).toEqual('target_01');
|
expect(elSelect.childNodes.item(0).textContent).toEqual("target_01");
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('Should open modal to edit replication rule', async(()=>{
|
it("Should open modal to edit replication rule", async(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
compCreate.openCreateEditRule(mockRule.id);
|
compCreate.openCreateEditRule(mockRule.id);
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let de: DebugElement = fixture.debugElement.query(By.css('input'));
|
let de: DebugElement = fixture.debugElement.query(By.css("input"));
|
||||||
expect(de).toBeTruthy();
|
expect(de).toBeTruthy();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let el: HTMLElement = de.nativeElement;
|
let el: HTMLElement = de.nativeElement;
|
||||||
expect(el).toBeTruthy();
|
expect(el).toBeTruthy();
|
||||||
expect(el.textContent.trim()).toEqual('sync_01');
|
expect(el.textContent.trim()).toEqual("sync_01");
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
@ -11,15 +11,22 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import {Component, OnInit, OnDestroy, ViewChild, ChangeDetectorRef, Input, EventEmitter, Output} from '@angular/core';
|
import {
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
OnDestroy,
|
||||||
|
ViewChild,
|
||||||
|
ChangeDetectorRef,
|
||||||
|
Input,
|
||||||
|
EventEmitter,
|
||||||
|
Output
|
||||||
|
} from "@angular/core";
|
||||||
import { Filter, ReplicationRule, Endpoint } from "../service/interface";
|
import { Filter, ReplicationRule, Endpoint } from "../service/interface";
|
||||||
import { Subject } from "rxjs/Subject";
|
import { Subject } from "rxjs/Subject";
|
||||||
import { Subscription } from "rxjs/Subscription";
|
import { Subscription } from "rxjs/Subscription";
|
||||||
import { FormArray, FormBuilder, FormGroup, Validators } from "@angular/forms";
|
import { FormArray, FormBuilder, FormGroup, Validators } from "@angular/forms";
|
||||||
import {CreateEditEndpointComponent} from "../create-edit-endpoint/create-edit-endpoint.component";
|
|
||||||
import {Router, ActivatedRoute} from "@angular/router";
|
|
||||||
import { compareValue, isEmptyObject, toPromise } from "../utils";
|
import { compareValue, isEmptyObject, toPromise } from "../utils";
|
||||||
import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
|
import { InlineAlertComponent } from "../inline-alert/inline-alert.component";
|
||||||
import { ReplicationService } from "../service/replication.service";
|
import { ReplicationService } from "../service/replication.service";
|
||||||
import { ErrorHandler } from "../error-handler/error-handler";
|
import { ErrorHandler } from "../error-handler/error-handler";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
@ -31,12 +38,10 @@ const ONE_HOUR_SECONDS = 3600;
|
|||||||
const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS;
|
const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-create-edit-rule',
|
selector: "hbr-create-edit-rule",
|
||||||
templateUrl: './create-edit-rule.component.html',
|
templateUrl: "./create-edit-rule.component.html",
|
||||||
styleUrls: ['./create-edit-rule.component.scss']
|
styleUrls: ["./create-edit-rule.component.scss"]
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||||
_localTime: Date = new Date();
|
_localTime: Date = new Date();
|
||||||
targetList: Endpoint[] = [];
|
targetList: Endpoint[] = [];
|
||||||
@ -51,12 +56,20 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
noSelectedProject = true;
|
noSelectedProject = true;
|
||||||
noSelectedEndpoint = true;
|
noSelectedEndpoint = true;
|
||||||
filterCount = 0;
|
filterCount = 0;
|
||||||
triggerNames: string[] = ['Manual', 'Immediate', 'Scheduled'];
|
triggerNames: string[] = ["Manual", "Immediate", "Scheduled"];
|
||||||
scheduleNames: string[] = ['Daily', 'Weekly'];
|
scheduleNames: string[] = ["Daily", "Weekly"];
|
||||||
weekly: string[] = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
|
weekly: string[] = [
|
||||||
filterSelect: string[] = ['repository', 'tag'];
|
"Monday",
|
||||||
ruleNameTooltip = 'TOOLTIP.EMPTY';
|
"Tuesday",
|
||||||
headerTitle = 'REPLICATION.ADD_POLICY';
|
"Wednesday",
|
||||||
|
"Thursday",
|
||||||
|
"Friday",
|
||||||
|
"Saturday",
|
||||||
|
"Sunday"
|
||||||
|
];
|
||||||
|
filterSelect: string[] = ["repository", "tag"];
|
||||||
|
ruleNameTooltip = "TOOLTIP.EMPTY";
|
||||||
|
headerTitle = "REPLICATION.ADD_POLICY";
|
||||||
|
|
||||||
createEditRuleOpened: boolean;
|
createEditRuleOpened: boolean;
|
||||||
filterListData: { [key: string]: any }[] = [];
|
filterListData: { [key: string]: any }[] = [];
|
||||||
@ -78,22 +91,21 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
@Output() goToRegistry = new EventEmitter<any>();
|
@Output() goToRegistry = new EventEmitter<any>();
|
||||||
@Output() reload = new EventEmitter<boolean>();
|
@Output() reload = new EventEmitter<boolean>();
|
||||||
|
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent) inlineAlert: InlineAlertComponent;
|
||||||
inlineAlert: InlineAlertComponent;
|
|
||||||
|
|
||||||
emptyProject = {
|
emptyProject = {
|
||||||
project_id: -1,
|
project_id: -1,
|
||||||
name: '',
|
name: ""
|
||||||
}
|
};
|
||||||
emptyEndpoint = {
|
emptyEndpoint = {
|
||||||
id: -1,
|
id: -1,
|
||||||
endpoint: '',
|
endpoint: "",
|
||||||
name: '',
|
name: "",
|
||||||
username: '',
|
username: "",
|
||||||
password: '',
|
password: "",
|
||||||
insecure: true,
|
insecure: true,
|
||||||
type: 0,
|
type: 0
|
||||||
}
|
};
|
||||||
constructor(
|
constructor(
|
||||||
private fb: FormBuilder,
|
private fb: FormBuilder,
|
||||||
private repService: ReplicationService,
|
private repService: ReplicationService,
|
||||||
@ -101,7 +113,8 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
private errorHandler: ErrorHandler,
|
private errorHandler: ErrorHandler,
|
||||||
private proService: ProjectService,
|
private proService: ProjectService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
public ref: ChangeDetectorRef) {
|
public ref: ChangeDetectorRef
|
||||||
|
) {
|
||||||
this.createForm();
|
this.createForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,30 +128,37 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
toPromise<Endpoint[]>(this.endpointService
|
toPromise<Endpoint[]>(this.endpointService.getEndpoints())
|
||||||
.getEndpoints())
|
|
||||||
.then(targets => {
|
.then(targets => {
|
||||||
this.targetList = targets || [];
|
this.targetList = targets || [];
|
||||||
}).catch((error: any) => this.errorHandler.error(error));
|
})
|
||||||
|
.catch((error: any) => this.errorHandler.error(error));
|
||||||
|
|
||||||
if (!this.projectId) {
|
if (!this.projectId) {
|
||||||
toPromise<Project[]>(this.proService.listProjects("", undefined))
|
toPromise<Project[]>(this.proService.listProjects("", undefined))
|
||||||
.then(targets => {
|
.then(targets => {
|
||||||
this.projectList = targets || [];
|
this.projectList = targets || [];
|
||||||
}).catch(error => this.errorHandler.error(error));
|
})
|
||||||
|
.catch(error => this.errorHandler.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.nameChecker.debounceTime(500).distinctUntilChanged().subscribe((ruleName: string) => {
|
this.nameChecker
|
||||||
|
.debounceTime(500)
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.subscribe((ruleName: string) => {
|
||||||
this.isRuleNameExist = false;
|
this.isRuleNameExist = false;
|
||||||
this.inNameChecking = true;
|
this.inNameChecking = true;
|
||||||
toPromise<ReplicationRule[]>(this.repService.getReplicationRules(0, ruleName))
|
toPromise<ReplicationRule[]>(
|
||||||
|
this.repService.getReplicationRules(0, ruleName)
|
||||||
|
)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.some(rule => rule.name === ruleName)) {
|
if (response.some(rule => rule.name === ruleName)) {
|
||||||
this.ruleNameTooltip = 'TOOLTIP.RULE_USER_EXISTING';
|
this.ruleNameTooltip = "TOOLTIP.RULE_USER_EXISTING";
|
||||||
this.isRuleNameExist = true;
|
this.isRuleNameExist = true;
|
||||||
}
|
}
|
||||||
this.inNameChecking = false;
|
this.inNameChecking = false;
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
this.inNameChecking = false;
|
this.inNameChecking = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -147,28 +167,30 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
.debounceTime(500)
|
.debounceTime(500)
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.subscribe((name: string) => {
|
.subscribe((name: string) => {
|
||||||
this.noProjectInfo = '';
|
this.noProjectInfo = "";
|
||||||
this.selectedProjectList = [];
|
this.selectedProjectList = [];
|
||||||
toPromise<Project[]>(this.proService.listProjects(name, undefined)).then((res: any) => {
|
toPromise<Project[]>(this.proService.listProjects(name, undefined))
|
||||||
|
.then((res: any) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
this.selectedProjectList = res.slice(0, 10);
|
this.selectedProjectList = res.slice(0, 10);
|
||||||
// if input value exit in project list
|
// if input value exit in project list
|
||||||
let pro = res.find((data: any) => data.name === name);
|
let pro = res.find((data: any) => data.name === name);
|
||||||
if (!pro) {
|
if (!pro) {
|
||||||
this.noProjectInfo = 'REPLICATION.NO_PROJECT_INFO';
|
this.noProjectInfo = "REPLICATION.NO_PROJECT_INFO";
|
||||||
this.noSelectedProject = true;
|
this.noSelectedProject = true;
|
||||||
} else {
|
} else {
|
||||||
this.noProjectInfo = '';
|
this.noProjectInfo = "";
|
||||||
this.noSelectedProject = false;
|
this.noSelectedProject = false;
|
||||||
this.setProject([pro])
|
this.setProject([pro]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.noProjectInfo = 'REPLICATION.NO_PROJECT_INFO';
|
this.noProjectInfo = "REPLICATION.NO_PROJECT_INFO";
|
||||||
this.noSelectedProject = true;
|
this.noSelectedProject = true;
|
||||||
}
|
}
|
||||||
}).catch((error: any) => {
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
this.errorHandler.error(error);
|
this.errorHandler.error(error);
|
||||||
this.noProjectInfo = 'REPLICATION.NO_PROJECT_INFO';
|
this.noProjectInfo = "REPLICATION.NO_PROJECT_INFO";
|
||||||
this.noSelectedProject = true;
|
this.noSelectedProject = true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -187,13 +209,18 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get isValid() {
|
get isValid() {
|
||||||
return !(this.isRuleNameExist || this.noSelectedProject || this.noSelectedEndpoint || this.inProgress );
|
return !(
|
||||||
|
this.isRuleNameExist ||
|
||||||
|
this.noSelectedProject ||
|
||||||
|
this.noSelectedEndpoint ||
|
||||||
|
this.inProgress
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
createForm() {
|
createForm() {
|
||||||
this.ruleForm = this.fb.group({
|
this.ruleForm = this.fb.group({
|
||||||
name: ['', Validators.required],
|
name: ["", Validators.required],
|
||||||
description: '',
|
description: "",
|
||||||
projects: this.fb.array([]),
|
projects: this.fb.array([]),
|
||||||
targets: this.fb.array([]),
|
targets: this.fb.array([]),
|
||||||
trigger: this.fb.group({
|
trigger: this.fb.group({
|
||||||
@ -201,8 +228,8 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
schedule_param: this.fb.group({
|
schedule_param: this.fb.group({
|
||||||
type: this.scheduleNames[0],
|
type: this.scheduleNames[0],
|
||||||
weekday: 1,
|
weekday: 1,
|
||||||
offtime: '08:00'
|
offtime: "08:00"
|
||||||
}),
|
})
|
||||||
}),
|
}),
|
||||||
filters: this.fb.array([]),
|
filters: this.fb.array([]),
|
||||||
replicate_existing_image_now: true,
|
replicate_existing_image_now: true,
|
||||||
@ -212,13 +239,16 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
initForm(): void {
|
initForm(): void {
|
||||||
this.ruleForm.reset({
|
this.ruleForm.reset({
|
||||||
name: '',
|
name: "",
|
||||||
description: '',
|
description: "",
|
||||||
trigger: {kind: this.triggerNames[0], schedule_param: {
|
trigger: {
|
||||||
|
kind: this.triggerNames[0],
|
||||||
|
schedule_param: {
|
||||||
type: this.scheduleNames[0],
|
type: this.scheduleNames[0],
|
||||||
weekday: 1,
|
weekday: 1,
|
||||||
offtime: '08:00'
|
offtime: "08:00"
|
||||||
}},
|
}
|
||||||
|
},
|
||||||
replicate_existing_image_now: true,
|
replicate_existing_image_now: true,
|
||||||
replicate_deletion: false
|
replicate_deletion: false
|
||||||
});
|
});
|
||||||
@ -254,44 +284,44 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get projects(): FormArray {
|
get projects(): FormArray {
|
||||||
return this.ruleForm.get('projects') as FormArray;
|
return this.ruleForm.get("projects") as FormArray;
|
||||||
}
|
}
|
||||||
setProject(projects: Project[]) {
|
setProject(projects: Project[]) {
|
||||||
const projectFGs = projects.map(project => this.fb.group(project));
|
const projectFGs = projects.map(project => this.fb.group(project));
|
||||||
const projectFormArray = this.fb.array(projectFGs);
|
const projectFormArray = this.fb.array(projectFGs);
|
||||||
this.ruleForm.setControl('projects', projectFormArray);
|
this.ruleForm.setControl("projects", projectFormArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
get filters(): FormArray {
|
get filters(): FormArray {
|
||||||
return this.ruleForm.get('filters') as FormArray;
|
return this.ruleForm.get("filters") as FormArray;
|
||||||
}
|
}
|
||||||
setFilter(filters: Filter[]) {
|
setFilter(filters: Filter[]) {
|
||||||
const filterFGs = filters.map(filter => this.fb.group(filter));
|
const filterFGs = filters.map(filter => this.fb.group(filter));
|
||||||
const filterFormArray = this.fb.array(filterFGs);
|
const filterFormArray = this.fb.array(filterFGs);
|
||||||
this.ruleForm.setControl('filters', filterFormArray);
|
this.ruleForm.setControl("filters", filterFormArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
get targets(): FormArray {
|
get targets(): FormArray {
|
||||||
return this.ruleForm.get('targets') as FormArray;
|
return this.ruleForm.get("targets") as FormArray;
|
||||||
}
|
}
|
||||||
setTarget(targets: Endpoint[]) {
|
setTarget(targets: Endpoint[]) {
|
||||||
const targetFGs = targets.map(target => this.fb.group(target));
|
const targetFGs = targets.map(target => this.fb.group(target));
|
||||||
const targetFormArray = this.fb.array(targetFGs);
|
const targetFormArray = this.fb.array(targetFGs);
|
||||||
this.ruleForm.setControl('targets', targetFormArray);
|
this.ruleForm.setControl("targets", targetFormArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
initFilter(name: string) {
|
initFilter(name: string) {
|
||||||
return this.fb.group({
|
return this.fb.group({
|
||||||
kind: name,
|
kind: name,
|
||||||
pattern: ['', Validators.required]
|
pattern: ["", Validators.required]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
filterChange($event: any) {
|
filterChange($event: any) {
|
||||||
if ($event && $event.target['value']) {
|
if ($event && $event.target["value"]) {
|
||||||
let id: number = $event.target.id;
|
let id: number = $event.target.id;
|
||||||
let name: string = $event.target.name;
|
let name: string = $event.target.name;
|
||||||
let value: string = $event.target['value'];
|
let value: string = $event.target["value"];
|
||||||
|
|
||||||
this.filterListData.forEach((data, index) => {
|
this.filterListData.forEach((data, index) => {
|
||||||
if (index === +id) {
|
if (index === +id) {
|
||||||
@ -308,11 +338,13 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
targetChange($event: any) {
|
targetChange($event: any) {
|
||||||
if ($event && $event.target) {
|
if ($event && $event.target) {
|
||||||
if ($event.target['value'] === '-1') {
|
if ($event.target["value"] === "-1") {
|
||||||
this.noSelectedEndpoint = true;
|
this.noSelectedEndpoint = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let selecedTarget: Endpoint = this.targetList.find(target => target.id === +$event.target['value']);
|
let selecedTarget: Endpoint = this.targetList.find(
|
||||||
|
target => target.id === +$event.target["value"]
|
||||||
|
);
|
||||||
this.setTarget([selecedTarget]);
|
this.setTarget([selecedTarget]);
|
||||||
this.noSelectedEndpoint = false;
|
this.noSelectedEndpoint = false;
|
||||||
}
|
}
|
||||||
@ -328,8 +360,8 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
focusClear($event: any): void {
|
focusClear($event: any): void {
|
||||||
if (this.policyId < 0 && this.firstClick === 0) {
|
if (this.policyId < 0 && this.firstClick === 0) {
|
||||||
if ($event && $event.target && $event.target['value']) {
|
if ($event && $event.target && $event.target["value"]) {
|
||||||
$event.target['value'] = '';
|
$event.target["value"] = "";
|
||||||
}
|
}
|
||||||
this.firstClick++;
|
this.firstClick++;
|
||||||
}
|
}
|
||||||
@ -341,7 +373,9 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
selectedProjectName(projectName: string) {
|
selectedProjectName(projectName: string) {
|
||||||
this.noSelectedProject = false;
|
this.noSelectedProject = false;
|
||||||
let pro: Project = this.selectedProjectList.find(data => data.name === projectName);
|
let pro: Project = this.selectedProjectList.find(
|
||||||
|
data => data.name === projectName
|
||||||
|
);
|
||||||
this.setProject([pro]);
|
this.setProject([pro]);
|
||||||
this.selectedProjectList = [];
|
this.selectedProjectList = [];
|
||||||
this.noProjectInfo = "";
|
this.noProjectInfo = "";
|
||||||
@ -358,16 +392,21 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
addNewFilter(): void {
|
addNewFilter(): void {
|
||||||
if (this.filterCount === 0) {
|
if (this.filterCount === 0) {
|
||||||
this.filterListData.push(this.baseFilterData(this.filterSelect[0], this.filterSelect.slice(), true));
|
this.filterListData.push(
|
||||||
|
this.baseFilterData(
|
||||||
|
this.filterSelect[0],
|
||||||
|
this.filterSelect.slice(),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
);
|
||||||
this.filters.push(this.initFilter(this.filterSelect[0]));
|
this.filters.push(this.initFilter(this.filterSelect[0]));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
let nameArr: string[] = this.filterSelect.slice();
|
let nameArr: string[] = this.filterSelect.slice();
|
||||||
this.filterListData.forEach(data => {
|
this.filterListData.forEach(data => {
|
||||||
nameArr.splice(nameArr.indexOf(data.name), 1);
|
nameArr.splice(nameArr.indexOf(data.name), 1);
|
||||||
});
|
});
|
||||||
// when add a new filter,the filterListData should change the options
|
// when add a new filter,the filterListData should change the options
|
||||||
this.filterListData.filter((data) => {
|
this.filterListData.filter(data => {
|
||||||
data.options.splice(data.options.indexOf(nameArr[0]), 1);
|
data.options.splice(data.options.indexOf(nameArr[0]), 1);
|
||||||
});
|
});
|
||||||
this.filterListData.push(this.baseFilterData(nameArr[0], nameArr, true));
|
this.filterListData.push(this.baseFilterData(nameArr[0], nameArr, true));
|
||||||
@ -395,14 +434,14 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const control = <FormArray>this.ruleForm.controls['filters'];
|
const control = <FormArray>this.ruleForm.controls["filters"];
|
||||||
control.removeAt(i);
|
control.removeAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selectTrigger($event: any): void {
|
selectTrigger($event: any): void {
|
||||||
if ($event && $event.target && $event.target['value']) {
|
if ($event && $event.target && $event.target["value"]) {
|
||||||
let val: string = $event.target['value'];
|
let val: string = $event.target["value"];
|
||||||
if (val === this.triggerNames[2]) {
|
if (val === this.triggerNames[2]) {
|
||||||
this.isScheduleOpt = true;
|
this.isScheduleOpt = true;
|
||||||
this.isImmediate = false;
|
this.isImmediate = false;
|
||||||
@ -420,14 +459,14 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
// Replication Schedule select value exchange
|
// Replication Schedule select value exchange
|
||||||
selectSchedule($event: any): void {
|
selectSchedule($event: any): void {
|
||||||
if ($event && $event.target && $event.target['value']) {
|
if ($event && $event.target && $event.target["value"]) {
|
||||||
switch ($event.target['value']) {
|
switch ($event.target["value"]) {
|
||||||
case this.scheduleNames[1]:
|
case this.scheduleNames[1]:
|
||||||
this.weeklySchedule = true;
|
this.weeklySchedule = true;
|
||||||
this.ruleForm.patchValue({
|
this.ruleForm.patchValue({
|
||||||
trigger: {
|
trigger: {
|
||||||
schedule_param: {
|
schedule_param: {
|
||||||
weekday: 1,
|
weekday: 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -440,11 +479,11 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkRuleName(): void {
|
checkRuleName(): void {
|
||||||
let ruleName: string = this.ruleForm.controls['name'].value;
|
let ruleName: string = this.ruleForm.controls["name"].value;
|
||||||
if (ruleName) {
|
if (ruleName) {
|
||||||
this.nameChecker.next(ruleName);
|
this.nameChecker.next(ruleName);
|
||||||
} else {
|
} else {
|
||||||
this.ruleNameTooltip = 'TOOLTIP.EMPTY';
|
this.ruleNameTooltip = "TOOLTIP.EMPTY";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,41 +504,49 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateTrigger(trigger: any) {
|
updateTrigger(trigger: any) {
|
||||||
if (trigger['schedule_param']) {
|
if (trigger["schedule_param"]) {
|
||||||
this.isScheduleOpt = true;
|
this.isScheduleOpt = true;
|
||||||
this.isImmediate = false;
|
this.isImmediate = false;
|
||||||
trigger['schedule_param']['offtime'] = this.getOfftime(trigger['schedule_param']['offtime']);
|
trigger["schedule_param"]["offtime"] = this.getOfftime(
|
||||||
if (trigger['schedule_param']['weekday']) {
|
trigger["schedule_param"]["offtime"]
|
||||||
|
);
|
||||||
|
if (trigger["schedule_param"]["weekday"]) {
|
||||||
this.weeklySchedule = true;
|
this.weeklySchedule = true;
|
||||||
} else {
|
} else {
|
||||||
// set default
|
// set default
|
||||||
trigger['schedule_param']['weekday'] = 1;
|
trigger["schedule_param"]["weekday"] = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (trigger['kind'] === this.triggerNames[0]) {
|
if (trigger["kind"] === this.triggerNames[0]) {
|
||||||
this.isImmediate = false;
|
this.isImmediate = false;
|
||||||
}
|
}
|
||||||
if (trigger['kind'] === this.triggerNames[1]) {
|
if (trigger["kind"] === this.triggerNames[1]) {
|
||||||
this.isImmediate = true;
|
this.isImmediate = true;
|
||||||
}
|
}
|
||||||
trigger['schedule_param'] = { type: this.scheduleNames[0],
|
trigger["schedule_param"] = {
|
||||||
|
type: this.scheduleNames[0],
|
||||||
weekday: this.weekly[0],
|
weekday: this.weekly[0],
|
||||||
offtime: '08:00'};
|
offtime: "08:00"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return trigger;
|
return trigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
setTriggerVaule(trigger: any) {
|
setTriggerVaule(trigger: any) {
|
||||||
if (!this.isScheduleOpt) {
|
if (!this.isScheduleOpt) {
|
||||||
delete trigger['schedule_param'];
|
delete trigger["schedule_param"];
|
||||||
return trigger;
|
return trigger;
|
||||||
} else {
|
} else {
|
||||||
if (!this.weeklySchedule) {
|
if (!this.weeklySchedule) {
|
||||||
delete trigger['schedule_param']['weekday'];
|
delete trigger["schedule_param"]["weekday"];
|
||||||
} else {
|
} else {
|
||||||
trigger['schedule_param']['weekday'] = +trigger['schedule_param']['weekday'];
|
trigger["schedule_param"]["weekday"] = +trigger["schedule_param"][
|
||||||
|
"weekday"
|
||||||
|
];
|
||||||
}
|
}
|
||||||
trigger['schedule_param']['offtime'] = this.setOfftime(trigger['schedule_param']['offtime']);
|
trigger["schedule_param"]["offtime"] = this.setOfftime(
|
||||||
|
trigger["schedule_param"]["offtime"]
|
||||||
|
);
|
||||||
return trigger;
|
return trigger;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -514,26 +561,32 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
let copyRuleForm: ReplicationRule = this.ruleForm.value;
|
let copyRuleForm: ReplicationRule = this.ruleForm.value;
|
||||||
copyRuleForm.trigger = this.setTriggerVaule(copyRuleForm.trigger);
|
copyRuleForm.trigger = this.setTriggerVaule(copyRuleForm.trigger);
|
||||||
if (this.policyId < 0) {
|
if (this.policyId < 0) {
|
||||||
this.repService.createReplicationRule(copyRuleForm)
|
this.repService
|
||||||
|
.createReplicationRule(copyRuleForm)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.translateService.get('REPLICATION.CREATED_SUCCESS')
|
this.translateService
|
||||||
|
.get("REPLICATION.CREATED_SUCCESS")
|
||||||
.subscribe(res => this.errorHandler.info(res));
|
.subscribe(res => this.errorHandler.info(res));
|
||||||
this.inProgress = false;
|
this.inProgress = false;
|
||||||
this.reload.emit(true);
|
this.reload.emit(true);
|
||||||
this.close();
|
this.close();
|
||||||
}).catch((error: any) => {
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
this.inProgress = false;
|
this.inProgress = false;
|
||||||
this.inlineAlert.showInlineError(error);
|
this.inlineAlert.showInlineError(error);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.repService.updateReplicationRule(this.policyId, this.ruleForm.value)
|
this.repService
|
||||||
|
.updateReplicationRule(this.policyId, this.ruleForm.value)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.translateService.get('REPLICATION.UPDATED_SUCCESS')
|
this.translateService
|
||||||
|
.get("REPLICATION.UPDATED_SUCCESS")
|
||||||
.subscribe(res => this.errorHandler.info(res));
|
.subscribe(res => this.errorHandler.info(res));
|
||||||
this.inProgress = false;
|
this.inProgress = false;
|
||||||
this.reload.emit(true);
|
this.reload.emit(true);
|
||||||
this.close();
|
this.close();
|
||||||
}).catch((error: any) => {
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
this.inProgress = false;
|
this.inProgress = false;
|
||||||
this.inlineAlert.showInlineError(error);
|
this.inlineAlert.showInlineError(error);
|
||||||
});
|
});
|
||||||
@ -559,28 +612,33 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
this.noProjectInfo = "";
|
this.noProjectInfo = "";
|
||||||
this.noEndpointInfo = "";
|
this.noEndpointInfo = "";
|
||||||
if (this.targetList.length === 0) {
|
if (this.targetList.length === 0) {
|
||||||
this.noEndpointInfo = 'REPLICATION.NO_ENDPOINT_INFO';
|
this.noEndpointInfo = "REPLICATION.NO_ENDPOINT_INFO";
|
||||||
}
|
}
|
||||||
if (this.projectList.length === 0 && !this.projectName) {
|
if (this.projectList.length === 0 && !this.projectName) {
|
||||||
this.noProjectInfo = 'REPLICATION.NO_PROJECT_INFO';
|
this.noProjectInfo = "REPLICATION.NO_PROJECT_INFO";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ruleId) {
|
if (ruleId) {
|
||||||
this.policyId = +ruleId;
|
this.policyId = +ruleId;
|
||||||
this.headerTitle = 'REPLICATION.EDIT_POLICY_TITLE';
|
this.headerTitle = "REPLICATION.EDIT_POLICY_TITLE";
|
||||||
toPromise(this.repService.getReplicationRule(ruleId))
|
toPromise(this.repService.getReplicationRule(ruleId))
|
||||||
.then((response) => {
|
.then(response => {
|
||||||
this.copyUpdateForm = Object.assign({}, response);
|
this.copyUpdateForm = Object.assign({}, response);
|
||||||
// set filter value is [] if callback fiter value is null.
|
// set filter value is [] if callback fiter value is null.
|
||||||
this.copyUpdateForm.filters = response.filters ? response.filters : [];
|
this.copyUpdateForm.filters = response.filters
|
||||||
|
? response.filters
|
||||||
|
: [];
|
||||||
this.updateForm(response);
|
this.updateForm(response);
|
||||||
}).catch((error: any) => {
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
this.inlineAlert.showInlineError(error);
|
this.inlineAlert.showInlineError(error);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.headerTitle = 'REPLICATION.ADD_POLICY';
|
this.headerTitle = "REPLICATION.ADD_POLICY";
|
||||||
if (this.projectId) {
|
if (this.projectId) {
|
||||||
this.setProject([{project_id: this.projectId, name: this.projectName}]);
|
this.setProject([
|
||||||
|
{ project_id: this.projectId, name: this.projectName }
|
||||||
|
]);
|
||||||
this.noSelectedProject = false;
|
this.noSelectedProject = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,7 +657,9 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
onCancel(): void {
|
onCancel(): void {
|
||||||
if (this.hasFormChange()) {
|
if (this.hasFormChange()) {
|
||||||
this.inlineAlert.showInlineConfirmation({ message: 'ALERT.FORM_CHANGE_CONFIRMATION' });
|
this.inlineAlert.showInlineConfirmation({
|
||||||
|
message: "ALERT.FORM_CHANGE_CONFIRMATION"
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
@ -611,9 +671,8 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
// UTC time
|
// UTC time
|
||||||
public getOfftime(daily_time: any): string {
|
public getOfftime(daily_time: any): string {
|
||||||
|
|
||||||
let timeOffset = 0; // seconds
|
let timeOffset = 0; // seconds
|
||||||
if (daily_time && typeof daily_time === 'number') {
|
if (daily_time && typeof daily_time === "number") {
|
||||||
timeOffset = +daily_time;
|
timeOffset = +daily_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -631,27 +690,29 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
// To time string
|
// To time string
|
||||||
let hours: number = Math.floor(timeOffset / ONE_HOUR_SECONDS);
|
let hours: number = Math.floor(timeOffset / ONE_HOUR_SECONDS);
|
||||||
let minutes: number = Math.floor((timeOffset - hours * ONE_HOUR_SECONDS) / 60);
|
let minutes: number = Math.floor(
|
||||||
|
(timeOffset - hours * ONE_HOUR_SECONDS) / 60
|
||||||
|
);
|
||||||
|
|
||||||
let timeStr: string = '' + hours;
|
let timeStr: string = "" + hours;
|
||||||
if (hours < 10) {
|
if (hours < 10) {
|
||||||
timeStr = '0' + timeStr;
|
timeStr = "0" + timeStr;
|
||||||
}
|
}
|
||||||
if (minutes < 10) {
|
if (minutes < 10) {
|
||||||
timeStr += ':0';
|
timeStr += ":0";
|
||||||
} else {
|
} else {
|
||||||
timeStr += ':';
|
timeStr += ":";
|
||||||
}
|
}
|
||||||
timeStr += minutes;
|
timeStr += minutes;
|
||||||
|
|
||||||
return timeStr;
|
return timeStr;
|
||||||
}
|
}
|
||||||
public setOfftime(v: string) {
|
public setOfftime(v: string) {
|
||||||
if (!v || v === '') {
|
if (!v || v === "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let values: string[] = v.split(':');
|
let values: string[] = v.split(":");
|
||||||
if (!values || values.length !== 2) {
|
if (!values || values.length !== 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -679,13 +740,21 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
if (!ruleValue || !this.copyUpdateForm) {
|
if (!ruleValue || !this.copyUpdateForm) {
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
for (let prop in ruleValue) {
|
for (let prop of Object.keys(ruleValue)) {
|
||||||
let field: any = this.copyUpdateForm[prop];
|
let field: any = this.copyUpdateForm[prop];
|
||||||
if (!compareValue(field, ruleValue[prop])) {
|
if (!compareValue(field, ruleValue[prop])) {
|
||||||
if (ruleValue[prop][0] && ruleValue[prop][0].project_id && (ruleValue[prop][0].project_id === field[0].project_id)) {
|
if (
|
||||||
|
ruleValue[prop][0] &&
|
||||||
|
ruleValue[prop][0].project_id &&
|
||||||
|
ruleValue[prop][0].project_id === field[0].project_id
|
||||||
|
) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ruleValue[prop][0] && ruleValue[prop][0].id && (ruleValue[prop][0].id === field[0].id)) {
|
if (
|
||||||
|
ruleValue[prop][0] &&
|
||||||
|
ruleValue[prop][0].id &&
|
||||||
|
ruleValue[prop][0].id === field[0].id
|
||||||
|
) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
changes[prop] = ruleValue[prop];
|
changes[prop] = ruleValue[prop];
|
||||||
@ -696,12 +765,11 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
// Trim string value
|
// Trim string value
|
||||||
if (typeof field === "string") {
|
if (typeof field === "string") {
|
||||||
changes[prop] = ('' + changes[prop]).trim();
|
changes[prop] = ("" + changes[prop]).trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import { Type } from '@angular/core';
|
import { Type } from "@angular/core";
|
||||||
|
|
||||||
import { CreateEditRuleComponent } from './create-edit-rule.component';
|
import { CreateEditRuleComponent } from "./create-edit-rule.component";
|
||||||
|
|
||||||
export const CREATE_EDIT_RULE_DIRECTIVES: Type<any>[] = [
|
export const CREATE_EDIT_RULE_DIRECTIVES: Type<any>[] = [
|
||||||
CreateEditRuleComponent
|
CreateEditRuleComponent
|
||||||
|
@ -11,19 +11,27 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Directive, OnChanges, Input, SimpleChanges } from '@angular/core';
|
import { Directive, OnChanges, Input, SimpleChanges } from "@angular/core";
|
||||||
import { NG_VALIDATORS, Validator, Validators, ValidatorFn, AbstractControl } from '@angular/forms';
|
import {
|
||||||
|
NG_VALIDATORS,
|
||||||
|
Validator,
|
||||||
|
Validators,
|
||||||
|
ValidatorFn,
|
||||||
|
AbstractControl
|
||||||
|
} from "@angular/forms";
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[dateValidator]',
|
selector: "[dateValidator]",
|
||||||
providers: [{provide: NG_VALIDATORS, useExisting: DateValidatorDirective, multi: true}]
|
providers: [
|
||||||
|
{ provide: NG_VALIDATORS, useExisting: DateValidatorDirective, multi: true }
|
||||||
|
]
|
||||||
})
|
})
|
||||||
export class DateValidatorDirective implements Validator, OnChanges {
|
export class DateValidatorDirective implements Validator, OnChanges {
|
||||||
@Input() dateValidator: string;
|
@Input() dateValidator: string;
|
||||||
private valFn = Validators.nullValidator;
|
private valFn = Validators.nullValidator;
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
const change = changes['dateValidator'];
|
const change = changes["dateValidator"];
|
||||||
if (change) {
|
if (change) {
|
||||||
this.valFn = dateValidator();
|
this.valFn = dateValidator();
|
||||||
} else {
|
} else {
|
||||||
@ -42,9 +50,10 @@ export function dateValidator(): ValidatorFn {
|
|||||||
if (controlValue) {
|
if (controlValue) {
|
||||||
const regYMD = /^(19|20)\d\d([- /.])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/g;
|
const regYMD = /^(19|20)\d\d([- /.])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/g;
|
||||||
const regDMY = /^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/g;
|
const regDMY = /^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/g;
|
||||||
valid = (regYMD.test(controlValue) || regDMY.test(controlValue));
|
valid = regYMD.test(controlValue) || regDMY.test(controlValue);
|
||||||
}
|
}
|
||||||
return valid ? Validators.nullValidator : {'dateValidator': { value: controlValue }};
|
return valid
|
||||||
|
? Validators.nullValidator
|
||||||
|
: { dateValidator: { value: controlValue } };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,22 @@
|
|||||||
import {Component, Input, Output, EventEmitter, ViewChild, OnChanges} from '@angular/core';
|
import {
|
||||||
import { NgModel } from '@angular/forms';
|
Component,
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
EventEmitter,
|
||||||
|
ViewChild,
|
||||||
|
OnChanges
|
||||||
|
} from "@angular/core";
|
||||||
|
import { NgModel } from "@angular/forms";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-datetime',
|
selector: "hbr-datetime",
|
||||||
templateUrl: './datetime-picker.component.html'
|
templateUrl: "./datetime-picker.component.html"
|
||||||
})
|
})
|
||||||
export class DatePickerComponent implements OnChanges {
|
export class DatePickerComponent implements OnChanges {
|
||||||
|
|
||||||
@Input() dateInput: string;
|
@Input() dateInput: string;
|
||||||
@Input() oneDayOffset: boolean;
|
@Input() oneDayOffset: boolean;
|
||||||
|
|
||||||
@ViewChild('searchTime')
|
@ViewChild("searchTime") searchTime: NgModel;
|
||||||
searchTime: NgModel;
|
|
||||||
|
|
||||||
@Output() search = new EventEmitter<string>();
|
@Output() search = new EventEmitter<string>();
|
||||||
|
|
||||||
@ -20,21 +25,32 @@ export class DatePickerComponent implements OnChanges{
|
|||||||
}
|
}
|
||||||
|
|
||||||
get dateInvalid(): boolean {
|
get dateInvalid(): boolean {
|
||||||
return (this.searchTime.errors && this.searchTime.errors.dateValidator && (this.searchTime.dirty || this.searchTime.touched)) || false;
|
return (
|
||||||
|
(this.searchTime.errors &&
|
||||||
|
this.searchTime.errors.dateValidator &&
|
||||||
|
(this.searchTime.dirty || this.searchTime.touched)) ||
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
convertDate(strDate: string): string {
|
convertDate(strDate: string): string {
|
||||||
if(/^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/.test(strDate)) {
|
if (
|
||||||
|
/^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/.test(
|
||||||
|
strDate
|
||||||
|
)
|
||||||
|
) {
|
||||||
let parts = strDate.split(/[-\/]/);
|
let parts = strDate.split(/[-\/]/);
|
||||||
strDate = parts[2] /*Year*/ + '-' +parts[1] /*Month*/ + '-' + parts[0] /*Date*/;
|
strDate =
|
||||||
|
parts[2] /*Year*/ + "-" + parts[1] /*Month*/ + "-" + parts[0] /*Date*/;
|
||||||
}
|
}
|
||||||
return strDate;
|
return strDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
doSearch() {
|
doSearch() {
|
||||||
let searchTerm: string = '';
|
let searchTerm: string = "";
|
||||||
if (this.searchTime.valid && this.dateInput) {
|
if (this.searchTime.valid && this.dateInput) {
|
||||||
let timestamp: number = new Date(this.convertDate(this.searchTime.value)).getTime() / 1000;
|
let timestamp: number =
|
||||||
|
new Date(this.convertDate(this.searchTime.value)).getTime() / 1000;
|
||||||
if (this.oneDayOffset) {
|
if (this.oneDayOffset) {
|
||||||
timestamp += 3600 * 24;
|
timestamp += 3600 * 24;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Type } from '@angular/core';
|
import { Type } from "@angular/core";
|
||||||
|
|
||||||
import { DatePickerComponent } from './datetime-picker.component';
|
import { DatePickerComponent } from "./datetime-picker.component";
|
||||||
import { DateValidatorDirective } from './date-validator.directive';
|
import { DateValidatorDirective } from "./date-validator.directive";
|
||||||
export const DATETIME_PICKER_DIRECTIVES: Type<any>[] = [
|
export const DATETIME_PICKER_DIRECTIVES: Type<any>[] = [
|
||||||
DatePickerComponent,
|
DatePickerComponent,
|
||||||
DateValidatorDirective
|
DateValidatorDirective
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="row flex-items-xs-between rightPos">
|
<div class="row flex-items-xs-between rightPos">
|
||||||
<div class="flex-items-xs-middle option-right">
|
<div class="flex-items-xs-middle option-right">
|
||||||
<hbr-filter [withDivider]="true" filterPlaceholder='{{"REPLICATION.FILTER_TARGETS_PLACEHOLDER" | translate}}' (filter)="doSearchTargets($event)" [currentValue]="targetName"></hbr-filter>
|
<hbr-filter [withDivider]="true" filterPlaceholder='{{"REPLICATION.FILTER_TARGETS_PLACEHOLDER" | translate}}' (filterEvt)="doSearchTargets($event)" [currentValue]="targetName"></hbr-filter>
|
||||||
<span class="refresh-btn" (click)="refreshTargets()">
|
<span class="refresh-btn" (click)="refreshTargets()">
|
||||||
<clr-icon shape="refresh"></clr-icon>
|
<clr-icon shape="refresh"></clr-icon>
|
||||||
</span>
|
</span>
|
||||||
|
@ -1,76 +1,80 @@
|
|||||||
import { ComponentFixture, TestBed, async, fakeAsync, tick } from '@angular/core/testing';
|
import { ComponentFixture, TestBed, async } from "@angular/core/testing";
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from "@angular/platform-browser";
|
||||||
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
import { DebugElement } from '@angular/core';
|
import { DebugElement } from "@angular/core";
|
||||||
|
|
||||||
import { SharedModule } from '../shared/shared.module';
|
import { SharedModule } from "../shared/shared.module";
|
||||||
import { EndpointComponent } from './endpoint.component';
|
import { EndpointComponent } from "./endpoint.component";
|
||||||
import { FilterComponent } from '../filter/filter.component';
|
import { FilterComponent } from "../filter/filter.component";
|
||||||
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation-dialog.component";
|
||||||
import { CreateEditEndpointComponent } from '../create-edit-endpoint/create-edit-endpoint.component';
|
import { CreateEditEndpointComponent } from "../create-edit-endpoint/create-edit-endpoint.component";
|
||||||
import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
|
import { InlineAlertComponent } from "../inline-alert/inline-alert.component";
|
||||||
import { ErrorHandler } from '../error-handler/error-handler';
|
import { ErrorHandler } from "../error-handler/error-handler";
|
||||||
import { Endpoint } from '../service/interface';
|
import { Endpoint } from "../service/interface";
|
||||||
import { EndpointService, EndpointDefaultService } from '../service/endpoint.service';
|
import {
|
||||||
import { IServiceConfig, SERVICE_CONFIG } from '../service.config';
|
EndpointService,
|
||||||
|
EndpointDefaultService
|
||||||
|
} from "../service/endpoint.service";
|
||||||
|
import { IServiceConfig, SERVICE_CONFIG } from "../service.config";
|
||||||
|
|
||||||
import { click } from '../utils';
|
import { click } from "../utils";
|
||||||
|
|
||||||
describe('EndpointComponent (inline template)', () => {
|
|
||||||
|
|
||||||
|
describe("EndpointComponent (inline template)", () => {
|
||||||
let mockData: Endpoint[] = [
|
let mockData: Endpoint[] = [
|
||||||
{
|
{
|
||||||
"id": 1,
|
id: 1,
|
||||||
"endpoint": "https://10.117.4.151",
|
endpoint: "https://10.117.4.151",
|
||||||
"name": "target_01",
|
name: "target_01",
|
||||||
"username": "admin",
|
username: "admin",
|
||||||
"password": "",
|
password: "",
|
||||||
"insecure": true,
|
insecure: true,
|
||||||
"type": 0
|
type: 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
id: 2,
|
||||||
"endpoint": "https://10.117.5.142",
|
endpoint: "https://10.117.5.142",
|
||||||
"name": "target_02",
|
name: "target_02",
|
||||||
"username": "AAA",
|
username: "AAA",
|
||||||
"password": "",
|
password: "",
|
||||||
"insecure": false,
|
insecure: false,
|
||||||
"type": 0
|
type: 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
id: 3,
|
||||||
"endpoint": "https://101.1.11.111",
|
endpoint: "https://101.1.11.111",
|
||||||
"name": "target_03",
|
name: "target_03",
|
||||||
"username": "admin",
|
username: "admin",
|
||||||
"password": "",
|
password: "",
|
||||||
"insecure": false,
|
insecure: false,
|
||||||
"type": 0
|
type: 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 4,
|
id: 4,
|
||||||
"endpoint": "http://4.4.4.4",
|
endpoint: "http://4.4.4.4",
|
||||||
"name": "target_04",
|
name: "target_04",
|
||||||
"username": "",
|
username: "",
|
||||||
"password": "",
|
password: "",
|
||||||
"insecure": false,
|
insecure: false,
|
||||||
"type": 0
|
type: 0
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
let mockOne: Endpoint[] = [{
|
let mockOne: Endpoint[] = [
|
||||||
"id": 1,
|
{
|
||||||
"endpoint": "https://10.117.4.151",
|
id: 1,
|
||||||
"name": "target_01",
|
endpoint: "https://10.117.4.151",
|
||||||
"username": "admin",
|
name: "target_01",
|
||||||
"password": "",
|
username: "admin",
|
||||||
"insecure": false,
|
password: "",
|
||||||
"type": 0
|
insecure: false,
|
||||||
}];
|
type: 0
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
let comp: EndpointComponent;
|
let comp: EndpointComponent;
|
||||||
let fixture: ComponentFixture<EndpointComponent>;
|
let fixture: ComponentFixture<EndpointComponent>;
|
||||||
let config: IServiceConfig = {
|
let config: IServiceConfig = {
|
||||||
systemInfoEndpoint: '/api/endpoints/testing'
|
systemInfoEndpoint: "/api/endpoints/testing"
|
||||||
};
|
};
|
||||||
|
|
||||||
let endpointService: EndpointService;
|
let endpointService: EndpointService;
|
||||||
@ -79,16 +83,14 @@ describe('EndpointComponent (inline template)', () => {
|
|||||||
let spyOne: jasmine.Spy;
|
let spyOne: jasmine.Spy;
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [SharedModule, NoopAnimationsModule],
|
||||||
SharedModule,
|
|
||||||
NoopAnimationsModule
|
|
||||||
],
|
|
||||||
declarations: [
|
declarations: [
|
||||||
FilterComponent,
|
FilterComponent,
|
||||||
ConfirmationDialogComponent,
|
ConfirmationDialogComponent,
|
||||||
CreateEditEndpointComponent,
|
CreateEditEndpointComponent,
|
||||||
InlineAlertComponent,
|
InlineAlertComponent,
|
||||||
EndpointComponent ],
|
EndpointComponent
|
||||||
|
],
|
||||||
providers: [
|
providers: [
|
||||||
ErrorHandler,
|
ErrorHandler,
|
||||||
{ provide: SERVICE_CONFIG, useValue: config },
|
{ provide: SERVICE_CONFIG, useValue: config },
|
||||||
@ -103,81 +105,90 @@ describe('EndpointComponent (inline template)', () => {
|
|||||||
|
|
||||||
endpointService = fixture.debugElement.injector.get(EndpointService);
|
endpointService = fixture.debugElement.injector.get(EndpointService);
|
||||||
|
|
||||||
spy = spyOn(endpointService, 'getEndpoints').and.returnValues(Promise.resolve(mockData));
|
spy = spyOn(endpointService, "getEndpoints").and.returnValues(
|
||||||
spyOnRules = spyOn(endpointService, 'getEndpointWithReplicationRules').and.returnValue([]);
|
Promise.resolve(mockData)
|
||||||
spyOne = spyOn(endpointService, 'getEndpoint').and.returnValue(Promise.resolve(mockOne[0]));
|
);
|
||||||
|
spyOnRules = spyOn(
|
||||||
|
endpointService,
|
||||||
|
"getEndpointWithReplicationRules"
|
||||||
|
).and.returnValue([]);
|
||||||
|
spyOne = spyOn(endpointService, "getEndpoint").and.returnValue(
|
||||||
|
Promise.resolve(mockOne[0])
|
||||||
|
);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should retrieve endpoint data', () => {
|
it("should retrieve endpoint data", () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(spy.calls.any()).toBeTruthy();
|
expect(spy.calls.any()).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should endpoint be initialized', () => {
|
it("should endpoint be initialized", () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(config.systemInfoEndpoint).toEqual('/api/endpoints/testing');
|
expect(config.systemInfoEndpoint).toEqual("/api/endpoints/testing");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should open create endpoint modal', async(() => {
|
it("should open create endpoint modal", async(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
comp.editTargets(mockOne);
|
comp.editTargets(mockOne);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(comp.target.name).toEqual('target_01');
|
expect(comp.target.name).toEqual("target_01");
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should filter endpoints by keyword', async(() => {
|
it("should filter endpoints by keyword", async(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
comp.doSearchTargets('target_02');
|
comp.doSearchTargets("target_02");
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(comp.targets.length).toEqual(1);
|
expect(comp.targets.length).toEqual(1);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should render data', async(()=>{
|
it("should render data", async(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let de: DebugElement = fixture.debugElement.query(By.css('datagrid-cell'));
|
let de: DebugElement = fixture.debugElement.query(
|
||||||
|
By.css("datagrid-cell")
|
||||||
|
);
|
||||||
expect(de).toBeTruthy();
|
expect(de).toBeTruthy();
|
||||||
let el: HTMLElement = de.nativeElement;
|
let el: HTMLElement = de.nativeElement;
|
||||||
expect(el.textContent).toEqual('target_01');
|
expect(el.textContent).toEqual("target_01");
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should open creation endpoint', async(()=>{
|
it("should open creation endpoint", async(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
let de: DebugElement = fixture.debugElement.query(By.css('btn-link'));
|
let de: DebugElement = fixture.debugElement.query(By.css("btn-link"));
|
||||||
expect(de).toBeTruthy();
|
expect(de).toBeTruthy();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
click(de);
|
click(de);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let deInput: DebugElement = fixture.debugElement.query(By.css('input'));
|
let deInput: DebugElement = fixture.debugElement.query(By.css("input"));
|
||||||
expect(deInput).toBeTruthy();
|
expect(deInput).toBeTruthy();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it("should open to edit existing endpoint", async(() => {
|
||||||
it('should open to edit existing endpoint', async(()=>{
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
let de: DebugElement = fixture.debugElement.query(del=>del.classes['action-item']);
|
let de: DebugElement = fixture.debugElement.query(
|
||||||
|
del => del.classes["action-item"]
|
||||||
|
);
|
||||||
expect(de).toBeTruthy();
|
expect(de).toBeTruthy();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
click(de);
|
click(de);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let deInput: DebugElement = fixture.debugElement.query(By.css('input'));
|
let deInput: DebugElement = fixture.debugElement.query(By.css("input"));
|
||||||
expect(deInput).toBeTruthy();
|
expect(deInput).toBeTruthy();
|
||||||
let elInput: HTMLElement = deInput.nativeElement;
|
let elInput: HTMLElement = deInput.nativeElement;
|
||||||
expect(elInput).toBeTruthy();
|
expect(elInput).toBeTruthy();
|
||||||
expect(elInput.textContent).toEqual('target_01');
|
expect(elInput.textContent).toEqual("target_01");
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
});
|
});
|
@ -11,43 +11,55 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, OnInit, OnDestroy, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
import {
|
||||||
import { Endpoint, ReplicationRule } from '../service/interface';
|
Component,
|
||||||
import { EndpointService } from '../service/endpoint.service';
|
OnInit,
|
||||||
|
OnDestroy,
|
||||||
|
ViewChild,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorRef
|
||||||
|
} from "@angular/core";
|
||||||
|
import { Endpoint } from "../service/interface";
|
||||||
|
import { EndpointService } from "../service/endpoint.service";
|
||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
import { ErrorHandler } from '../error-handler/index';
|
import { ErrorHandler } from "../error-handler/index";
|
||||||
|
|
||||||
import { ConfirmationMessage } from '../confirmation-dialog/confirmation-message';
|
import { ConfirmationMessage } from "../confirmation-dialog/confirmation-message";
|
||||||
import { ConfirmationAcknowledgement } from '../confirmation-dialog/confirmation-state-message';
|
import { ConfirmationAcknowledgement } from "../confirmation-dialog/confirmation-state-message";
|
||||||
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation-dialog.component";
|
||||||
|
|
||||||
import { ConfirmationTargets, ConfirmationState, ConfirmationButtons } from '../shared/shared.const';
|
import {
|
||||||
|
ConfirmationTargets,
|
||||||
|
ConfirmationState,
|
||||||
|
ConfirmationButtons
|
||||||
|
} from "../shared/shared.const";
|
||||||
|
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from "rxjs/Subscription";
|
||||||
|
|
||||||
import { CreateEditEndpointComponent } from '../create-edit-endpoint/create-edit-endpoint.component';
|
import { CreateEditEndpointComponent } from "../create-edit-endpoint/create-edit-endpoint.component";
|
||||||
|
|
||||||
import { toPromise, CustomComparator } from '../utils';
|
import { toPromise, CustomComparator } from "../utils";
|
||||||
|
|
||||||
import { State, Comparator } from 'clarity-angular';
|
import { Comparator } from "clarity-angular";
|
||||||
import {BatchInfo, BathInfoChanges} from "../confirmation-dialog/confirmation-batch-message";
|
import {
|
||||||
|
BatchInfo,
|
||||||
|
BathInfoChanges
|
||||||
|
} from "../confirmation-dialog/confirmation-batch-message";
|
||||||
import { Observable } from "rxjs/Observable";
|
import { Observable } from "rxjs/Observable";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-endpoint',
|
selector: "hbr-endpoint",
|
||||||
templateUrl: './endpoint.component.html',
|
templateUrl: "./endpoint.component.html",
|
||||||
styleUrls: ['./endpoint.component.scss'],
|
styleUrls: ["./endpoint.component.scss"],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class EndpointComponent implements OnInit, OnDestroy {
|
export class EndpointComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@ViewChild(CreateEditEndpointComponent)
|
@ViewChild(CreateEditEndpointComponent)
|
||||||
createEditEndpointComponent: CreateEditEndpointComponent;
|
createEditEndpointComponent: CreateEditEndpointComponent;
|
||||||
|
|
||||||
|
@ViewChild("confirmationDialog")
|
||||||
@ViewChild('confirmationDialog')
|
|
||||||
confirmationDialogComponent: ConfirmationDialogComponent;
|
confirmationDialogComponent: ConfirmationDialogComponent;
|
||||||
|
|
||||||
targets: Endpoint[];
|
targets: Endpoint[];
|
||||||
@ -58,7 +70,10 @@ export class EndpointComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
loading: boolean = false;
|
loading: boolean = false;
|
||||||
|
|
||||||
creationTimeComparator: Comparator<Endpoint> = new CustomComparator<Endpoint>('creation_time', 'date');
|
creationTimeComparator: Comparator<Endpoint> = new CustomComparator<Endpoint>(
|
||||||
|
"creation_time",
|
||||||
|
"date"
|
||||||
|
);
|
||||||
|
|
||||||
timerHandler: any;
|
timerHandler: any;
|
||||||
selectedRow: Endpoint[] = [];
|
selectedRow: Endpoint[] = [];
|
||||||
@ -79,12 +94,13 @@ export class EndpointComponent implements OnInit, OnDestroy {
|
|||||||
private endpointService: EndpointService,
|
private endpointService: EndpointService,
|
||||||
private errorHandler: ErrorHandler,
|
private errorHandler: ErrorHandler,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
private ref: ChangeDetectorRef) {
|
private ref: ChangeDetectorRef
|
||||||
|
) {
|
||||||
this.forceRefreshView(1000);
|
this.forceRefreshView(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.targetName = '';
|
this.targetName = "";
|
||||||
this.retrieve();
|
this.retrieve();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,14 +116,13 @@ export class EndpointComponent implements OnInit, OnDestroy {
|
|||||||
retrieve(): void {
|
retrieve(): void {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.selectedRow = [];
|
this.selectedRow = [];
|
||||||
toPromise<Endpoint[]>(this.endpointService
|
toPromise<Endpoint[]>(this.endpointService.getEndpoints(this.targetName))
|
||||||
.getEndpoints(this.targetName))
|
.then(targets => {
|
||||||
.then(
|
|
||||||
targets => {
|
|
||||||
this.targets = targets || [];
|
this.targets = targets || [];
|
||||||
this.forceRefreshView(1000);
|
this.forceRefreshView(1000);
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
}).catch(error => {
|
})
|
||||||
|
.catch(error => {
|
||||||
this.errorHandler.error(error);
|
this.errorHandler.error(error);
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
@ -123,7 +138,7 @@ export class EndpointComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reload($event: any) {
|
reload($event: any) {
|
||||||
this.targetName = '';
|
this.targetName = "";
|
||||||
this.retrieve();
|
this.retrieve();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,26 +170,29 @@ export class EndpointComponent implements OnInit, OnDestroy {
|
|||||||
this.batchDelectionInfos.push(initBatchMessage);
|
this.batchDelectionInfos.push(initBatchMessage);
|
||||||
});
|
});
|
||||||
let deletionMessage = new ConfirmationMessage(
|
let deletionMessage = new ConfirmationMessage(
|
||||||
'REPLICATION.DELETION_TITLE_TARGET',
|
"REPLICATION.DELETION_TITLE_TARGET",
|
||||||
'REPLICATION.DELETION_SUMMARY_TARGET',
|
"REPLICATION.DELETION_SUMMARY_TARGET",
|
||||||
targetNames.join(', ') || '',
|
targetNames.join(", ") || "",
|
||||||
targets,
|
targets,
|
||||||
ConfirmationTargets.TARGET,
|
ConfirmationTargets.TARGET,
|
||||||
ConfirmationButtons.DELETE_CANCEL);
|
ConfirmationButtons.DELETE_CANCEL
|
||||||
|
);
|
||||||
this.confirmationDialogComponent.open(deletionMessage);
|
this.confirmationDialogComponent.open(deletionMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
confirmDeletion(message: ConfirmationAcknowledgement) {
|
confirmDeletion(message: ConfirmationAcknowledgement) {
|
||||||
if (message &&
|
if (
|
||||||
|
message &&
|
||||||
message.source === ConfirmationTargets.TARGET &&
|
message.source === ConfirmationTargets.TARGET &&
|
||||||
message.state === ConfirmationState.CONFIRMED) {
|
message.state === ConfirmationState.CONFIRMED
|
||||||
|
) {
|
||||||
let targetLists: Endpoint[] = message.data;
|
let targetLists: Endpoint[] = message.data;
|
||||||
if (targetLists && targetLists.length) {
|
if (targetLists && targetLists.length) {
|
||||||
let promiseLists: any[] = [];
|
let promiseLists: any[] = [];
|
||||||
targetLists.forEach(target => {
|
targetLists.forEach(target => {
|
||||||
promiseLists.push(this.delOperate(target.id, target.name));
|
promiseLists.push(this.delOperate(target.id, target.name));
|
||||||
})
|
});
|
||||||
Promise.all(promiseLists).then((item) => {
|
Promise.all(promiseLists).then(item => {
|
||||||
this.selectedRow = [];
|
this.selectedRow = [];
|
||||||
this.reload(true);
|
this.reload(true);
|
||||||
this.forceRefreshView(2000);
|
this.forceRefreshView(2000);
|
||||||
@ -185,23 +203,30 @@ export class EndpointComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
delOperate(id: number | string, name: string) {
|
delOperate(id: number | string, name: string) {
|
||||||
let findedList = this.batchDelectionInfos.find(data => data.name === name);
|
let findedList = this.batchDelectionInfos.find(data => data.name === name);
|
||||||
return toPromise<number>(this.endpointService
|
return toPromise<number>(this.endpointService.deleteEndpoint(id))
|
||||||
.deleteEndpoint(id))
|
.then(response => {
|
||||||
.then(
|
this.translateService.get("BATCH.DELETED_SUCCESS").subscribe(res => {
|
||||||
response => {
|
|
||||||
this.translateService.get('BATCH.DELETED_SUCCESS')
|
|
||||||
.subscribe(res => {
|
|
||||||
findedList = BathInfoChanges(findedList, res);
|
findedList = BathInfoChanges(findedList, res);
|
||||||
});
|
});
|
||||||
}).catch(
|
})
|
||||||
error => {
|
.catch(error => {
|
||||||
if (error && error.status === 412) {
|
if (error && error.status === 412) {
|
||||||
Observable.forkJoin(this.translateService.get('BATCH.DELETED_FAILURE'),
|
Observable.forkJoin(
|
||||||
this.translateService.get('DESTINATION.FAILED_TO_DELETE_TARGET_IN_USED')).subscribe(res => {
|
this.translateService.get("BATCH.DELETED_FAILURE"),
|
||||||
findedList = BathInfoChanges(findedList, res[0], false, true, res[1]);
|
this.translateService.get(
|
||||||
|
"DESTINATION.FAILED_TO_DELETE_TARGET_IN_USED"
|
||||||
|
)
|
||||||
|
).subscribe(res => {
|
||||||
|
findedList = BathInfoChanges(
|
||||||
|
findedList,
|
||||||
|
res[0],
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
res[1]
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.translateService.get('BATCH.DELETED_FAILURE').subscribe(res => {
|
this.translateService.get("BATCH.DELETED_FAILURE").subscribe(res => {
|
||||||
findedList = BathInfoChanges(findedList, res, false, true);
|
findedList = BathInfoChanges(findedList, res, false, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import { Type } from '@angular/core';
|
import { Type } from "@angular/core";
|
||||||
import { EndpointComponent } from './endpoint.component';
|
import { EndpointComponent } from "./endpoint.component";
|
||||||
|
|
||||||
|
export const ENDPOINT_DIRECTIVES: Type<any>[] = [EndpointComponent];
|
||||||
export const ENDPOINT_DIRECTIVES: Type<any>[] = [
|
|
||||||
EndpointComponent
|
|
||||||
];
|
|
||||||
|
@ -49,7 +49,6 @@ export abstract class ErrorHandler {
|
|||||||
abstract log(log: any): void;
|
abstract log(log: any): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DefaultErrorHandler extends ErrorHandler {
|
export class DefaultErrorHandler extends ErrorHandler {
|
||||||
public error(error: any): void {
|
public error(error: any): void {
|
||||||
@ -61,6 +60,7 @@ export class DefaultErrorHandler extends ErrorHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public info(info: any): void {
|
public info(info: any): void {
|
||||||
|
// tslint:disable-next-line:no-console
|
||||||
console.info("[Default info handler]: ", info);
|
console.info("[Default info handler]: ", info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
export * from './error-handler';
|
export * from "./error-handler";
|
||||||
|
@ -11,27 +11,23 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, Input, Output, OnInit, EventEmitter } from '@angular/core';
|
import { Component, Input, Output, OnInit, EventEmitter } from "@angular/core";
|
||||||
import { Subject } from 'rxjs/Subject';
|
import { Subject } from "rxjs/Subject";
|
||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
|
|
||||||
import 'rxjs/add/operator/debounceTime';
|
|
||||||
import 'rxjs/add/operator/distinctUntilChanged';
|
|
||||||
|
|
||||||
|
import "rxjs/add/operator/debounceTime";
|
||||||
|
import "rxjs/add/operator/distinctUntilChanged";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-filter',
|
selector: "hbr-filter",
|
||||||
templateUrl: './filter.component.html',
|
templateUrl: "./filter.component.html",
|
||||||
styleUrls: ['./filter.component.scss']
|
styleUrls: ["./filter.component.scss"]
|
||||||
})
|
})
|
||||||
|
|
||||||
export class FilterComponent implements OnInit {
|
export class FilterComponent implements OnInit {
|
||||||
|
|
||||||
placeHolder: string = "";
|
placeHolder: string = "";
|
||||||
filterTerms = new Subject<string>();
|
filterTerms = new Subject<string>();
|
||||||
isExpanded: boolean = false;
|
isExpanded: boolean = false;
|
||||||
|
|
||||||
@Output("filter") private filterEvt = new EventEmitter<string>();
|
@Output() private filterEvt = new EventEmitter<string>();
|
||||||
@Output() private openFlag = new EventEmitter<boolean>();
|
@Output() private openFlag = new EventEmitter<boolean>();
|
||||||
|
|
||||||
@Input() currentValue: string;
|
@Input() currentValue: string;
|
||||||
@ -45,11 +41,9 @@ export class FilterComponent implements OnInit {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.filterTerms
|
this.filterTerms
|
||||||
.debounceTime(500)
|
.debounceTime(500)
|
||||||
//.distinctUntilChanged()
|
|
||||||
.subscribe(terms => {
|
.subscribe(terms => {
|
||||||
this.filterEvt.emit(terms);
|
this.filterEvt.emit(terms);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
valueChange(): void {
|
valueChange(): void {
|
||||||
|
@ -9,19 +9,28 @@
|
|||||||
* conditions of the subcomponent's license, as noted in the LICENSE file.
|
* conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, Input, Output, SimpleChanges, ContentChild, ViewChild, ViewChildren,
|
import {
|
||||||
TemplateRef, HostListener, ViewEncapsulation, EventEmitter, AfterViewInit } from '@angular/core';
|
Component,
|
||||||
import { CancelablePromise } from '../shared/shared.utils';
|
Input,
|
||||||
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
|
Output,
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
ContentChild,
|
||||||
|
ViewChild,
|
||||||
|
ViewChildren,
|
||||||
|
TemplateRef,
|
||||||
|
HostListener,
|
||||||
|
ViewEncapsulation,
|
||||||
|
EventEmitter,
|
||||||
|
AfterViewInit
|
||||||
|
} from "@angular/core";
|
||||||
|
import { Subscription } from "rxjs/Subscription";
|
||||||
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { ScrollPosition } from "../service/interface";
|
||||||
import { ScrollPosition } from '../service/interface'
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-gridview',
|
selector: "hbr-gridview",
|
||||||
templateUrl: './grid-view.component.html',
|
templateUrl: "./grid-view.component.html",
|
||||||
styleUrls: ['./grid-view.component.scss'],
|
styleUrls: ["./grid-view.component.scss"],
|
||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
/**
|
/**
|
||||||
@ -41,8 +50,8 @@ export class GridViewComponent implements AfterViewInit {
|
|||||||
return this.cardStyles[index];
|
return this.cardStyles[index];
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
opacity: '0',
|
opacity: "0",
|
||||||
overflow: 'hidden'
|
overflow: "hidden"
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
this.cardStyles = newCardStyles;
|
this.cardStyles = newCardStyles;
|
||||||
@ -51,8 +60,8 @@ export class GridViewComponent implements AfterViewInit {
|
|||||||
|
|
||||||
@Output() loadNextPageEvent = new EventEmitter<any>();
|
@Output() loadNextPageEvent = new EventEmitter<any>();
|
||||||
|
|
||||||
@ViewChildren('cardItem') cards: any;
|
@ViewChildren("cardItem") cards: any;
|
||||||
@ViewChild('itemsHolder') itemsHolder: any;
|
@ViewChild("itemsHolder") itemsHolder: any;
|
||||||
@ContentChild(TemplateRef) gridItemTmpl: any;
|
@ContentChild(TemplateRef) gridItemTmpl: any;
|
||||||
|
|
||||||
_items: any[] = [];
|
_items: any[] = [];
|
||||||
@ -91,19 +100,20 @@ export class GridViewComponent implements AfterViewInit {
|
|||||||
return this._items;
|
return this._items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('scroll', ['$event'])
|
@HostListener("scroll", ["$event"])
|
||||||
onScroll(event: any) {
|
onScroll(event: any) {
|
||||||
|
|
||||||
this.preScrollPosition = this.CurrentScrollPosition;
|
this.preScrollPosition = this.CurrentScrollPosition;
|
||||||
this.CurrentScrollPosition = {
|
this.CurrentScrollPosition = {
|
||||||
sH: event.target.scrollHeight,
|
sH: event.target.scrollHeight,
|
||||||
sT: event.target.scrollTop,
|
sT: event.target.scrollTop,
|
||||||
cH: event.target.clientHeight
|
cH: event.target.clientHeight
|
||||||
}
|
};
|
||||||
if (!this.loading
|
if (
|
||||||
&& this.isScrollDown()
|
!this.loading &&
|
||||||
&& this.isScrollExpectPercent()
|
this.isScrollDown() &&
|
||||||
&& (this.currentPage * this.pageSize < this.totalCount)) {
|
this.isScrollExpectPercent() &&
|
||||||
|
this.currentPage * this.pageSize < this.totalCount
|
||||||
|
) {
|
||||||
this.loadNextPageEvent.emit();
|
this.loadNextPageEvent.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,10 +123,14 @@ export class GridViewComponent implements AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isScrollExpectPercent(): boolean {
|
isScrollExpectPercent(): boolean {
|
||||||
return ((this.CurrentScrollPosition.sT + this.CurrentScrollPosition.cH) / this.CurrentScrollPosition.sH) > (this.expectScrollPercent / 100);
|
return (
|
||||||
|
(this.CurrentScrollPosition.sT + this.CurrentScrollPosition.cH) /
|
||||||
|
this.CurrentScrollPosition.sH >
|
||||||
|
this.expectScrollPercent / 100
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('window:resize')
|
@HostListener("window:resize")
|
||||||
onResize(event: any) {
|
onResize(event: any) {
|
||||||
this.throttleLayout();
|
this.throttleLayout();
|
||||||
}
|
}
|
||||||
@ -136,7 +150,7 @@ export class GridViewComponent implements AfterViewInit {
|
|||||||
let el = this.itemsHolder.nativeElement;
|
let el = this.itemsHolder.nativeElement;
|
||||||
|
|
||||||
let width = el.offsetWidth;
|
let width = el.offsetWidth;
|
||||||
let items = el.querySelectorAll('.card-item');
|
let items = el.querySelectorAll(".card-item");
|
||||||
let items_count = items.length;
|
let items_count = items.length;
|
||||||
if (items_count === 0) {
|
if (items_count === 0) {
|
||||||
el.height = 0;
|
el.height = 0;
|
||||||
@ -158,17 +172,24 @@ export class GridViewComponent implements AfterViewInit {
|
|||||||
let maxWidth = parseInt(maxWidthStyle, 10);
|
let maxWidth = parseInt(maxWidthStyle, 10);
|
||||||
|
|
||||||
let marginHeight: number =
|
let marginHeight: number =
|
||||||
parseInt(itemsStyle.marginTop, 10) + parseInt(itemsStyle.marginBottom, 10);
|
parseInt(itemsStyle.marginTop, 10) +
|
||||||
|
parseInt(itemsStyle.marginBottom, 10);
|
||||||
let marginWidth: number =
|
let marginWidth: number =
|
||||||
parseInt(itemsStyle.marginLeft, 10) + parseInt(itemsStyle.marginRight, 10);
|
parseInt(itemsStyle.marginLeft, 10) +
|
||||||
|
parseInt(itemsStyle.marginRight, 10);
|
||||||
|
|
||||||
let columns = Math.floor(width / (minWidth + marginWidth));
|
let columns = Math.floor(width / (minWidth + marginWidth));
|
||||||
|
|
||||||
let columnsToUse = Math.max(Math.min(columns, items_count), 1);
|
let columnsToUse = Math.max(Math.min(columns, items_count), 1);
|
||||||
let rows = Math.floor(items_count / columnsToUse);
|
let rows = Math.floor(items_count / columnsToUse);
|
||||||
let itemWidth = Math.min(Math.floor(width / columnsToUse) - marginWidth, maxWidth);
|
let itemWidth = Math.min(
|
||||||
let itemSpacing = columnsToUse === 1 || columns > items_count ? marginWidth :
|
Math.floor(width / columnsToUse) - marginWidth,
|
||||||
(width - marginWidth - columnsToUse * itemWidth) / (columnsToUse - 1);
|
maxWidth
|
||||||
|
);
|
||||||
|
let itemSpacing =
|
||||||
|
columnsToUse === 1 || columns > items_count
|
||||||
|
? marginWidth
|
||||||
|
: (width - marginWidth - columnsToUse * itemWidth) / (columnsToUse - 1);
|
||||||
if (!this.withAdmiral) {
|
if (!this.withAdmiral) {
|
||||||
// Fixed spacing and margin on standalone mode
|
// Fixed spacing and margin on standalone mode
|
||||||
itemSpacing = marginWidth;
|
itemSpacing = marginWidth;
|
||||||
@ -176,7 +197,11 @@ export class GridViewComponent implements AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let visible = items_count;
|
let visible = items_count;
|
||||||
if (this.hidePartialRows && this.totalItemsCount && items_count !== this.totalItemsCount) {
|
if (
|
||||||
|
this.hidePartialRows &&
|
||||||
|
this.totalItemsCount &&
|
||||||
|
items_count !== this.totalItemsCount
|
||||||
|
) {
|
||||||
visible = rows * columnsToUse;
|
visible = rows * columnsToUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,27 +216,27 @@ export class GridViewComponent implements AfterViewInit {
|
|||||||
// trick to show nice apear animation, where the item is already positioned,
|
// trick to show nice apear animation, where the item is already positioned,
|
||||||
// but it will pop out
|
// but it will pop out
|
||||||
let oldTransform = itemStyle.transform;
|
let oldTransform = itemStyle.transform;
|
||||||
if (!oldTransform || oldTransform === 'none') {
|
if (!oldTransform || oldTransform === "none") {
|
||||||
this.cardStyles[i] = {
|
this.cardStyles[i] = {
|
||||||
transform: 'translate(' + left + 'px,' + top + 'px) scale(0)',
|
transform: "translate(" + left + "px," + top + "px) scale(0)",
|
||||||
width: itemWidth + 'px',
|
width: itemWidth + "px",
|
||||||
transition: 'none',
|
transition: "none",
|
||||||
overflow: 'hidden'
|
overflow: "hidden"
|
||||||
};
|
};
|
||||||
this.throttleLayout();
|
this.throttleLayout();
|
||||||
} else {
|
} else {
|
||||||
this.cardStyles[i] = {
|
this.cardStyles[i] = {
|
||||||
transform: 'translate(' + left + 'px,' + top + 'px) scale(1)',
|
transform: "translate(" + left + "px," + top + "px) scale(1)",
|
||||||
width: itemWidth + 'px',
|
width: itemWidth + "px",
|
||||||
transition: null,
|
transition: null,
|
||||||
overflow: 'hidden'
|
overflow: "hidden"
|
||||||
};
|
};
|
||||||
this.throttleLayout();
|
this.throttleLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item.classList.contains('context-selected')) {
|
if (!item.classList.contains("context-selected")) {
|
||||||
let itemHeight = itemsHeight[i];
|
let itemHeight = itemsHeight[i];
|
||||||
if (itemStyle.display === 'none' && itemHeight !== 0) {
|
if (itemStyle.display === "none" && itemHeight !== 0) {
|
||||||
this.cardStyles[i].display = null;
|
this.cardStyles[i].display = null;
|
||||||
}
|
}
|
||||||
if (itemHeight !== 0) {
|
if (itemHeight !== 0) {
|
||||||
@ -222,20 +247,20 @@ export class GridViewComponent implements AfterViewInit {
|
|||||||
|
|
||||||
for (let i = visible; i < items_count; i++) {
|
for (let i = visible; i < items_count; i++) {
|
||||||
this.cardStyles[i] = {
|
this.cardStyles[i] = {
|
||||||
display: 'none'
|
display: "none"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
this.itemsHolderStyle = {
|
this.itemsHolderStyle = {
|
||||||
height: Math.ceil(count / columnsToUse) * (height + marginHeight) + 'px'
|
height: Math.ceil(count / columnsToUse) * (height + marginHeight) + "px"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
onCardEnter(i: number) {
|
onCardEnter(i: number) {
|
||||||
this.cardStyles[i].overflow = 'visible';
|
this.cardStyles[i].overflow = "visible";
|
||||||
}
|
}
|
||||||
|
|
||||||
onCardLeave(i: number) {
|
onCardLeave(i: number) {
|
||||||
this.cardStyles[i].overflow = 'hidden';
|
this.cardStyles[i].overflow = "hidden";
|
||||||
}
|
}
|
||||||
|
|
||||||
trackByFn(index: number, item: any) {
|
trackByFn(index: number, item: any) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { NgModule, ModuleWithProviders, Provider, APP_INITIALIZER, Inject } from '@angular/core';
|
import { NgModule, ModuleWithProviders, Provider, APP_INITIALIZER } from '@angular/core';
|
||||||
|
|
||||||
import { LOG_DIRECTIVES } from './log/index';
|
import { LOG_DIRECTIVES } from './log/index';
|
||||||
import { FILTER_DIRECTIVES } from './filter/index';
|
import { FILTER_DIRECTIVES } from './filter/index';
|
||||||
@ -99,43 +99,43 @@ export const DefaultServiceConfig: IServiceConfig = {
|
|||||||
*/
|
*/
|
||||||
export interface HarborModuleConfig {
|
export interface HarborModuleConfig {
|
||||||
// Service endpoints
|
// Service endpoints
|
||||||
config?: Provider,
|
config?: Provider;
|
||||||
|
|
||||||
// Handling error messages
|
// Handling error messages
|
||||||
errorHandler?: Provider,
|
errorHandler?: Provider;
|
||||||
|
|
||||||
// Service implementation for system info
|
// Service implementation for system info
|
||||||
systemInfoService?: Provider,
|
systemInfoService?: Provider;
|
||||||
|
|
||||||
// Service implementation for log
|
// Service implementation for log
|
||||||
logService?: Provider,
|
logService?: Provider;
|
||||||
|
|
||||||
// Service implementation for endpoint
|
// Service implementation for endpoint
|
||||||
endpointService?: Provider,
|
endpointService?: Provider;
|
||||||
|
|
||||||
// Service implementation for replication
|
// Service implementation for replication
|
||||||
replicationService?: Provider,
|
replicationService?: Provider;
|
||||||
|
|
||||||
// Service implementation for repository
|
// Service implementation for repository
|
||||||
repositoryService?: Provider,
|
repositoryService?: Provider;
|
||||||
|
|
||||||
// Service implementation for tag
|
// Service implementation for tag
|
||||||
tagService?: Provider,
|
tagService?: Provider;
|
||||||
|
|
||||||
// Service implementation for vulnerability scanning
|
// Service implementation for vulnerability scanning
|
||||||
scanningService?: Provider,
|
scanningService?: Provider;
|
||||||
|
|
||||||
// Service implementation for configuration
|
// Service implementation for configuration
|
||||||
configService?: Provider,
|
configService?: Provider;
|
||||||
|
|
||||||
// Service implementation for job log
|
// Service implementation for job log
|
||||||
jobLogService?: Provider,
|
jobLogService?: Provider;
|
||||||
|
|
||||||
// Service implementation for project policy
|
// Service implementation for project policy
|
||||||
projectPolicyService?: Provider,
|
projectPolicyService?: Provider;
|
||||||
|
|
||||||
// Service implementation for label
|
// Service implementation for label
|
||||||
labelService?: Provider,
|
labelService?: Provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
export interface i18nConfig {
|
export interface I18nConfig {
|
||||||
/**
|
/**
|
||||||
* The cookie key used to store the current used language preference.
|
* The cookie key used to store the current used language preference.
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
* @memberOf IServiceConfig
|
* @memberOf IServiceConfig
|
||||||
*/
|
*/
|
||||||
langCookieKey?: string,
|
langCookieKey?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare what languages are supported.
|
* Declare what languages are supported.
|
||||||
@ -13,13 +13,13 @@ export interface i18nConfig {
|
|||||||
* @type {string[]}
|
* @type {string[]}
|
||||||
* @memberOf IServiceConfig
|
* @memberOf IServiceConfig
|
||||||
*/
|
*/
|
||||||
supportedLangs?: string[],
|
supportedLangs?: string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define the default language the translate service uses.
|
* Define the default language the translate service uses.
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
* @memberOf i18nConfig
|
* @memberOf I18nConfig
|
||||||
*/
|
*/
|
||||||
defaultLang?: string;
|
defaultLang?: string;
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
export * from './translate-init.service';
|
export * from "./translate-init.service";
|
||||||
export * from './i18n-config';
|
export * from "./i18n-config";
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { TranslateLoader } from '@ngx-translate/core';
|
import { TranslateLoader } from "@ngx-translate/core";
|
||||||
import 'rxjs/add/observable/of';
|
import "rxjs/add/observable/of";
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from "rxjs/Observable";
|
||||||
|
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import { IServiceConfig } from "../service.config";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare a translation loader with local json object
|
* Declare a translation loader with local json object
|
||||||
@ -17,10 +17,12 @@ export class TranslatorJsonLoader extends TranslateLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTranslation(lang: string): Observable<any> {
|
getTranslation(lang: string): Observable<any> {
|
||||||
let dict: any = this.config &&
|
let dict: any =
|
||||||
|
this.config &&
|
||||||
this.config.localI18nMessageVariableMap &&
|
this.config.localI18nMessageVariableMap &&
|
||||||
this.config.localI18nMessageVariableMap[lang] ?
|
this.config.localI18nMessageVariableMap[lang]
|
||||||
this.config.localI18nMessageVariableMap[lang] : {};
|
? this.config.localI18nMessageVariableMap[lang]
|
||||||
|
: {};
|
||||||
return Observable.of(dict);
|
return Observable.of(dict);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,7 +11,10 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { MissingTranslationHandler, MissingTranslationHandlerParams } from '@ngx-translate/core';
|
import {
|
||||||
|
MissingTranslationHandler,
|
||||||
|
MissingTranslationHandlerParams
|
||||||
|
} from "@ngx-translate/core";
|
||||||
|
|
||||||
export class MyMissingTranslationHandler implements MissingTranslationHandler {
|
export class MyMissingTranslationHandler implements MissingTranslationHandler {
|
||||||
handle(params: MissingTranslationHandlerParams) {
|
handle(params: MissingTranslationHandlerParams) {
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
import { i18nConfig } from "./i18n-config";
|
import { I18nConfig } from "./i18n-config";
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
import { DEFAULT_LANG_COOKIE_KEY, DEFAULT_SUPPORTING_LANGS, DEFAULT_LANG } from '../utils';
|
import {
|
||||||
import { CookieService } from 'ngx-cookie';
|
DEFAULT_LANG_COOKIE_KEY,
|
||||||
|
DEFAULT_SUPPORTING_LANGS,
|
||||||
|
DEFAULT_LANG
|
||||||
|
} from "../utils";
|
||||||
|
import { CookieService } from "ngx-cookie";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TranslateServiceInitializer {
|
export class TranslateServiceInitializer {
|
||||||
@ -11,19 +15,27 @@ export class TranslateServiceInitializer {
|
|||||||
private cookie: CookieService
|
private cookie: CookieService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public init(config: i18nConfig = {}): void {
|
public init(config: I18nConfig = {}): void {
|
||||||
let selectedLang: string = config.defaultLang ? config.defaultLang : DEFAULT_LANG;
|
let selectedLang: string = config.defaultLang
|
||||||
let supportedLangs: string[] = config.supportedLangs ? config.supportedLangs : DEFAULT_SUPPORTING_LANGS;
|
? config.defaultLang
|
||||||
|
: DEFAULT_LANG;
|
||||||
|
let supportedLangs: string[] = config.supportedLangs
|
||||||
|
? config.supportedLangs
|
||||||
|
: DEFAULT_SUPPORTING_LANGS;
|
||||||
|
|
||||||
this.translateService.addLangs(supportedLangs);
|
this.translateService.addLangs(supportedLangs);
|
||||||
this.translateService.setDefaultLang(selectedLang);
|
this.translateService.setDefaultLang(selectedLang);
|
||||||
|
|
||||||
if (config.enablei18Support) {
|
if (config.enablei18Support) {
|
||||||
// If user has selected lang, then directly use it
|
// If user has selected lang, then directly use it
|
||||||
let langSetting: string = this.cookie.get(config.langCookieKey ? config.langCookieKey : DEFAULT_LANG_COOKIE_KEY);
|
let langSetting: string = this.cookie.get(
|
||||||
|
config.langCookieKey ? config.langCookieKey : DEFAULT_LANG_COOKIE_KEY
|
||||||
|
);
|
||||||
if (!langSetting || langSetting.trim() === "") {
|
if (!langSetting || langSetting.trim() === "") {
|
||||||
// Use browser lang
|
// Use browser lang
|
||||||
langSetting = this.translateService.getBrowserCultureLang().toLowerCase();
|
langSetting = this.translateService
|
||||||
|
.getBrowserCultureLang()
|
||||||
|
.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (langSetting && langSetting.trim() !== "") {
|
if (langSetting && langSetting.trim() !== "") {
|
||||||
|
@ -1,25 +1,26 @@
|
|||||||
import { TestBed, inject } from '@angular/core/testing';
|
import { TestBed, inject } from "@angular/core/testing";
|
||||||
import { SharedModule } from '../shared/shared.module';
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
import { DEFAULT_LANG } from '../utils';
|
|
||||||
|
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import { SharedModule } from "../shared/shared.module";
|
||||||
|
import { DEFAULT_LANG } from "../utils";
|
||||||
|
|
||||||
|
import { SERVICE_CONFIG, IServiceConfig } from "../service.config";
|
||||||
|
|
||||||
const EN_US_LANG: any = {
|
const EN_US_LANG: any = {
|
||||||
"SIGN_UP": {
|
SIGN_UP: {
|
||||||
"TITLE": "Sign Up"
|
TITLE: "Sign Up"
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const ZH_CN_LANG: any = {
|
const ZH_CN_LANG: any = {
|
||||||
"SIGN_UP": {
|
SIGN_UP: {
|
||||||
"TITLE": "注册"
|
TITLE: "注册"
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
describe('TranslateService', () => {
|
describe("TranslateService", () => {
|
||||||
let testConfig: IServiceConfig = {
|
let testConfig: IServiceConfig = {
|
||||||
langMessageLoader: 'local',
|
langMessageLoader: "local",
|
||||||
localI18nMessageVariableMap: {
|
localI18nMessageVariableMap: {
|
||||||
"en-us": EN_US_LANG,
|
"en-us": EN_US_LANG,
|
||||||
"zh-cn": ZH_CN_LANG
|
"zh-cn": ZH_CN_LANG
|
||||||
@ -27,37 +28,49 @@ describe('TranslateService', () => {
|
|||||||
};
|
};
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [SharedModule],
|
||||||
SharedModule
|
providers: [
|
||||||
],
|
{
|
||||||
providers: [{
|
provide: SERVICE_CONFIG,
|
||||||
provide: SERVICE_CONFIG, useValue: testConfig
|
useValue: testConfig
|
||||||
}]
|
}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be initialized', inject([TranslateService], (service: TranslateService) => {
|
it(
|
||||||
|
"should be initialized",
|
||||||
|
inject([TranslateService], (service: TranslateService) => {
|
||||||
expect(service).toBeTruthy();
|
expect(service).toBeTruthy();
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
it('should use the specified lang', inject([TranslateService], (service: TranslateService) => {
|
it(
|
||||||
|
"should use the specified lang",
|
||||||
|
inject([TranslateService], (service: TranslateService) => {
|
||||||
service.use(DEFAULT_LANG).subscribe(() => {
|
service.use(DEFAULT_LANG).subscribe(() => {
|
||||||
expect(service.currentLang).toEqual(DEFAULT_LANG);
|
expect(service.currentLang).toEqual(DEFAULT_LANG);
|
||||||
});
|
});
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
it('should translate key to text [en-us]', inject([TranslateService], (service: TranslateService) => {
|
it(
|
||||||
|
"should translate key to text [en-us]",
|
||||||
|
inject([TranslateService], (service: TranslateService) => {
|
||||||
service.use(DEFAULT_LANG);
|
service.use(DEFAULT_LANG);
|
||||||
service.get('SIGN_UP.TITLE').subscribe(text => {
|
service.get("SIGN_UP.TITLE").subscribe(text => {
|
||||||
expect(text).toEqual('Sign Up');
|
expect(text).toEqual("Sign Up");
|
||||||
});
|
});
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
it('should translate key to text [zh-cn]', inject([TranslateService], (service: TranslateService) => {
|
it(
|
||||||
service.use('zh-cn');
|
"should translate key to text [zh-cn]",
|
||||||
service.get('SIGN_UP.TITLE').subscribe(text => {
|
inject([TranslateService], (service: TranslateService) => {
|
||||||
expect(text).toEqual('注册');
|
service.use("zh-cn");
|
||||||
|
service.get("SIGN_UP.TITLE").subscribe(text => {
|
||||||
|
expect(text).toEqual("注册");
|
||||||
});
|
});
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
@ -11,20 +11,21 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, Output, EventEmitter } from "@angular/core";
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
import { errorHandler } from '../shared/shared.utils';
|
import { errorHandler } from "../shared/shared.utils";
|
||||||
import { Observable } from 'rxjs/Rx';
|
// tslint:disable-next-line:no-unused-variable
|
||||||
import { Subscription } from "rxjs";
|
import { Observable } from "rxjs/Observable";
|
||||||
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-inline-alert',
|
selector: "hbr-inline-alert",
|
||||||
templateUrl: './inline-alert.component.html',
|
templateUrl: "./inline-alert.component.html",
|
||||||
styleUrls: [ './inline-alert.component.scss' ]
|
styleUrls: ["./inline-alert.component.scss"]
|
||||||
})
|
})
|
||||||
export class InlineAlertComponent {
|
export class InlineAlertComponent {
|
||||||
inlineAlertType: string = 'alert-danger';
|
inlineAlertType: string = "alert-danger";
|
||||||
inlineAlertClosable: boolean = false;
|
inlineAlertClosable: boolean = false;
|
||||||
alertClose: boolean = true;
|
alertClose: boolean = true;
|
||||||
displayedText: string = "";
|
displayedText: string = "";
|
||||||
@ -46,10 +47,12 @@ export class InlineAlertComponent {
|
|||||||
public showInlineError(error: any): void {
|
public showInlineError(error: any): void {
|
||||||
this.displayedText = errorHandler(error);
|
this.displayedText = errorHandler(error);
|
||||||
if (this.displayedText) {
|
if (this.displayedText) {
|
||||||
this.translate.get(this.displayedText).subscribe((res: string) => this.displayedText = res);
|
this.translate
|
||||||
|
.get(this.displayedText)
|
||||||
|
.subscribe((res: string) => (this.displayedText = res));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.inlineAlertType = 'alert-danger';
|
this.inlineAlertType = "alert-danger";
|
||||||
this.showCancelAction = false;
|
this.showCancelAction = false;
|
||||||
this.inlineAlertClosable = true;
|
this.inlineAlertClosable = true;
|
||||||
this.alertClose = false;
|
this.alertClose = false;
|
||||||
@ -60,9 +63,11 @@ export class InlineAlertComponent {
|
|||||||
public showInlineConfirmation(warning: any): void {
|
public showInlineConfirmation(warning: any): void {
|
||||||
this.displayedText = "";
|
this.displayedText = "";
|
||||||
if (warning && warning.message) {
|
if (warning && warning.message) {
|
||||||
this.translate.get(warning.message).subscribe((res: string) => this.displayedText = res);
|
this.translate
|
||||||
|
.get(warning.message)
|
||||||
|
.subscribe((res: string) => (this.displayedText = res));
|
||||||
}
|
}
|
||||||
this.inlineAlertType = 'alert-warning';
|
this.inlineAlertType = "alert-warning";
|
||||||
this.showCancelAction = true;
|
this.showCancelAction = true;
|
||||||
this.inlineAlertClosable = false;
|
this.inlineAlertClosable = false;
|
||||||
this.alertClose = false;
|
this.alertClose = false;
|
||||||
@ -73,9 +78,11 @@ export class InlineAlertComponent {
|
|||||||
public showInlineSuccess(info: any): void {
|
public showInlineSuccess(info: any): void {
|
||||||
this.displayedText = "";
|
this.displayedText = "";
|
||||||
if (info && info.message) {
|
if (info && info.message) {
|
||||||
this.translate.get(info.message).subscribe((res: string) => this.displayedText = res);
|
this.translate
|
||||||
|
.get(info.message)
|
||||||
|
.subscribe((res: string) => (this.displayedText = res));
|
||||||
}
|
}
|
||||||
this.inlineAlertType = 'alert-success';
|
this.inlineAlertType = "alert-success";
|
||||||
this.showCancelAction = false;
|
this.showCancelAction = false;
|
||||||
this.inlineAlertClosable = true;
|
this.inlineAlertClosable = true;
|
||||||
this.alertClose = false;
|
this.alertClose = false;
|
||||||
@ -87,8 +94,7 @@ export class InlineAlertComponent {
|
|||||||
this.alertClose = true;
|
this.alertClose = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public blink() {
|
public blink() {}
|
||||||
}
|
|
||||||
|
|
||||||
confirmCancel(): void {
|
confirmCancel(): void {
|
||||||
this.confirmEvt.emit(true);
|
this.confirmEvt.emit(true);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { DebugElement } from '@angular/core';
|
// tslint:disable-next-line:no-unused-variable
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { JobLogService, JobLogDefaultService } from '../service/index';
|
import { JobLogService, JobLogDefaultService } from '../service/index';
|
||||||
|
|
||||||
|
@ -11,26 +11,30 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Input} from '@angular/core';
|
import {
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorRef,
|
||||||
|
Component,
|
||||||
|
Input
|
||||||
|
} from "@angular/core";
|
||||||
|
|
||||||
import { JobLogService } from '../service/index';
|
import { JobLogService } from "../service/index";
|
||||||
import { ErrorHandler } from '../error-handler/index';
|
import { ErrorHandler } from "../error-handler/index";
|
||||||
import { toPromise } from '../utils';
|
import { toPromise } from "../utils";
|
||||||
|
|
||||||
const supportSet: string[] = ["replication", "scan"];
|
const supportSet: string[] = ["replication", "scan"];
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'job-log-viewer',
|
selector: "job-log-viewer",
|
||||||
templateUrl: './job-log-viewer.component.html',
|
templateUrl: "./job-log-viewer.component.html",
|
||||||
styleUrls: ['./job-log-viewer.component.scss'],
|
styleUrls: ["./job-log-viewer.component.scss"],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
|
|
||||||
export class JobLogViewerComponent {
|
export class JobLogViewerComponent {
|
||||||
_jobType: string = "replication";
|
_jobType: string = "replication";
|
||||||
|
|
||||||
opened: boolean = false;
|
opened: boolean = false;
|
||||||
log: string = '';
|
log: string = "";
|
||||||
onGoing: boolean = true;
|
onGoing: boolean = true;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
|
@ -11,9 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import {Component, Input, Output, OnInit, EventEmitter, OnChanges} from '@angular/core';
|
import {Component, Input, OnInit, OnChanges} from '@angular/core';
|
||||||
import { Subject } from 'rxjs/Subject';
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
|
|
||||||
import 'rxjs/add/operator/debounceTime';
|
import 'rxjs/add/operator/debounceTime';
|
||||||
import 'rxjs/add/operator/distinctUntilChanged';
|
import 'rxjs/add/operator/distinctUntilChanged';
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="row flex-items-xs-between rightPos">
|
<div class="row flex-items-xs-between rightPos">
|
||||||
<div class="flex-items-xs-middle option-right">
|
<div class="flex-items-xs-middle option-right">
|
||||||
<hbr-filter [withDivider]="true" filterPlaceholder='{{"LABEL.FILTER_LABEL_PLACEHOLDER" | translate}}' (filter)="doSearchTargets($event)" [currentValue]="targetName"></hbr-filter>
|
<hbr-filter [withDivider]="true" filterPlaceholder='{{"LABEL.FILTER_LABEL_PLACEHOLDER" | translate}}' (filterEvt)="doSearchTargets($event)" [currentValue]="targetName"></hbr-filter>
|
||||||
<span class="refresh-btn" (click)="refreshTargets()">
|
<span class="refresh-btn" (click)="refreshTargets()">
|
||||||
<clr-icon shape="refresh"></clr-icon>
|
<clr-icon shape="refresh"></clr-icon>
|
||||||
</span>
|
</span>
|
||||||
|
@ -48,7 +48,7 @@ describe('LabelComponent (inline template)', () => {
|
|||||||
project_id: 0,
|
project_id: 0,
|
||||||
scope: "g",
|
scope: "g",
|
||||||
update_time: "",
|
update_time: "",
|
||||||
}
|
};
|
||||||
|
|
||||||
let comp: LabelComponent;
|
let comp: LabelComponent;
|
||||||
let fixture: ComponentFixture<LabelComponent>;
|
let fixture: ComponentFixture<LabelComponent>;
|
||||||
@ -107,7 +107,7 @@ describe('LabelComponent (inline template)', () => {
|
|||||||
comp.editLabel([mockOneData]);
|
comp.editLabel([mockOneData]);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(comp.targets[0].name).toEqual('label0-g');
|
expect(comp.targets[0].name).toEqual('label0-g');
|
||||||
})
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/*it('should open to edit existing label', async() => {
|
/*it('should open to edit existing label', async() => {
|
||||||
@ -128,4 +128,4 @@ describe('LabelComponent (inline template)', () => {
|
|||||||
})
|
})
|
||||||
})*/
|
})*/
|
||||||
|
|
||||||
})
|
});
|
||||||
|
@ -12,24 +12,35 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import {
|
import {
|
||||||
Component, OnInit, OnDestroy, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef,
|
Component,
|
||||||
|
OnInit,
|
||||||
|
ViewChild,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorRef,
|
||||||
Input
|
Input
|
||||||
} from '@angular/core';
|
} from "@angular/core";
|
||||||
import { Label } from "../service/interface";
|
import { Label } from "../service/interface";
|
||||||
import {LabelDefaultService, LabelService} from "../service/label.service";
|
import { LabelService } from "../service/label.service";
|
||||||
import { toPromise } from "../utils";
|
import { toPromise } from "../utils";
|
||||||
import { ErrorHandler } from "../error-handler/error-handler";
|
import { ErrorHandler } from "../error-handler/error-handler";
|
||||||
import { CreateEditLabelComponent } from "../create-edit-label/create-edit-label.component";
|
import { CreateEditLabelComponent } from "../create-edit-label/create-edit-label.component";
|
||||||
import {BatchInfo, BathInfoChanges} from "../confirmation-dialog/confirmation-batch-message";
|
import {
|
||||||
|
BatchInfo,
|
||||||
|
BathInfoChanges
|
||||||
|
} from "../confirmation-dialog/confirmation-batch-message";
|
||||||
import { ConfirmationMessage } from "../confirmation-dialog/confirmation-message";
|
import { ConfirmationMessage } from "../confirmation-dialog/confirmation-message";
|
||||||
import {ConfirmationButtons, ConfirmationState, ConfirmationTargets} from "../shared/shared.const";
|
import {
|
||||||
|
ConfirmationButtons,
|
||||||
|
ConfirmationState,
|
||||||
|
ConfirmationTargets
|
||||||
|
} from "../shared/shared.const";
|
||||||
import { ConfirmationAcknowledgement } from "../confirmation-dialog/confirmation-state-message";
|
import { ConfirmationAcknowledgement } from "../confirmation-dialog/confirmation-state-message";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation-dialog.component";
|
import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation-dialog.component";
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-label',
|
selector: "hbr-label",
|
||||||
templateUrl: './label.component.html',
|
templateUrl: "./label.component.html",
|
||||||
styleUrls: ['./label.component.scss'],
|
styleUrls: ["./label.component.scss"],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class LabelComponent implements OnInit {
|
export class LabelComponent implements OnInit {
|
||||||
@ -47,32 +58,33 @@ export class LabelComponent implements OnInit {
|
|||||||
|
|
||||||
@ViewChild(CreateEditLabelComponent)
|
@ViewChild(CreateEditLabelComponent)
|
||||||
createEditLabel: CreateEditLabelComponent;
|
createEditLabel: CreateEditLabelComponent;
|
||||||
@ViewChild('confirmationDialog')
|
@ViewChild("confirmationDialog")
|
||||||
confirmationDialogComponent: ConfirmationDialogComponent;
|
confirmationDialogComponent: ConfirmationDialogComponent;
|
||||||
constructor(
|
constructor(
|
||||||
private labelService: LabelService,
|
private labelService: LabelService,
|
||||||
private errorHandler: ErrorHandler,
|
private errorHandler: ErrorHandler,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
private ref: ChangeDetectorRef) {
|
private ref: ChangeDetectorRef
|
||||||
}
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.retrieve(this.scope);
|
this.retrieve(this.scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
retrieve(scope: string, name = '') {
|
retrieve(scope: string, name = "") {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.selectedRow = [];
|
this.selectedRow = [];
|
||||||
this.targetName = '';
|
this.targetName = "";
|
||||||
toPromise<Label[]>(this.labelService.getLabels(scope, this.projectId, name))
|
toPromise<Label[]>(this.labelService.getLabels(scope, this.projectId, name))
|
||||||
.then(targets => {
|
.then(targets => {
|
||||||
this.targets = targets || [];
|
this.targets = targets || [];
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.forceRefreshView(2000);
|
this.forceRefreshView(2000);
|
||||||
}).catch(error => {
|
})
|
||||||
|
.catch(error => {
|
||||||
this.errorHandler.error(error);
|
this.errorHandler.error(error);
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openModal(): void {
|
openModal(): void {
|
||||||
@ -110,27 +122,30 @@ export class LabelComponent implements OnInit {
|
|||||||
this.batchDelectionInfos.push(initBatchMessage);
|
this.batchDelectionInfos.push(initBatchMessage);
|
||||||
});
|
});
|
||||||
let deletionMessage = new ConfirmationMessage(
|
let deletionMessage = new ConfirmationMessage(
|
||||||
'LABEL.DELETION_TITLE_TARGET',
|
"LABEL.DELETION_TITLE_TARGET",
|
||||||
'LABEL.DELETION_SUMMARY_TARGET',
|
"LABEL.DELETION_SUMMARY_TARGET",
|
||||||
targetNames.join(', ') || '',
|
targetNames.join(", ") || "",
|
||||||
targets,
|
targets,
|
||||||
ConfirmationTargets.TARGET,
|
ConfirmationTargets.TARGET,
|
||||||
ConfirmationButtons.DELETE_CANCEL);
|
ConfirmationButtons.DELETE_CANCEL
|
||||||
|
);
|
||||||
this.confirmationDialogComponent.open(deletionMessage);
|
this.confirmationDialogComponent.open(deletionMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmDeletion(message: ConfirmationAcknowledgement) {
|
confirmDeletion(message: ConfirmationAcknowledgement) {
|
||||||
if (message &&
|
if (
|
||||||
|
message &&
|
||||||
message.source === ConfirmationTargets.TARGET &&
|
message.source === ConfirmationTargets.TARGET &&
|
||||||
message.state === ConfirmationState.CONFIRMED) {
|
message.state === ConfirmationState.CONFIRMED
|
||||||
|
) {
|
||||||
let targetLists: Label[] = message.data;
|
let targetLists: Label[] = message.data;
|
||||||
if (targetLists && targetLists.length) {
|
if (targetLists && targetLists.length) {
|
||||||
let promiseLists: any[] = [];
|
let promiseLists: any[] = [];
|
||||||
targetLists.forEach(target => {
|
targetLists.forEach(target => {
|
||||||
promiseLists.push(this.delOperate(target.id, target.name));
|
promiseLists.push(this.delOperate(target.id, target.name));
|
||||||
})
|
});
|
||||||
Promise.all(promiseLists).then((item) => {
|
Promise.all(promiseLists).then(item => {
|
||||||
this.selectedRow = [];
|
this.selectedRow = [];
|
||||||
this.retrieve(this.scope);
|
this.retrieve(this.scope);
|
||||||
});
|
});
|
||||||
@ -140,17 +155,14 @@ export class LabelComponent implements OnInit {
|
|||||||
|
|
||||||
delOperate(id: number, name: string) {
|
delOperate(id: number, name: string) {
|
||||||
let findedList = this.batchDelectionInfos.find(data => data.name === name);
|
let findedList = this.batchDelectionInfos.find(data => data.name === name);
|
||||||
return toPromise<number>(this.labelService
|
return toPromise<number>(this.labelService.deleteLabel(id))
|
||||||
.deleteLabel(id))
|
.then(response => {
|
||||||
.then(
|
this.translateService.get("BATCH.DELETED_SUCCESS").subscribe(res => {
|
||||||
response => {
|
|
||||||
this.translateService.get('BATCH.DELETED_SUCCESS')
|
|
||||||
.subscribe(res => {
|
|
||||||
findedList = BathInfoChanges(findedList, res);
|
findedList = BathInfoChanges(findedList, res);
|
||||||
});
|
});
|
||||||
}).catch(
|
})
|
||||||
error => {
|
.catch(error => {
|
||||||
this.translateService.get('BATCH.DELETED_FAILURE').subscribe(res => {
|
this.translateService.get("BATCH.DELETED_FAILURE").subscribe(res => {
|
||||||
findedList = BathInfoChanges(findedList, res, false, true);
|
findedList = BathInfoChanges(findedList, res, false, true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -23,36 +23,40 @@ import {
|
|||||||
OnChanges,
|
OnChanges,
|
||||||
SimpleChange,
|
SimpleChange,
|
||||||
SimpleChanges
|
SimpleChanges
|
||||||
} from '@angular/core';
|
} from "@angular/core";
|
||||||
|
|
||||||
import { ReplicationService } from '../service/replication.service';
|
|
||||||
import {ReplicationJob, ReplicationJobItem, ReplicationRule} from '../service/interface';
|
|
||||||
|
|
||||||
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
|
||||||
import { ConfirmationMessage } from '../confirmation-dialog/confirmation-message';
|
|
||||||
import { ConfirmationAcknowledgement } from '../confirmation-dialog/confirmation-state-message';
|
|
||||||
|
|
||||||
import { ConfirmationState, ConfirmationTargets, ConfirmationButtons } from '../shared/shared.const';
|
|
||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
import { ErrorHandler } from '../error-handler/error-handler';
|
|
||||||
import { toPromise, CustomComparator } from '../utils';
|
|
||||||
|
|
||||||
import { State, Comparator } from 'clarity-angular';
|
|
||||||
|
|
||||||
import {BatchInfo, BathInfoChanges} from "../confirmation-dialog/confirmation-batch-message";
|
|
||||||
import { Observable } from "rxjs/Observable";
|
import { Observable } from "rxjs/Observable";
|
||||||
|
import { Comparator } from "clarity-angular";
|
||||||
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
|
import { ReplicationService } from "../service/replication.service";
|
||||||
|
import {
|
||||||
|
ReplicationJob,
|
||||||
|
ReplicationJobItem,
|
||||||
|
ReplicationRule
|
||||||
|
} from "../service/interface";
|
||||||
|
import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation-dialog.component";
|
||||||
|
import { ConfirmationMessage } from "../confirmation-dialog/confirmation-message";
|
||||||
|
import { ConfirmationAcknowledgement } from "../confirmation-dialog/confirmation-state-message";
|
||||||
|
import {
|
||||||
|
ConfirmationState,
|
||||||
|
ConfirmationTargets,
|
||||||
|
ConfirmationButtons
|
||||||
|
} from "../shared/shared.const";
|
||||||
|
import { ErrorHandler } from "../error-handler/error-handler";
|
||||||
|
import { toPromise, CustomComparator } from "../utils";
|
||||||
|
import {
|
||||||
|
BatchInfo,
|
||||||
|
BathInfoChanges
|
||||||
|
} from "../confirmation-dialog/confirmation-batch-message";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-list-replication-rule',
|
selector: "hbr-list-replication-rule",
|
||||||
templateUrl: './list-replication-rule.component.html',
|
templateUrl: "./list-replication-rule.component.html",
|
||||||
styleUrls: ['./list-replication-rule.component.scss'],
|
styleUrls: ["./list-replication-rule.component.scss"],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
||||||
|
nullTime = "0001-01-01T00:00:00Z";
|
||||||
nullTime = '0001-01-01T00:00:00Z';
|
|
||||||
|
|
||||||
@Input() projectId: number;
|
@Input() projectId: number;
|
||||||
@Input() isSystemAdmin: boolean;
|
@Input() isSystemAdmin: boolean;
|
||||||
@ -80,20 +84,25 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
|||||||
selectedRow: ReplicationRule;
|
selectedRow: ReplicationRule;
|
||||||
batchDelectionInfos: BatchInfo[] = [];
|
batchDelectionInfos: BatchInfo[] = [];
|
||||||
|
|
||||||
@ViewChild('toggleConfirmDialog')
|
@ViewChild("toggleConfirmDialog")
|
||||||
toggleConfirmDialog: ConfirmationDialogComponent;
|
toggleConfirmDialog: ConfirmationDialogComponent;
|
||||||
|
|
||||||
@ViewChild('deletionConfirmDialog')
|
@ViewChild("deletionConfirmDialog")
|
||||||
deletionConfirmDialog: ConfirmationDialogComponent;
|
deletionConfirmDialog: ConfirmationDialogComponent;
|
||||||
|
|
||||||
startTimeComparator: Comparator<ReplicationRule> = new CustomComparator<ReplicationRule>('start_time', 'date');
|
startTimeComparator: Comparator<ReplicationRule> = new CustomComparator<
|
||||||
enabledComparator: Comparator<ReplicationRule> = new CustomComparator<ReplicationRule>('enabled', 'number');
|
ReplicationRule
|
||||||
|
>("start_time", "date");
|
||||||
|
enabledComparator: Comparator<ReplicationRule> = new CustomComparator<
|
||||||
|
ReplicationRule
|
||||||
|
>("enabled", "number");
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private replicationService: ReplicationService,
|
private replicationService: ReplicationService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
private errorHandler: ErrorHandler,
|
private errorHandler: ErrorHandler,
|
||||||
private ref: ChangeDetectorRef) {
|
private ref: ChangeDetectorRef
|
||||||
|
) {
|
||||||
setInterval(() => ref.markForCheck(), 500);
|
setInterval(() => ref.markForCheck(), 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,19 +135,20 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
retrieveRules(ruleName = ''): void {
|
retrieveRules(ruleName = ""): void {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
/*this.selectedRow = null;*/
|
/*this.selectedRow = null;*/
|
||||||
toPromise<ReplicationRule[]>(this.replicationService
|
toPromise<ReplicationRule[]>(
|
||||||
.getReplicationRules(this.projectId, ruleName))
|
this.replicationService.getReplicationRules(this.projectId, ruleName)
|
||||||
|
)
|
||||||
.then(rules => {
|
.then(rules => {
|
||||||
this.rules = rules || [];
|
this.rules = rules || [];
|
||||||
// job list hidden
|
// job list hidden
|
||||||
this.hideJobs.emit();
|
this.hideJobs.emit();
|
||||||
this.changedRules = this.rules;
|
this.changedRules = this.rules;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
})
|
||||||
).catch(error => {
|
.catch(error => {
|
||||||
this.errorHandler.error(error);
|
this.errorHandler.error(error);
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
@ -149,16 +159,17 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deletionConfirm(message: ConfirmationAcknowledgement) {
|
deletionConfirm(message: ConfirmationAcknowledgement) {
|
||||||
if (message &&
|
if (
|
||||||
|
message &&
|
||||||
message.source === ConfirmationTargets.POLICY &&
|
message.source === ConfirmationTargets.POLICY &&
|
||||||
message.state === ConfirmationState.CONFIRMED) {
|
message.state === ConfirmationState.CONFIRMED
|
||||||
|
) {
|
||||||
this.deleteOpe(message.data);
|
this.deleteOpe(message.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
selectRule(rule: ReplicationRule): void {
|
selectRule(rule: ReplicationRule): void {
|
||||||
this.selectedId = rule.id || '';
|
this.selectedId = rule.id || "";
|
||||||
this.selectOne.emit(rule);
|
this.selectOne.emit(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,13 +189,16 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
|||||||
let ruleData: ReplicationJobItem[];
|
let ruleData: ReplicationJobItem[];
|
||||||
this.canDeleteRule = true;
|
this.canDeleteRule = true;
|
||||||
let count = 0;
|
let count = 0;
|
||||||
return toPromise<ReplicationJob>(this.replicationService
|
return toPromise<ReplicationJob>(this.replicationService.getJobs(id))
|
||||||
.getJobs(id))
|
|
||||||
.then(response => {
|
.then(response => {
|
||||||
ruleData = response.data;
|
ruleData = response.data;
|
||||||
if (ruleData.length) {
|
if (ruleData.length) {
|
||||||
ruleData.forEach(job => {
|
ruleData.forEach(job => {
|
||||||
if ((job.status === 'pending') || (job.status === 'running') || (job.status === 'retrying')) {
|
if (
|
||||||
|
job.status === "pending" ||
|
||||||
|
job.status === "running" ||
|
||||||
|
job.status === "retrying"
|
||||||
|
) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -201,12 +215,13 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
|||||||
initBatchMessage.name = rule.name;
|
initBatchMessage.name = rule.name;
|
||||||
this.batchDelectionInfos.push(initBatchMessage);
|
this.batchDelectionInfos.push(initBatchMessage);
|
||||||
let deletionMessage = new ConfirmationMessage(
|
let deletionMessage = new ConfirmationMessage(
|
||||||
'REPLICATION.DELETION_TITLE',
|
"REPLICATION.DELETION_TITLE",
|
||||||
'REPLICATION.DELETION_SUMMARY',
|
"REPLICATION.DELETION_SUMMARY",
|
||||||
rule.name,
|
rule.name,
|
||||||
rule,
|
rule,
|
||||||
ConfirmationTargets.POLICY,
|
ConfirmationTargets.POLICY,
|
||||||
ConfirmationButtons.DELETE_CANCEL);
|
ConfirmationButtons.DELETE_CANCEL
|
||||||
|
);
|
||||||
this.deletionConfirmDialog.open(deletionMessage);
|
this.deletionConfirmDialog.open(deletionMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,10 +230,20 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
|||||||
let promiseLists: any[] = [];
|
let promiseLists: any[] = [];
|
||||||
Promise.all([this.jobList(rule.id)]).then(items => {
|
Promise.all([this.jobList(rule.id)]).then(items => {
|
||||||
if (!this.canDeleteRule) {
|
if (!this.canDeleteRule) {
|
||||||
let findedList = this.batchDelectionInfos.find(data => data.name === rule.name);
|
let findedList = this.batchDelectionInfos.find(
|
||||||
Observable.forkJoin(this.translateService.get('BATCH.DELETED_FAILURE'),
|
data => data.name === rule.name
|
||||||
this.translateService.get('REPLICATION.DELETION_SUMMARY_FAILURE')).subscribe(res => {
|
);
|
||||||
findedList = BathInfoChanges(findedList, res[0], false, true, res[1]);
|
Observable.forkJoin(
|
||||||
|
this.translateService.get("BATCH.DELETED_FAILURE"),
|
||||||
|
this.translateService.get("REPLICATION.DELETION_SUMMARY_FAILURE")
|
||||||
|
).subscribe(res => {
|
||||||
|
findedList = BathInfoChanges(
|
||||||
|
findedList,
|
||||||
|
res[0],
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
res[1]
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
promiseLists.push(this.delOperate(+rule.id, rule.name));
|
promiseLists.push(this.delOperate(+rule.id, rule.name));
|
||||||
@ -236,20 +261,30 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
|||||||
|
|
||||||
delOperate(ruleId: number, name: string) {
|
delOperate(ruleId: number, name: string) {
|
||||||
let findedList = this.batchDelectionInfos.find(data => data.name === name);
|
let findedList = this.batchDelectionInfos.find(data => data.name === name);
|
||||||
return toPromise<any>(this.replicationService
|
return toPromise<any>(this.replicationService.deleteReplicationRule(ruleId))
|
||||||
.deleteReplicationRule(ruleId))
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.translateService.get('BATCH.DELETED_SUCCESS')
|
this.translateService
|
||||||
.subscribe(res => findedList = BathInfoChanges(findedList, res));
|
.get("BATCH.DELETED_SUCCESS")
|
||||||
|
.subscribe(res => (findedList = BathInfoChanges(findedList, res)));
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
if (error && error.status === 412) {
|
if (error && error.status === 412) {
|
||||||
Observable.forkJoin(this.translateService.get('BATCH.DELETED_FAILURE'),
|
Observable.forkJoin(
|
||||||
this.translateService.get('REPLICATION.FAILED_TO_DELETE_POLICY_ENABLED')).subscribe(res => {
|
this.translateService.get("BATCH.DELETED_FAILURE"),
|
||||||
findedList = BathInfoChanges(findedList, res[0], false, true, res[1]);
|
this.translateService.get(
|
||||||
|
"REPLICATION.FAILED_TO_DELETE_POLICY_ENABLED"
|
||||||
|
)
|
||||||
|
).subscribe(res => {
|
||||||
|
findedList = BathInfoChanges(
|
||||||
|
findedList,
|
||||||
|
res[0],
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
res[1]
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.translateService.get('BATCH.DELETED_FAILURE').subscribe(res => {
|
this.translateService.get("BATCH.DELETED_FAILURE").subscribe(res => {
|
||||||
findedList = BathInfoChanges(findedList, res, false, true);
|
findedList = BathInfoChanges(findedList, res, false, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<option value="operation">{{"AUDIT_LOG.OPERATION" | translate | lowercase}}</option>
|
<option value="operation">{{"AUDIT_LOG.OPERATION" | translate | lowercase}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<hbr-filter [withDivider]="true" filterPlaceholder='{{"AUDIT_LOG.FILTER_PLACEHOLDER" | translate}}' (filter)="doFilter($event)"
|
<hbr-filter [withDivider]="true" filterPlaceholder='{{"AUDIT_LOG.FILTER_PLACEHOLDER" | translate}}' (filterEvt)="doFilter($event)"
|
||||||
(openFlag)="openFilter($event)" [currentValue]="currentTerm"></hbr-filter>
|
(openFlag)="openFilter($event)" [currentValue]="currentTerm"></hbr-filter>
|
||||||
<span (click)="refresh()" class="refresh-btn">
|
<span (click)="refresh()" class="refresh-btn">
|
||||||
<clr-icon shape="refresh" [hidden]="inProgress" ng-disabled="inProgress"></clr-icon>
|
<clr-icon shape="refresh" [hidden]="inProgress" ng-disabled="inProgress"></clr-icon>
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
|
||||||
import { HttpModule } from '@angular/http';
|
|
||||||
import { DebugElement } from '@angular/core';
|
import { DebugElement } from '@angular/core';
|
||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
import { AccessLog, AccessLogItem, RequestQueryParams } from '../service/index';
|
import { AccessLog, AccessLogItem, RequestQueryParams } from '../service/index';
|
||||||
|
|
||||||
import { RecentLogComponent } from './recent-log.component';
|
import { RecentLogComponent } from './recent-log.component';
|
||||||
@ -83,7 +80,7 @@ describe('RecentLogComponent (inline template)', () => {
|
|||||||
if (params.get('page') === '1') {
|
if (params.get('page') === '1') {
|
||||||
mockData.data = mockItems.slice(0, 15);
|
mockData.data = mockItems.slice(0, 15);
|
||||||
} else {
|
} else {
|
||||||
mockData.data = mockItems.slice(15, 18)
|
mockData.data = mockItems.slice(15, 18);
|
||||||
}
|
}
|
||||||
return Promise.resolve(mockData);
|
return Promise.resolve(mockData);
|
||||||
}
|
}
|
||||||
@ -194,7 +191,7 @@ describe('RecentLogComponent (inline template)', () => {
|
|||||||
|
|
||||||
let els: HTMLElement[] = fixture.nativeElement.querySelectorAll('.datagrid-row');
|
let els: HTMLElement[] = fixture.nativeElement.querySelectorAll('.datagrid-row');
|
||||||
expect(els).toBeTruthy();
|
expect(els).toBeTruthy();
|
||||||
expect(els.length).toEqual(4)
|
expect(els.length).toEqual(4);
|
||||||
|
|
||||||
let refreshEl: HTMLElement = fixture.nativeElement.querySelector(".refresh-btn");
|
let refreshEl: HTMLElement = fixture.nativeElement.querySelector(".refresh-btn");
|
||||||
expect(refreshEl).toBeTruthy("Not found refresh button");
|
expect(refreshEl).toBeTruthy("Not found refresh button");
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, OnInit, Input } from '@angular/core';
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Comparator, State } from 'clarity-angular';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AccessLogService,
|
AccessLogService,
|
||||||
AccessLog,
|
AccessLog,
|
||||||
@ -20,7 +21,6 @@ import {
|
|||||||
RequestQueryParams
|
RequestQueryParams
|
||||||
} from '../service/index';
|
} from '../service/index';
|
||||||
import { ErrorHandler } from '../error-handler/index';
|
import { ErrorHandler } from '../error-handler/index';
|
||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
import { toPromise, CustomComparator } from '../utils';
|
import { toPromise, CustomComparator } from '../utils';
|
||||||
import {
|
import {
|
||||||
DEFAULT_PAGE_SIZE,
|
DEFAULT_PAGE_SIZE,
|
||||||
@ -29,8 +29,6 @@ import {
|
|||||||
doSorting
|
doSorting
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
|
|
||||||
import { Comparator, State } from 'clarity-angular';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-log',
|
selector: 'hbr-log',
|
||||||
templateUrl: './recent-log.component.html',
|
templateUrl: './recent-log.component.html',
|
||||||
@ -126,7 +124,7 @@ export class RecentLogComponent implements OnInit {
|
|||||||
toPromise<AccessLog>(this.logService.getRecentLogs(params))
|
toPromise<AccessLog>(this.logService.getRecentLogs(params))
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.logsCache = response; // Keep the data
|
this.logsCache = response; // Keep the data
|
||||||
this.recentLogs = this.logsCache.data.filter(log => log.username != "");//To display
|
this.recentLogs = this.logsCache.data.filter(log => log.username !== ""); // To display
|
||||||
|
|
||||||
// Do customized filter
|
// Do customized filter
|
||||||
this.recentLogs = doFiltering<AccessLogItem>(this.recentLogs, state);
|
this.recentLogs = doFiltering<AccessLogItem>(this.recentLogs, state);
|
||||||
@ -145,7 +143,7 @@ export class RecentLogComponent implements OnInit {
|
|||||||
} else {
|
} else {
|
||||||
// Column sorting and filtering
|
// Column sorting and filtering
|
||||||
|
|
||||||
this.recentLogs = this.logsCache.data.filter(log => log.username != "");//Reset data
|
this.recentLogs = this.logsCache.data.filter(log => log.username !== ""); // Reset data
|
||||||
|
|
||||||
// Do customized filter
|
// Do customized filter
|
||||||
this.recentLogs = doFiltering<AccessLogItem>(this.recentLogs, state);
|
this.recentLogs = doFiltering<AccessLogItem>(this.recentLogs, state);
|
||||||
|
@ -5,7 +5,7 @@ import { ProjectService } from '../service/project.service';
|
|||||||
import { ErrorHandler } from '../error-handler/error-handler';
|
import { ErrorHandler } from '../error-handler/error-handler';
|
||||||
import { State } from 'clarity-angular';
|
import { State } from 'clarity-angular';
|
||||||
|
|
||||||
import { ConfirmationState, ConfirmationTargets, ConfirmationButtons } from '../shared/shared.const';
|
import { ConfirmationState, ConfirmationTargets } from '../shared/shared.const';
|
||||||
import { ConfirmationMessage } from '../confirmation-dialog/confirmation-message';
|
import { ConfirmationMessage } from '../confirmation-dialog/confirmation-message';
|
||||||
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
||||||
import { ConfirmationAcknowledgement } from '../confirmation-dialog/confirmation-state-message';
|
import { ConfirmationAcknowledgement } from '../confirmation-dialog/confirmation-state-message';
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
import { async, ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
|
||||||
import { HttpModule } from '@angular/http';
|
|
||||||
import { DebugElement } from '@angular/core';
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
|
|
||||||
import { PushImageButtonComponent } from './push-image.component';
|
import { PushImageButtonComponent } from './push-image.component';
|
||||||
import { CopyInputComponent } from './copy-input.component';
|
import { CopyInputComponent } from './copy-input.component';
|
||||||
@ -10,7 +6,6 @@ import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
|
|||||||
|
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
||||||
import { SharedModule } from '../shared/shared.module';
|
import { SharedModule } from '../shared/shared.module';
|
||||||
import { click } from '../utils';
|
|
||||||
|
|
||||||
describe('PushImageButtonComponent (inline template)', () => {
|
describe('PushImageButtonComponent (inline template)', () => {
|
||||||
let component: PushImageButtonComponent;
|
let component: PushImageButtonComponent;
|
||||||
@ -34,7 +29,7 @@ describe('PushImageButtonComponent (inline template)', () => {
|
|||||||
fixture = TestBed.createComponent(PushImageButtonComponent);
|
fixture = TestBed.createComponent(PushImageButtonComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
component.projectName = 'testing';
|
component.projectName = 'testing';
|
||||||
component.registryUrl = 'https://testing.harbor.com'
|
component.registryUrl = 'https://testing.harbor.com';
|
||||||
serviceConfig = TestBed.get(SERVICE_CONFIG);
|
serviceConfig = TestBed.get(SERVICE_CONFIG);
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@ -57,9 +52,10 @@ describe('PushImageButtonComponent (inline template)', () => {
|
|||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(copyInputs.length).toEqual(2);
|
expect(copyInputs.length).toEqual(2);
|
||||||
expect(copyInputs[0].value.trim()).toEqual(`docker tag SOURCE_IMAGE[:TAG] ${component.registryUrl}/${component.projectName}/IMAGE[:TAG]`);
|
expect(copyInputs[0].value.trim())
|
||||||
|
.toEqual(`docker tag SOURCE_IMAGE[:TAG] ${component.registryUrl}/${component.projectName}/IMAGE[:TAG]`);
|
||||||
expect(copyInputs[1].value.trim()).toEqual(`docker push ${component.registryUrl}/${component.projectName}/IMAGE[:TAG]`);
|
expect(copyInputs[1].value.trim()).toEqual(`docker push ${component.registryUrl}/${component.projectName}/IMAGE[:TAG]`);
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import { Component, Input, ViewChild } from '@angular/core';
|
import { Component, Input, ViewChild } from "@angular/core";
|
||||||
import { CopyInputComponent } from './copy-input.component';
|
import { CopyInputComponent } from "./copy-input.component";
|
||||||
import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
|
import { InlineAlertComponent } from "../inline-alert/inline-alert.component";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-push-image-button',
|
selector: "hbr-push-image-button",
|
||||||
templateUrl: './push-image.component.html',
|
templateUrl: "./push-image.component.html",
|
||||||
styleUrls: ['./push-image.scss'],
|
styleUrls: ["./push-image.scss"],
|
||||||
|
|
||||||
providers: []
|
providers: []
|
||||||
})
|
})
|
||||||
@ -18,9 +17,10 @@ export class PushImageButtonComponent {
|
|||||||
@ViewChild("pushCopy") pushCopyInput: CopyInputComponent;
|
@ViewChild("pushCopy") pushCopyInput: CopyInputComponent;
|
||||||
@ViewChild("copyAlert") copyAlert: InlineAlertComponent;
|
@ViewChild("copyAlert") copyAlert: InlineAlertComponent;
|
||||||
|
|
||||||
|
|
||||||
public get tagCommand(): string {
|
public get tagCommand(): string {
|
||||||
return `docker tag SOURCE_IMAGE[:TAG] ${this.registryUrl}/${this.projectName}/IMAGE[:TAG]`;
|
return `docker tag SOURCE_IMAGE[:TAG] ${this.registryUrl}/${
|
||||||
|
this.projectName
|
||||||
|
}/IMAGE[:TAG]`;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get pushCommand(): string {
|
public get pushCommand(): string {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="row flex-items-xs-between rightPos">
|
<div class="row flex-items-xs-between rightPos">
|
||||||
<div class="flex-xs-middle option-right">
|
<div class="flex-xs-middle option-right">
|
||||||
<hbr-filter [withDivider]="true" filterPlaceholder='{{"REPLICATION.FILTER_POLICIES_PLACEHOLDER" | translate}}' (filter)="doSearchRules($event)" [currentValue]="search.ruleName"></hbr-filter>
|
<hbr-filter [withDivider]="true" filterPlaceholder='{{"REPLICATION.FILTER_POLICIES_PLACEHOLDER" | translate}}' (filterEvt)="doSearchRules($event)" [currentValue]="search.ruleName"></hbr-filter>
|
||||||
<span class="refresh-btn" (click)="refreshRules()">
|
<span class="refresh-btn" (click)="refreshRules()">
|
||||||
<clr-icon shape="refresh"></clr-icon>
|
<clr-icon shape="refresh"></clr-icon>
|
||||||
</span>
|
</span>
|
||||||
@ -18,7 +18,7 @@
|
|||||||
<h5 class="flex-items-xs-bottom option-left-down" style="margin-left: 14px;">{{'REPLICATION.REPLICATION_JOBS' | translate}}</h5>
|
<h5 class="flex-items-xs-bottom option-left-down" style="margin-left: 14px;">{{'REPLICATION.REPLICATION_JOBS' | translate}}</h5>
|
||||||
<div class="flex-items-xs-bottom option-right-down">
|
<div class="flex-items-xs-bottom option-right-down">
|
||||||
<button class="btn btn-link" (click)="toggleSearchJobOptionalName(currentJobSearchOption)">{{toggleJobSearchOption[currentJobSearchOption] | translate}}</button>
|
<button class="btn btn-link" (click)="toggleSearchJobOptionalName(currentJobSearchOption)">{{toggleJobSearchOption[currentJobSearchOption] | translate}}</button>
|
||||||
<hbr-filter [withDivider]="true" filterPlaceholder='{{"REPLICATION.FILTER_JOBS_PLACEHOLDER" | translate}}' (filter)="doSearchJobs($event)" [currentValue]="search.repoName" ></hbr-filter>
|
<hbr-filter [withDivider]="true" filterPlaceholder='{{"REPLICATION.FILTER_JOBS_PLACEHOLDER" | translate}}' (filterEvt)="doSearchJobs($event)" [currentValue]="search.repoName" ></hbr-filter>
|
||||||
<span class="refresh-btn" (click)="refreshJobs()">
|
<span class="refresh-btn" (click)="refreshJobs()">
|
||||||
<clr-icon shape="refresh"></clr-icon>
|
<clr-icon shape="refresh"></clr-icon>
|
||||||
</span>
|
</span>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ComponentFixture, TestBed, async, inject } from '@angular/core/testing';
|
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { DebugElement } from '@angular/core';
|
import { DebugElement } from '@angular/core';
|
||||||
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
@ -9,7 +9,6 @@ import { ReplicationComponent } from './replication.component';
|
|||||||
import { ListReplicationRuleComponent } from '../list-replication-rule/list-replication-rule.component';
|
import { ListReplicationRuleComponent } from '../list-replication-rule/list-replication-rule.component';
|
||||||
import { CreateEditRuleComponent } from '../create-edit-rule/create-edit-rule.component';
|
import { CreateEditRuleComponent } from '../create-edit-rule/create-edit-rule.component';
|
||||||
import { DatePickerComponent } from '../datetime-picker/datetime-picker.component';
|
import { DatePickerComponent } from '../datetime-picker/datetime-picker.component';
|
||||||
import { DateValidatorDirective } from '../datetime-picker/date-validator.directive';
|
|
||||||
import { FilterComponent } from '../filter/filter.component';
|
import { FilterComponent } from '../filter/filter.component';
|
||||||
import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
|
import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
|
||||||
import {ReplicationRule, ReplicationJob, Endpoint} from '../service/interface';
|
import {ReplicationRule, ReplicationJob, Endpoint} from '../service/interface';
|
||||||
@ -20,7 +19,6 @@ import { ReplicationService, ReplicationDefaultService } from '../service/replic
|
|||||||
import { EndpointService, EndpointDefaultService } from '../service/endpoint.service';
|
import { EndpointService, EndpointDefaultService } from '../service/endpoint.service';
|
||||||
import { JobLogViewerComponent } from '../job-log-viewer/job-log-viewer.component';
|
import { JobLogViewerComponent } from '../job-log-viewer/job-log-viewer.component';
|
||||||
import { JobLogService, JobLogDefaultService, ReplicationJobItem } from '../service/index';
|
import { JobLogService, JobLogDefaultService, ReplicationJobItem } from '../service/index';
|
||||||
import {Project} from "../project-policy-config/project";
|
|
||||||
import {ProjectDefaultService, ProjectService} from "../service/project.service";
|
import {ProjectDefaultService, ProjectService} from "../service/project.service";
|
||||||
|
|
||||||
describe('Replication Component (inline template)', () => {
|
describe('Replication Component (inline template)', () => {
|
||||||
@ -159,28 +157,28 @@ describe('Replication Component (inline template)', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
let mockProjects: Project[] = [
|
// let mockProjects: Project[] = [
|
||||||
{ "project_id": 1,
|
// { "project_id": 1,
|
||||||
"owner_id": 0,
|
// "owner_id": 0,
|
||||||
"name": 'project_01',
|
// "name": 'project_01',
|
||||||
"creation_time": '',
|
// "creation_time": '',
|
||||||
"deleted": 0,
|
// "deleted": 0,
|
||||||
"owner_name": '',
|
// "owner_name": '',
|
||||||
"togglable": false,
|
// "togglable": false,
|
||||||
"update_time": '',
|
// "update_time": '',
|
||||||
"current_user_role_id": 0,
|
// "current_user_role_id": 0,
|
||||||
"repo_count": 0,
|
// "repo_count": 0,
|
||||||
"has_project_admin_role": false,
|
// "has_project_admin_role": false,
|
||||||
"is_member": false,
|
// "is_member": false,
|
||||||
"role_name": '',
|
// "role_name": '',
|
||||||
"metadata": {
|
// "metadata": {
|
||||||
"public": '',
|
// "public": '',
|
||||||
"enable_content_trust": '',
|
// "enable_content_trust": '',
|
||||||
"prevent_vul": '',
|
// "prevent_vul": '',
|
||||||
"severity": '',
|
// "severity": '',
|
||||||
"auto_scan": '',
|
// "auto_scan": '',
|
||||||
}
|
// }
|
||||||
}];
|
// }];
|
||||||
|
|
||||||
let mockJob: ReplicationJob = {
|
let mockJob: ReplicationJob = {
|
||||||
metadata: {xTotalCount: 3},
|
metadata: {xTotalCount: 3},
|
||||||
@ -341,5 +339,5 @@ describe('Replication Component (inline template)', () => {
|
|||||||
expect(el).toBeTruthy();
|
expect(el).toBeTruthy();
|
||||||
expect(el.textContent.trim()).toEqual('library/nginx');
|
expect(el.textContent.trim()).toEqual('library/nginx');
|
||||||
});
|
});
|
||||||
}))
|
}));
|
||||||
});
|
});
|
@ -11,17 +11,29 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, OnInit, ViewChild, Input, Output, OnDestroy, EventEmitter } from '@angular/core';
|
import {
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
ViewChild,
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
OnDestroy,
|
||||||
|
EventEmitter
|
||||||
|
} from "@angular/core";
|
||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
import { ListReplicationRuleComponent } from '../list-replication-rule/list-replication-rule.component';
|
import { ListReplicationRuleComponent } from "../list-replication-rule/list-replication-rule.component";
|
||||||
import { CreateEditRuleComponent } from '../create-edit-rule/create-edit-rule.component';
|
import { CreateEditRuleComponent } from "../create-edit-rule/create-edit-rule.component";
|
||||||
import { ErrorHandler } from '../error-handler/error-handler';
|
import { ErrorHandler } from "../error-handler/error-handler";
|
||||||
|
|
||||||
import { ReplicationService } from '../service/replication.service';
|
import { ReplicationService } from "../service/replication.service";
|
||||||
import { RequestQueryParams } from '../service/RequestQueryParams';
|
import { RequestQueryParams } from "../service/RequestQueryParams";
|
||||||
import { ReplicationRule, ReplicationJob, ReplicationJobItem } from '../service/interface';
|
import {
|
||||||
|
ReplicationRule,
|
||||||
|
ReplicationJob,
|
||||||
|
ReplicationJobItem
|
||||||
|
} from "../service/interface";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
toPromise,
|
toPromise,
|
||||||
@ -30,59 +42,68 @@ import {
|
|||||||
doFiltering,
|
doFiltering,
|
||||||
doSorting,
|
doSorting,
|
||||||
calculatePage
|
calculatePage
|
||||||
} from '../utils';
|
} from "../utils";
|
||||||
|
|
||||||
import { Comparator } from 'clarity-angular';
|
import { Comparator } from "clarity-angular";
|
||||||
|
|
||||||
import { JobLogViewerComponent } from '../job-log-viewer/index';
|
import { JobLogViewerComponent } from "../job-log-viewer/index";
|
||||||
import { State } from "clarity-angular";
|
import { State } from "clarity-angular";
|
||||||
import { Observable } from "rxjs/Observable";
|
import { Observable } from "rxjs/Observable";
|
||||||
import { Subscription } from "rxjs/Subscription";
|
import { Subscription } from "rxjs/Subscription";
|
||||||
import {ConfirmationTargets, ConfirmationButtons, ConfirmationState} from "../shared/shared.const";
|
import {
|
||||||
|
ConfirmationTargets,
|
||||||
|
ConfirmationButtons,
|
||||||
|
ConfirmationState
|
||||||
|
} from "../shared/shared.const";
|
||||||
import { ConfirmationMessage } from "../confirmation-dialog/confirmation-message";
|
import { ConfirmationMessage } from "../confirmation-dialog/confirmation-message";
|
||||||
import {BatchInfo, BathInfoChanges} from "../confirmation-dialog/confirmation-batch-message";
|
import {
|
||||||
|
BatchInfo,
|
||||||
|
BathInfoChanges
|
||||||
|
} from "../confirmation-dialog/confirmation-batch-message";
|
||||||
import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation-dialog.component";
|
import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation-dialog.component";
|
||||||
import { ConfirmationAcknowledgement } from "../confirmation-dialog/confirmation-state-message";
|
import { ConfirmationAcknowledgement } from "../confirmation-dialog/confirmation-state-message";
|
||||||
|
|
||||||
const ruleStatus: { [key: string]: any } = [
|
const ruleStatus: { [key: string]: any } = [
|
||||||
{ 'key': 'all', 'description': 'REPLICATION.ALL_STATUS' },
|
{ key: "all", description: "REPLICATION.ALL_STATUS" },
|
||||||
{ 'key': '1', 'description': 'REPLICATION.ENABLED' },
|
{ key: "1", description: "REPLICATION.ENABLED" },
|
||||||
{ 'key': '0', 'description': 'REPLICATION.DISABLED' }
|
{ key: "0", description: "REPLICATION.DISABLED" }
|
||||||
];
|
];
|
||||||
|
|
||||||
const jobStatus: { [key: string]: any } = [
|
const jobStatus: { [key: string]: any } = [
|
||||||
{ 'key': 'all', 'description': 'REPLICATION.ALL' },
|
{ key: "all", description: "REPLICATION.ALL" },
|
||||||
{ 'key': 'pending', 'description': 'REPLICATION.PENDING' },
|
{ key: "pending", description: "REPLICATION.PENDING" },
|
||||||
{ 'key': 'running', 'description': 'REPLICATION.RUNNING' },
|
{ key: "running", description: "REPLICATION.RUNNING" },
|
||||||
{ 'key': 'error', 'description': 'REPLICATION.ERROR' },
|
{ key: "error", description: "REPLICATION.ERROR" },
|
||||||
{ 'key': 'retrying', 'description': 'REPLICATION.RETRYING' },
|
{ key: "retrying", description: "REPLICATION.RETRYING" },
|
||||||
{ 'key': 'stopped', 'description': 'REPLICATION.STOPPED' },
|
{ key: "stopped", description: "REPLICATION.STOPPED" },
|
||||||
{ 'key': 'finished', 'description': 'REPLICATION.FINISHED' },
|
{ key: "finished", description: "REPLICATION.FINISHED" },
|
||||||
{ 'key': 'canceled', 'description': 'REPLICATION.CANCELED' }
|
{ key: "canceled", description: "REPLICATION.CANCELED" }
|
||||||
];
|
];
|
||||||
|
|
||||||
const optionalSearch: {} = { 0: 'REPLICATION.ADVANCED', 1: 'REPLICATION.SIMPLE' };
|
const optionalSearch: {} = {
|
||||||
|
0: "REPLICATION.ADVANCED",
|
||||||
|
1: "REPLICATION.SIMPLE"
|
||||||
|
};
|
||||||
|
|
||||||
export class SearchOption {
|
export class SearchOption {
|
||||||
ruleId: number | string;
|
ruleId: number | string;
|
||||||
ruleName: string = '';
|
ruleName: string = "";
|
||||||
repoName: string = '';
|
repoName: string = "";
|
||||||
status: string = '';
|
status: string = "";
|
||||||
startTime: string = '';
|
startTime: string = "";
|
||||||
startTimestamp: string = '';
|
startTimestamp: string = "";
|
||||||
endTime: string = '';
|
endTime: string = "";
|
||||||
endTimestamp: string = '';
|
endTimestamp: string = "";
|
||||||
page: number = 1;
|
page: number = 1;
|
||||||
pageSize: number = DEFAULT_PAGE_SIZE;
|
pageSize: number = DEFAULT_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-replication',
|
selector: "hbr-replication",
|
||||||
templateUrl: './replication.component.html',
|
templateUrl: "./replication.component.html",
|
||||||
styleUrls: ['./replication.component.scss']
|
styleUrls: ["./replication.component.scss"]
|
||||||
})
|
})
|
||||||
export class ReplicationComponent implements OnInit, OnDestroy {
|
export class ReplicationComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@Input() projectId: number | string;
|
@Input() projectId: number | string;
|
||||||
@Input() projectName: string;
|
@Input() projectName: string;
|
||||||
@Input() isSystemAdmin: boolean;
|
@Input() isSystemAdmin: boolean;
|
||||||
@ -96,10 +117,10 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
search: SearchOption = new SearchOption();
|
search: SearchOption = new SearchOption();
|
||||||
|
|
||||||
ruleStatus = ruleStatus;
|
ruleStatus = ruleStatus;
|
||||||
currentRuleStatus: { key: string, description: string };
|
currentRuleStatus: { key: string; description: string };
|
||||||
|
|
||||||
jobStatus = jobStatus;
|
jobStatus = jobStatus;
|
||||||
currentJobStatus: { key: string, description: string };
|
currentJobStatus: { key: string; description: string };
|
||||||
|
|
||||||
changedRules: ReplicationRule[];
|
changedRules: ReplicationRule[];
|
||||||
|
|
||||||
@ -108,7 +129,6 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
isStopOnGoing: boolean;
|
isStopOnGoing: boolean;
|
||||||
hiddenJobList = true;
|
hiddenJobList = true;
|
||||||
|
|
||||||
|
|
||||||
jobs: ReplicationJobItem[];
|
jobs: ReplicationJobItem[];
|
||||||
batchDelectionInfos: BatchInfo[] = [];
|
batchDelectionInfos: BatchInfo[] = [];
|
||||||
|
|
||||||
@ -124,11 +144,15 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
@ViewChild("replicationLogViewer")
|
@ViewChild("replicationLogViewer")
|
||||||
replicationLogViewer: JobLogViewerComponent;
|
replicationLogViewer: JobLogViewerComponent;
|
||||||
|
|
||||||
@ViewChild('replicationConfirmDialog')
|
@ViewChild("replicationConfirmDialog")
|
||||||
replicationConfirmDialog: ConfirmationDialogComponent;
|
replicationConfirmDialog: ConfirmationDialogComponent;
|
||||||
|
|
||||||
creationTimeComparator: Comparator<ReplicationJob> = new CustomComparator<ReplicationJob>('creation_time', 'date');
|
creationTimeComparator: Comparator<ReplicationJob> = new CustomComparator<
|
||||||
updateTimeComparator: Comparator<ReplicationJob> = new CustomComparator<ReplicationJob>('update_time', 'date');
|
ReplicationJob
|
||||||
|
>("creation_time", "date");
|
||||||
|
updateTimeComparator: Comparator<ReplicationJob> = new CustomComparator<
|
||||||
|
ReplicationJob
|
||||||
|
>("update_time", "date");
|
||||||
|
|
||||||
// Server driven pagination
|
// Server driven pagination
|
||||||
currentPage: number = 1;
|
currentPage: number = 1;
|
||||||
@ -141,9 +165,8 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
constructor(
|
constructor(
|
||||||
private errorHandler: ErrorHandler,
|
private errorHandler: ErrorHandler,
|
||||||
private replicationService: ReplicationService,
|
private replicationService: ReplicationService,
|
||||||
private translateService: TranslateService) {
|
private translateService: TranslateService
|
||||||
}
|
) {}
|
||||||
|
|
||||||
|
|
||||||
public get showPaginationIndex(): boolean {
|
public get showPaginationIndex(): boolean {
|
||||||
return this.totalCount > 0;
|
return this.totalCount > 0;
|
||||||
@ -185,26 +208,28 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
this.currentState = state;
|
this.currentState = state;
|
||||||
|
|
||||||
let pageNumber: number = calculatePage(state);
|
let pageNumber: number = calculatePage(state);
|
||||||
if (pageNumber <= 0) { pageNumber = 1; }
|
if (pageNumber <= 0) {
|
||||||
|
pageNumber = 1;
|
||||||
|
}
|
||||||
|
|
||||||
let params: RequestQueryParams = new RequestQueryParams();
|
let params: RequestQueryParams = new RequestQueryParams();
|
||||||
// Pagination
|
// Pagination
|
||||||
params.set("page", '' + pageNumber);
|
params.set("page", "" + pageNumber);
|
||||||
params.set("page_size", '' + this.pageSize);
|
params.set("page_size", "" + this.pageSize);
|
||||||
// Search by status
|
// Search by status
|
||||||
if (this.search.status.trim()) {
|
if (this.search.status.trim()) {
|
||||||
params.set('status', this.search.status);
|
params.set("status", this.search.status);
|
||||||
}
|
}
|
||||||
// Search by repository
|
// Search by repository
|
||||||
if (this.search.repoName.trim()) {
|
if (this.search.repoName.trim()) {
|
||||||
params.set('repository', this.search.repoName);
|
params.set("repository", this.search.repoName);
|
||||||
}
|
}
|
||||||
// Search by timestamps
|
// Search by timestamps
|
||||||
if (this.search.startTimestamp.trim()) {
|
if (this.search.startTimestamp.trim()) {
|
||||||
params.set('start_time', this.search.startTimestamp);
|
params.set("start_time", this.search.startTimestamp);
|
||||||
}
|
}
|
||||||
if (this.search.endTimestamp.trim()) {
|
if (this.search.endTimestamp.trim()) {
|
||||||
params.set('end_time', this.search.endTimestamp);
|
params.set("end_time", this.search.endTimestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.jobsLoading = true;
|
this.jobsLoading = true;
|
||||||
@ -214,18 +239,22 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
this.jobs = doSorting<ReplicationJobItem>(this.jobs, state);
|
this.jobs = doSorting<ReplicationJobItem>(this.jobs, state);
|
||||||
|
|
||||||
this.jobsLoading = false;
|
this.jobsLoading = false;
|
||||||
toPromise<ReplicationJob>(this.replicationService
|
toPromise<ReplicationJob>(
|
||||||
.getJobs(this.search.ruleId, params))
|
this.replicationService.getJobs(this.search.ruleId, params)
|
||||||
.then(
|
)
|
||||||
response => {
|
.then(response => {
|
||||||
this.totalCount = response.metadata.xTotalCount;
|
this.totalCount = response.metadata.xTotalCount;
|
||||||
this.jobs = response.data;
|
this.jobs = response.data;
|
||||||
|
|
||||||
if (!this.timerDelay) {
|
if (!this.timerDelay) {
|
||||||
this.timerDelay = Observable.timer(10000, 10000).subscribe(() => {
|
this.timerDelay = Observable.timer(10000, 10000).subscribe(() => {
|
||||||
let count: number = 0;
|
let count: number = 0;
|
||||||
this.jobs.forEach((job) => {
|
this.jobs.forEach(job => {
|
||||||
if ((job.status === 'pending') || (job.status === 'running') || (job.status === 'retrying')) {
|
if (
|
||||||
|
job.status === "pending" ||
|
||||||
|
job.status === "running" ||
|
||||||
|
job.status === "retrying"
|
||||||
|
) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -243,8 +272,8 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
this.jobs = doSorting<ReplicationJobItem>(this.jobs, state);
|
this.jobs = doSorting<ReplicationJobItem>(this.jobs, state);
|
||||||
|
|
||||||
this.jobsLoading = false;
|
this.jobsLoading = false;
|
||||||
|
})
|
||||||
}).catch(error => {
|
.catch(error => {
|
||||||
this.jobsLoading = false;
|
this.jobsLoading = false;
|
||||||
this.errorHandler.error(error);
|
this.errorHandler.error(error);
|
||||||
});
|
});
|
||||||
@ -267,11 +296,11 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
selectOneRule(rule: ReplicationRule) {
|
selectOneRule(rule: ReplicationRule) {
|
||||||
if (rule && rule.id) {
|
if (rule && rule.id) {
|
||||||
this.hiddenJobList = false;
|
this.hiddenJobList = false;
|
||||||
this.search.ruleId = rule.id || '';
|
this.search.ruleId = rule.id || "";
|
||||||
this.search.repoName = '';
|
this.search.repoName = "";
|
||||||
this.search.status = '';
|
this.search.status = "";
|
||||||
this.currentJobSearchOption = 0;
|
this.currentJobSearchOption = 0;
|
||||||
this.currentJobStatus = { 'key': 'all', 'description': 'REPLICATION.ALL' };
|
this.currentJobStatus = { key: "all", description: "REPLICATION.ALL" };
|
||||||
this.loadFirstPage();
|
this.loadFirstPage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,26 +312,31 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
initBatchMessage.name = rule.name;
|
initBatchMessage.name = rule.name;
|
||||||
this.batchDelectionInfos.push(initBatchMessage);
|
this.batchDelectionInfos.push(initBatchMessage);
|
||||||
let replicationMessage = new ConfirmationMessage(
|
let replicationMessage = new ConfirmationMessage(
|
||||||
'REPLICATION.REPLICATION_TITLE',
|
"REPLICATION.REPLICATION_TITLE",
|
||||||
'REPLICATION.REPLICATION_SUMMARY',
|
"REPLICATION.REPLICATION_SUMMARY",
|
||||||
rule.name,
|
rule.name,
|
||||||
rule,
|
rule,
|
||||||
ConfirmationTargets.TARGET,
|
ConfirmationTargets.TARGET,
|
||||||
ConfirmationButtons.REPLICATE_CANCEL);
|
ConfirmationButtons.REPLICATE_CANCEL
|
||||||
|
);
|
||||||
this.replicationConfirmDialog.open(replicationMessage);
|
this.replicationConfirmDialog.open(replicationMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmReplication(message: ConfirmationAcknowledgement) {
|
confirmReplication(message: ConfirmationAcknowledgement) {
|
||||||
if (message &&
|
if (
|
||||||
|
message &&
|
||||||
message.source === ConfirmationTargets.TARGET &&
|
message.source === ConfirmationTargets.TARGET &&
|
||||||
message.state === ConfirmationState.CONFIRMED) {
|
message.state === ConfirmationState.CONFIRMED
|
||||||
|
) {
|
||||||
let rule: ReplicationRule = message.data;
|
let rule: ReplicationRule = message.data;
|
||||||
|
|
||||||
if (rule) {
|
if (rule) {
|
||||||
Promise.all([this.replicationOperate(+rule.id, rule.name)]).then((item) => {
|
Promise.all([this.replicationOperate(+rule.id, rule.name)]).then(
|
||||||
|
item => {
|
||||||
this.selectOneRule(rule);
|
this.selectOneRule(rule);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,18 +346,28 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
return toPromise<any>(this.replicationService.replicateRule(ruleId))
|
return toPromise<any>(this.replicationService.replicateRule(ruleId))
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.translateService.get('BATCH.REPLICATE_SUCCESS')
|
this.translateService
|
||||||
.subscribe(res => findedList = BathInfoChanges(findedList, res));
|
.get("BATCH.REPLICATE_SUCCESS")
|
||||||
|
.subscribe(res => (findedList = BathInfoChanges(findedList, res)));
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
if (error && error.status === 412) {
|
if (error && error.status === 412) {
|
||||||
Observable.forkJoin(this.translateService.get('BATCH.REPLICATE_FAILURE'),
|
Observable.forkJoin(
|
||||||
this.translateService.get('REPLICATION.REPLICATE_SUMMARY_FAILURE'))
|
this.translateService.get("BATCH.REPLICATE_FAILURE"),
|
||||||
.subscribe(function (res) {
|
this.translateService.get("REPLICATION.REPLICATE_SUMMARY_FAILURE")
|
||||||
findedList = BathInfoChanges(findedList, res[0], false, true, res[1]);
|
).subscribe(function(res) {
|
||||||
|
findedList = BathInfoChanges(
|
||||||
|
findedList,
|
||||||
|
res[0],
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
res[1]
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.translateService.get('BATCH.REPLICATE_FAILURE').subscribe(res => {
|
this.translateService
|
||||||
|
.get("BATCH.REPLICATE_FAILURE")
|
||||||
|
.subscribe(res => {
|
||||||
findedList = BathInfoChanges(findedList, res, false, true);
|
findedList = BathInfoChanges(findedList, res, false, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -344,12 +388,11 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
let status = $event.target["value"];
|
let status = $event.target["value"];
|
||||||
|
|
||||||
this.currentJobStatus = this.jobStatus.find((r: any) => r.key === status);
|
this.currentJobStatus = this.jobStatus.find((r: any) => r.key === status);
|
||||||
if (this.currentJobStatus.key === 'all') {
|
if (this.currentJobStatus.key === "all") {
|
||||||
status = '';
|
status = "";
|
||||||
}
|
}
|
||||||
this.search.status = status;
|
this.search.status = status;
|
||||||
this.doSearchJobs(this.search.repoName);
|
this.doSearchJobs(this.search.repoName);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,7 +421,7 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
reloadRules(isReady: boolean) {
|
reloadRules(isReady: boolean) {
|
||||||
if (isReady) {
|
if (isReady) {
|
||||||
this.search.ruleName = '';
|
this.search.ruleName = "";
|
||||||
this.listReplicationRule.retrieveRules(this.search.ruleName);
|
this.listReplicationRule.retrieveRules(this.search.ruleName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -387,11 +430,10 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
this.listReplicationRule.retrieveRules();
|
this.listReplicationRule.retrieveRules();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
refreshJobs() {
|
refreshJobs() {
|
||||||
this.currentJobStatus = this.jobStatus[0];
|
this.currentJobStatus = this.jobStatus[0];
|
||||||
this.search.startTime = ' ';
|
this.search.startTime = " ";
|
||||||
this.search.endTime = ' ';
|
this.search.endTime = " ";
|
||||||
this.search.repoName = "";
|
this.search.repoName = "";
|
||||||
this.search.startTimestamp = "";
|
this.search.startTimestamp = "";
|
||||||
this.search.endTimestamp = "";
|
this.search.endTimestamp = "";
|
||||||
@ -410,7 +452,9 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggleSearchJobOptionalName(option: number) {
|
toggleSearchJobOptionalName(option: number) {
|
||||||
(option === 1) ? this.currentJobSearchOption = 0 : this.currentJobSearchOption = 1;
|
option === 1
|
||||||
|
? (this.currentJobSearchOption = 0)
|
||||||
|
: (this.currentJobSearchOption = 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
doJobSearchByStartTime(fromTimestamp: string) {
|
doJobSearchByStartTime(fromTimestamp: string) {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<div class="row flex-items-xs-right option-right rightPos">
|
<div class="row flex-items-xs-right option-right rightPos">
|
||||||
<div class="flex-xs-middle">
|
<div class="flex-xs-middle">
|
||||||
<hbr-push-image-button style="display: inline-block;" [registryUrl]="registryUrl" [projectName]="projectName"></hbr-push-image-button>
|
<hbr-push-image-button style="display: inline-block;" [registryUrl]="registryUrl" [projectName]="projectName"></hbr-push-image-button>
|
||||||
<hbr-filter [withDivider]="true" filterPlaceholder="{{'REPOSITORY.FILTER_FOR_REPOSITORIES' | translate}}" (filter)="doSearchRepoNames($event)" [currentValue]="lastFilteredRepoName"></hbr-filter>
|
<hbr-filter [withDivider]="true" filterPlaceholder="{{'REPOSITORY.FILTER_FOR_REPOSITORIES' | translate}}" (filterEvt)="doSearchRepoNames($event)" [currentValue]="lastFilteredRepoName"></hbr-filter>
|
||||||
<span class="card-btn" (click)="showCard(true)" (mouseenter) ="mouseEnter('card') " (mouseleave) ="mouseLeave('card')">
|
<span class="card-btn" (click)="showCard(true)" (mouseenter) ="mouseEnter('card') " (mouseleave) ="mouseLeave('card')">
|
||||||
<clr-icon [ngClass]="{'is-highlight': isCardView || isHovering('card') }" shape="view-cards"></clr-icon>
|
<clr-icon [ngClass]="{'is-highlight': isCardView || isHovering('card') }" shape="view-cards"></clr-icon>
|
||||||
</span>
|
</span>
|
||||||
|
@ -11,26 +11,23 @@ import { TagComponent } from '../tag/tag.component';
|
|||||||
import { FilterComponent } from '../filter/filter.component';
|
import { FilterComponent } from '../filter/filter.component';
|
||||||
|
|
||||||
import { ErrorHandler } from '../error-handler/error-handler';
|
import { ErrorHandler } from '../error-handler/error-handler';
|
||||||
import { Repository, RepositoryItem, Tag, SystemInfo } from '../service/interface';
|
import { Repository, RepositoryItem, SystemInfo } from '../service/interface';
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
||||||
import { RepositoryService, RepositoryDefaultService } from '../service/repository.service';
|
import { RepositoryService, RepositoryDefaultService } from '../service/repository.service';
|
||||||
import { TagService, TagDefaultService } from '../service/tag.service';
|
import { TagService, TagDefaultService } from '../service/tag.service';
|
||||||
import { SystemInfoService, SystemInfoDefaultService } from '../service/system-info.service';
|
import { SystemInfoService, SystemInfoDefaultService } from '../service/system-info.service';
|
||||||
import { VULNERABILITY_DIRECTIVES } from '../vulnerability-scanning/index';
|
import { VULNERABILITY_DIRECTIVES } from '../vulnerability-scanning/index';
|
||||||
import { HBR_GRIDVIEW_DIRECTIVES } from '../gridview/index'
|
import { HBR_GRIDVIEW_DIRECTIVES } from '../gridview/index';
|
||||||
import { PUSH_IMAGE_BUTTON_DIRECTIVES } from '../push-image/index';
|
import { PUSH_IMAGE_BUTTON_DIRECTIVES } from '../push-image/index';
|
||||||
import { INLINE_ALERT_DIRECTIVES } from '../inline-alert/index';
|
import { INLINE_ALERT_DIRECTIVES } from '../inline-alert/index';
|
||||||
import { JobLogViewerComponent } from '../job-log-viewer/index';
|
import { JobLogViewerComponent } from '../job-log-viewer/index';
|
||||||
import {LabelPieceComponent} from "../label-piece/label-piece.component";
|
import {LabelPieceComponent} from "../label-piece/label-piece.component";
|
||||||
|
|
||||||
import { click } from '../utils';
|
|
||||||
|
|
||||||
describe('RepositoryComponentGridview (inline template)', () => {
|
describe('RepositoryComponentGridview (inline template)', () => {
|
||||||
|
|
||||||
let compRepo: RepositoryGridviewComponent;
|
let compRepo: RepositoryGridviewComponent;
|
||||||
let fixtureRepo: ComponentFixture<RepositoryGridviewComponent>;
|
let fixtureRepo: ComponentFixture<RepositoryGridviewComponent>;
|
||||||
let repositoryService: RepositoryService;
|
let repositoryService: RepositoryService;
|
||||||
let tagService: TagService;
|
|
||||||
let systemInfoService: SystemInfoService;
|
let systemInfoService: SystemInfoService;
|
||||||
|
|
||||||
let spyRepos: jasmine.Spy;
|
let spyRepos: jasmine.Spy;
|
||||||
@ -74,20 +71,20 @@ describe('RepositoryComponentGridview (inline template)', () => {
|
|||||||
data: mockRepoData
|
data: mockRepoData
|
||||||
};
|
};
|
||||||
|
|
||||||
let mockTagData: Tag[] = [
|
// let mockTagData: Tag[] = [
|
||||||
{
|
// {
|
||||||
"digest": "sha256:e5c82328a509aeb7c18c1d7fb36633dc638fcf433f651bdcda59c1cc04d3ee55",
|
// "digest": "sha256:e5c82328a509aeb7c18c1d7fb36633dc638fcf433f651bdcda59c1cc04d3ee55",
|
||||||
"name": "1.11.5",
|
// "name": "1.11.5",
|
||||||
"size": "2049",
|
// "size": "2049",
|
||||||
"architecture": "amd64",
|
// "architecture": "amd64",
|
||||||
"os": "linux",
|
// "os": "linux",
|
||||||
"docker_version": "1.12.3",
|
// "docker_version": "1.12.3",
|
||||||
"author": "NGINX Docker Maintainers \"docker-maint@nginx.com\"",
|
// "author": "NGINX Docker Maintainers \"docker-maint@nginx.com\"",
|
||||||
"created": new Date("2016-11-08T22:41:15.912313785Z"),
|
// "created": new Date("2016-11-08T22:41:15.912313785Z"),
|
||||||
"signature": null,
|
// "signature": null,
|
||||||
"labels": []
|
// "labels": []
|
||||||
}
|
// }
|
||||||
];
|
// ];
|
||||||
|
|
||||||
let config: IServiceConfig = {
|
let config: IServiceConfig = {
|
||||||
repositoryBaseEndpoint: '/api/repository/testing',
|
repositoryBaseEndpoint: '/api/repository/testing',
|
||||||
|
@ -1,36 +1,68 @@
|
|||||||
import { Component, Input, Output, OnInit, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef, EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
|
import {
|
||||||
import { Router } from '@angular/router';
|
Component,
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
Input,
|
||||||
|
Output,
|
||||||
|
OnInit,
|
||||||
|
ViewChild,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorRef,
|
||||||
|
EventEmitter,
|
||||||
|
OnChanges,
|
||||||
|
SimpleChanges
|
||||||
|
} from "@angular/core";
|
||||||
|
import { Router } from "@angular/router";
|
||||||
import { Observable } from "rxjs/Observable";
|
import { Observable } from "rxjs/Observable";
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
import { Comparator, State } from 'clarity-angular';
|
import { Comparator, State } from "clarity-angular";
|
||||||
|
|
||||||
import { Repository, SystemInfo, SystemInfoService, RepositoryService, RequestQueryParams, RepositoryItem, TagService } from '../service/index';
|
|
||||||
import { ErrorHandler } from '../error-handler/error-handler';
|
|
||||||
import { toPromise, CustomComparator , DEFAULT_PAGE_SIZE, calculatePage, doFiltering, doSorting, clone} from '../utils';
|
|
||||||
import { ConfirmationState, ConfirmationTargets, ConfirmationButtons } from '../shared/shared.const';
|
|
||||||
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
|
||||||
import { ConfirmationMessage } from '../confirmation-dialog/confirmation-message';
|
|
||||||
import { ConfirmationAcknowledgement } from '../confirmation-dialog/confirmation-state-message';
|
|
||||||
import { Tag, CardItemEvent } from '../service/interface';
|
|
||||||
import {BatchInfo, BathInfoChanges} from "../confirmation-dialog/confirmation-batch-message";
|
|
||||||
import { GridViewComponent } from '../gridview/grid-view.component';
|
|
||||||
|
|
||||||
|
import {
|
||||||
|
Repository,
|
||||||
|
SystemInfo,
|
||||||
|
SystemInfoService,
|
||||||
|
RepositoryService,
|
||||||
|
RequestQueryParams,
|
||||||
|
RepositoryItem,
|
||||||
|
TagService
|
||||||
|
} from "../service/index";
|
||||||
|
import { ErrorHandler } from "../error-handler/error-handler";
|
||||||
|
import {
|
||||||
|
toPromise,
|
||||||
|
CustomComparator,
|
||||||
|
DEFAULT_PAGE_SIZE,
|
||||||
|
calculatePage,
|
||||||
|
doFiltering,
|
||||||
|
doSorting,
|
||||||
|
clone
|
||||||
|
} from "../utils";
|
||||||
|
import {
|
||||||
|
ConfirmationState,
|
||||||
|
ConfirmationTargets,
|
||||||
|
ConfirmationButtons
|
||||||
|
} from "../shared/shared.const";
|
||||||
|
import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation-dialog.component";
|
||||||
|
import { ConfirmationMessage } from "../confirmation-dialog/confirmation-message";
|
||||||
|
import { ConfirmationAcknowledgement } from "../confirmation-dialog/confirmation-state-message";
|
||||||
|
import { Tag } from "../service/interface";
|
||||||
|
import {
|
||||||
|
BatchInfo,
|
||||||
|
BathInfoChanges
|
||||||
|
} from "../confirmation-dialog/confirmation-batch-message";
|
||||||
|
import { GridViewComponent } from "../gridview/grid-view.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-repository-gridview',
|
selector: "hbr-repository-gridview",
|
||||||
templateUrl: './repository-gridview.component.html',
|
templateUrl: "./repository-gridview.component.html",
|
||||||
styleUrls: ['./repository-gridview.component.scss'],
|
styleUrls: ["./repository-gridview.component.scss"],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
||||||
signedCon: { [key: string]: any | string[] } = {};
|
signedCon: { [key: string]: any | string[] } = {};
|
||||||
@Input() projectId: number;
|
@Input() projectId: number;
|
||||||
@Input() projectName = 'unknown';
|
@Input() projectName = "unknown";
|
||||||
@Input() urlPrefix: string;
|
@Input() urlPrefix: string;
|
||||||
@Input() hasSignedIn: boolean;
|
@Input() hasSignedIn: boolean;
|
||||||
@Input() hasProjectAdminRole: boolean;
|
@Input() hasProjectAdminRole: boolean;
|
||||||
@Input() mode = 'admiral';
|
@Input() mode = "admiral";
|
||||||
@Output() repoClickEvent = new EventEmitter<RepositoryItem>();
|
@Output() repoClickEvent = new EventEmitter<RepositoryItem>();
|
||||||
@Output() repoProvisionEvent = new EventEmitter<RepositoryItem>();
|
@Output() repoProvisionEvent = new EventEmitter<RepositoryItem>();
|
||||||
@Output() addInfoEvent = new EventEmitter<RepositoryItem>();
|
@Output() addInfoEvent = new EventEmitter<RepositoryItem>();
|
||||||
@ -47,20 +79,22 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
listHover = false;
|
listHover = false;
|
||||||
|
|
||||||
batchDelectionInfos: BatchInfo[] = [];
|
batchDelectionInfos: BatchInfo[] = [];
|
||||||
pullCountComparator: Comparator<RepositoryItem> = new CustomComparator<RepositoryItem>('pull_count', 'number');
|
pullCountComparator: Comparator<RepositoryItem> = new CustomComparator<
|
||||||
tagsCountComparator: Comparator<RepositoryItem> = new CustomComparator<RepositoryItem>('tags_count', 'number');
|
RepositoryItem
|
||||||
|
>("pull_count", "number");
|
||||||
|
tagsCountComparator: Comparator<RepositoryItem> = new CustomComparator<
|
||||||
|
RepositoryItem
|
||||||
|
>("tags_count", "number");
|
||||||
|
|
||||||
pageSize: number = DEFAULT_PAGE_SIZE;
|
pageSize: number = DEFAULT_PAGE_SIZE;
|
||||||
currentPage = 1;
|
currentPage = 1;
|
||||||
totalCount = 0;
|
totalCount = 0;
|
||||||
currentState: State;
|
currentState: State;
|
||||||
|
|
||||||
@ViewChild('confirmationDialog')
|
@ViewChild("confirmationDialog")
|
||||||
confirmationDialog: ConfirmationDialogComponent;
|
confirmationDialog: ConfirmationDialogComponent;
|
||||||
|
|
||||||
@ViewChild('gridView')
|
@ViewChild("gridView") gridView: GridViewComponent;
|
||||||
gridView: GridViewComponent;
|
|
||||||
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private errorHandler: ErrorHandler,
|
private errorHandler: ErrorHandler,
|
||||||
@ -69,10 +103,11 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
private systemInfoService: SystemInfoService,
|
private systemInfoService: SystemInfoService,
|
||||||
private tagService: TagService,
|
private tagService: TagService,
|
||||||
private ref: ChangeDetectorRef,
|
private ref: ChangeDetectorRef,
|
||||||
private router: Router) { }
|
private router: Router
|
||||||
|
) {}
|
||||||
|
|
||||||
public get registryUrl(): string {
|
public get registryUrl(): string {
|
||||||
return this.systemInfo ? this.systemInfo.registry_url : '';
|
return this.systemInfo ? this.systemInfo.registry_url : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public get withClair(): boolean {
|
public get withClair(): boolean {
|
||||||
@ -80,13 +115,15 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get isClairDBReady(): boolean {
|
public get isClairDBReady(): boolean {
|
||||||
return this.systemInfo &&
|
return (
|
||||||
|
this.systemInfo &&
|
||||||
this.systemInfo.clair_vulnerability_status &&
|
this.systemInfo.clair_vulnerability_status &&
|
||||||
this.systemInfo.clair_vulnerability_status.overall_last_update > 0;
|
this.systemInfo.clair_vulnerability_status.overall_last_update > 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get withAdmiral(): boolean {
|
public get withAdmiral(): boolean {
|
||||||
return this.mode === 'admiral'
|
return this.mode === "admiral";
|
||||||
}
|
}
|
||||||
|
|
||||||
public get showDBStatusWarning(): boolean {
|
public get showDBStatusWarning(): boolean {
|
||||||
@ -94,7 +131,7 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
if (changes['projectId'] && changes['projectId'].currentValue) {
|
if (changes["projectId"] && changes["projectId"].currentValue) {
|
||||||
this.refresh();
|
this.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,31 +139,32 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
// Get system info for tag views
|
// Get system info for tag views
|
||||||
toPromise<SystemInfo>(this.systemInfoService.getSystemInfo())
|
toPromise<SystemInfo>(this.systemInfoService.getSystemInfo())
|
||||||
.then(systemInfo => this.systemInfo = systemInfo)
|
.then(systemInfo => (this.systemInfo = systemInfo))
|
||||||
.catch(error => this.errorHandler.error(error));
|
.catch(error => this.errorHandler.error(error));
|
||||||
|
|
||||||
if (this.mode === 'admiral') {
|
if (this.mode === "admiral") {
|
||||||
this.isCardView = true;
|
this.isCardView = true;
|
||||||
} else {
|
} else {
|
||||||
this.isCardView = false;
|
this.isCardView = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lastFilteredRepoName = '';
|
this.lastFilteredRepoName = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmDeletion(message: ConfirmationAcknowledgement) {
|
confirmDeletion(message: ConfirmationAcknowledgement) {
|
||||||
if (message &&
|
if (
|
||||||
|
message &&
|
||||||
message.source === ConfirmationTargets.REPOSITORY &&
|
message.source === ConfirmationTargets.REPOSITORY &&
|
||||||
message.state === ConfirmationState.CONFIRMED) {
|
message.state === ConfirmationState.CONFIRMED
|
||||||
|
) {
|
||||||
let promiseLists: any[] = [];
|
let promiseLists: any[] = [];
|
||||||
let repoNames: string[] = message.data.split(',');
|
let repoNames: string[] = message.data.split(",");
|
||||||
|
|
||||||
repoNames.forEach(repoName => {
|
repoNames.forEach(repoName => {
|
||||||
promiseLists.push(this.delOperate(repoName));
|
promiseLists.push(this.delOperate(repoName));
|
||||||
});
|
});
|
||||||
|
|
||||||
Promise.all(promiseLists).then((item) => {
|
Promise.all(promiseLists).then(item => {
|
||||||
this.selectedRow = [];
|
this.selectedRow = [];
|
||||||
this.refresh();
|
this.refresh();
|
||||||
let st: State = this.getStateAfterDeletion();
|
let st: State = this.getStateAfterDeletion();
|
||||||
@ -140,36 +178,57 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
delOperate(repoName: string) {
|
delOperate(repoName: string) {
|
||||||
let findedList = this.batchDelectionInfos.find(data => data.name === repoName);
|
let findedList = this.batchDelectionInfos.find(
|
||||||
|
data => data.name === repoName
|
||||||
|
);
|
||||||
if (this.signedCon[repoName].length !== 0) {
|
if (this.signedCon[repoName].length !== 0) {
|
||||||
Observable.forkJoin(this.translateService.get('BATCH.DELETED_FAILURE'),
|
Observable.forkJoin(
|
||||||
this.translateService.get('REPOSITORY.DELETION_TITLE_REPO_SIGNED')).subscribe(res => {
|
this.translateService.get("BATCH.DELETED_FAILURE"),
|
||||||
|
this.translateService.get("REPOSITORY.DELETION_TITLE_REPO_SIGNED")
|
||||||
|
).subscribe(res => {
|
||||||
findedList = BathInfoChanges(findedList, res[0], false, true, res[1]);
|
findedList = BathInfoChanges(findedList, res[0], false, true, res[1]);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return toPromise<number>(this.repositoryService
|
return toPromise<number>(
|
||||||
.deleteRepository(repoName))
|
this.repositoryService.deleteRepository(repoName)
|
||||||
.then(
|
)
|
||||||
response => {
|
.then(response => {
|
||||||
this.translateService.get('BATCH.DELETED_SUCCESS').subscribe(res => {
|
this.translateService.get("BATCH.DELETED_SUCCESS").subscribe(res => {
|
||||||
findedList = BathInfoChanges(findedList, res);
|
findedList = BathInfoChanges(findedList, res);
|
||||||
});
|
});
|
||||||
}).catch(error => {
|
})
|
||||||
|
.catch(error => {
|
||||||
if (error.status === "412") {
|
if (error.status === "412") {
|
||||||
Observable.forkJoin(this.translateService.get('BATCH.DELETED_FAILURE'),
|
Observable.forkJoin(
|
||||||
this.translateService.get('REPOSITORY.TAGS_SIGNED')).subscribe(res => {
|
this.translateService.get("BATCH.DELETED_FAILURE"),
|
||||||
findedList = BathInfoChanges(findedList, res[0], false, true, res[1]);
|
this.translateService.get("REPOSITORY.TAGS_SIGNED")
|
||||||
|
).subscribe(res => {
|
||||||
|
findedList = BathInfoChanges(
|
||||||
|
findedList,
|
||||||
|
res[0],
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
res[1]
|
||||||
|
);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error.status === 503) {
|
if (error.status === 503) {
|
||||||
Observable.forkJoin(this.translateService.get('BATCH.DELETED_FAILURE'),
|
Observable.forkJoin(
|
||||||
this.translateService.get('REPOSITORY.TAGS_NO_DELETE')).subscribe(res => {
|
this.translateService.get("BATCH.DELETED_FAILURE"),
|
||||||
findedList = BathInfoChanges(findedList, res[0], false, true, res[1]);
|
this.translateService.get("REPOSITORY.TAGS_NO_DELETE")
|
||||||
|
).subscribe(res => {
|
||||||
|
findedList = BathInfoChanges(
|
||||||
|
findedList,
|
||||||
|
res[0],
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
res[1]
|
||||||
|
);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.translateService.get('BATCH.DELETED_FAILURE').subscribe(res => {
|
this.translateService.get("BATCH.DELETED_FAILURE").subscribe(res => {
|
||||||
findedList = BathInfoChanges(findedList, res, false, true);
|
findedList = BathInfoChanges(findedList, res, false, true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -211,15 +270,20 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Promise.all(repArr).then(() => {
|
Promise.all(repArr).then(() => {
|
||||||
this.confirmationDialogSet('REPOSITORY.DELETION_TITLE_REPO', '', repoNames.join(','), 'REPOSITORY.DELETION_SUMMARY_REPO', ConfirmationButtons.DELETE_CANCEL);
|
this.confirmationDialogSet(
|
||||||
|
"REPOSITORY.DELETION_TITLE_REPO",
|
||||||
|
"",
|
||||||
|
repoNames.join(","),
|
||||||
|
"REPOSITORY.DELETION_SUMMARY_REPO",
|
||||||
|
ConfirmationButtons.DELETE_CANCEL
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getTagInfo(repoName: string): Promise<void> {
|
getTagInfo(repoName: string): Promise<void> {
|
||||||
this.signedCon[repoName] = [];
|
this.signedCon[repoName] = [];
|
||||||
return toPromise<Tag[]>(this.tagService
|
return toPromise<Tag[]>(this.tagService.getTags(repoName))
|
||||||
.getTags(repoName))
|
|
||||||
.then(items => {
|
.then(items => {
|
||||||
items.forEach((t: Tag) => {
|
items.forEach((t: Tag) => {
|
||||||
if (t.signature !== null) {
|
if (t.signature !== null) {
|
||||||
@ -231,20 +295,38 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
signedDataSet(repoName: string): void {
|
signedDataSet(repoName: string): void {
|
||||||
let signature = '';
|
let signature = "";
|
||||||
if (this.signedCon[repoName].length === 0) {
|
if (this.signedCon[repoName].length === 0) {
|
||||||
this.confirmationDialogSet('REPOSITORY.DELETION_TITLE_REPO', signature, repoName, 'REPOSITORY.DELETION_SUMMARY_REPO', ConfirmationButtons.DELETE_CANCEL);
|
this.confirmationDialogSet(
|
||||||
|
"REPOSITORY.DELETION_TITLE_REPO",
|
||||||
|
signature,
|
||||||
|
repoName,
|
||||||
|
"REPOSITORY.DELETION_SUMMARY_REPO",
|
||||||
|
ConfirmationButtons.DELETE_CANCEL
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
signature = this.signedCon[repoName].join(',');
|
signature = this.signedCon[repoName].join(",");
|
||||||
this.confirmationDialogSet('REPOSITORY.DELETION_TITLE_REPO_SIGNED', signature, repoName, 'REPOSITORY.DELETION_SUMMARY_REPO_SIGNED', ConfirmationButtons.CLOSE);
|
this.confirmationDialogSet(
|
||||||
|
"REPOSITORY.DELETION_TITLE_REPO_SIGNED",
|
||||||
|
signature,
|
||||||
|
repoName,
|
||||||
|
"REPOSITORY.DELETION_SUMMARY_REPO_SIGNED",
|
||||||
|
ConfirmationButtons.CLOSE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmationDialogSet(summaryTitle: string, signature: string, repoName: string, summaryKey: string, button: ConfirmationButtons): void {
|
confirmationDialogSet(
|
||||||
this.translateService.get(summaryKey,
|
summaryTitle: string,
|
||||||
{
|
signature: string,
|
||||||
|
repoName: string,
|
||||||
|
summaryKey: string,
|
||||||
|
button: ConfirmationButtons
|
||||||
|
): void {
|
||||||
|
this.translateService
|
||||||
|
.get(summaryKey, {
|
||||||
repoName: repoName,
|
repoName: repoName,
|
||||||
signedImages: signature,
|
signedImages: signature
|
||||||
})
|
})
|
||||||
.subscribe((res: string) => {
|
.subscribe((res: string) => {
|
||||||
summaryKey = res;
|
summaryKey = res;
|
||||||
@ -254,7 +336,8 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
repoName,
|
repoName,
|
||||||
repoName,
|
repoName,
|
||||||
ConfirmationTargets.REPOSITORY,
|
ConfirmationTargets.REPOSITORY,
|
||||||
button);
|
button
|
||||||
|
);
|
||||||
this.confirmationDialog.open(message);
|
this.confirmationDialog.open(message);
|
||||||
|
|
||||||
let hnd = setInterval(() => this.ref.markForCheck(), 100);
|
let hnd = setInterval(() => this.ref.markForCheck(), 100);
|
||||||
@ -264,15 +347,15 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
|
|
||||||
provisionItemEvent(evt: any, repo: RepositoryItem): void {
|
provisionItemEvent(evt: any, repo: RepositoryItem): void {
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
let repoCopy = clone(repo)
|
let repoCopy = clone(repo);
|
||||||
repoCopy.name = this.registryUrl + ':443/' + repoCopy.name;
|
repoCopy.name = this.registryUrl + ":443/" + repoCopy.name;
|
||||||
this.repoProvisionEvent.emit(repoCopy);
|
this.repoProvisionEvent.emit(repoCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
itemAddInfoEvent(evt: any, repo: RepositoryItem): void {
|
itemAddInfoEvent(evt: any, repo: RepositoryItem): void {
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
let repoCopy = clone(repo)
|
let repoCopy = clone(repo);
|
||||||
repoCopy.name = this.registryUrl + ':443/' + repoCopy.name;
|
repoCopy.name = this.registryUrl + ":443/" + repoCopy.name;
|
||||||
this.addInfoEvent.emit(repoCopy);
|
this.addInfoEvent.emit(repoCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,33 +370,42 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
this.doSearchRepoNames('');
|
this.doSearchRepoNames("");
|
||||||
}
|
}
|
||||||
|
|
||||||
loadNextPage() {
|
loadNextPage() {
|
||||||
if (this.currentPage * this.pageSize >= this.totalCount) {
|
if (this.currentPage * this.pageSize >= this.totalCount) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.currentPage = this.currentPage + 1;
|
this.currentPage = this.currentPage + 1;
|
||||||
|
|
||||||
// Pagination
|
// Pagination
|
||||||
let params: RequestQueryParams = new RequestQueryParams();
|
let params: RequestQueryParams = new RequestQueryParams();
|
||||||
params.set("page", '' + this.currentPage);
|
params.set("page", "" + this.currentPage);
|
||||||
params.set("page_size", '' + this.pageSize);
|
params.set("page_size", "" + this.pageSize);
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
||||||
toPromise<Repository>(this.repositoryService.getRepositories(
|
toPromise<Repository>(
|
||||||
|
this.repositoryService.getRepositories(
|
||||||
this.projectId,
|
this.projectId,
|
||||||
this.lastFilteredRepoName,
|
this.lastFilteredRepoName,
|
||||||
params))
|
params
|
||||||
|
)
|
||||||
|
)
|
||||||
.then((repo: Repository) => {
|
.then((repo: Repository) => {
|
||||||
this.totalCount = repo.metadata.xTotalCount;
|
this.totalCount = repo.metadata.xTotalCount;
|
||||||
this.repositoriesCopy = repo.data;
|
this.repositoriesCopy = repo.data;
|
||||||
this.signedCon = {};
|
this.signedCon = {};
|
||||||
// Do filtering and sorting
|
// Do filtering and sorting
|
||||||
this.repositoriesCopy = doFiltering<RepositoryItem>(this.repositoriesCopy, this.currentState);
|
this.repositoriesCopy = doFiltering<RepositoryItem>(
|
||||||
this.repositoriesCopy = doSorting<RepositoryItem>(this.repositoriesCopy, this.currentState);
|
this.repositoriesCopy,
|
||||||
|
this.currentState
|
||||||
|
);
|
||||||
|
this.repositoriesCopy = doSorting<RepositoryItem>(
|
||||||
|
this.repositoriesCopy,
|
||||||
|
this.currentState
|
||||||
|
);
|
||||||
this.repositories = this.repositories.concat(this.repositoriesCopy);
|
this.repositories = this.repositories.concat(this.repositoriesCopy);
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
})
|
})
|
||||||
@ -331,26 +423,34 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
this.currentState = state;
|
this.currentState = state;
|
||||||
|
|
||||||
let pageNumber: number = calculatePage(state);
|
let pageNumber: number = calculatePage(state);
|
||||||
if (pageNumber <= 0) { pageNumber = 1; }
|
if (pageNumber <= 0) {
|
||||||
|
pageNumber = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Pagination
|
// Pagination
|
||||||
let params: RequestQueryParams = new RequestQueryParams();
|
let params: RequestQueryParams = new RequestQueryParams();
|
||||||
params.set("page", '' + pageNumber);
|
params.set("page", "" + pageNumber);
|
||||||
params.set("page_size", '' + this.pageSize);
|
params.set("page_size", "" + this.pageSize);
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
||||||
toPromise<Repository>(this.repositoryService.getRepositories(
|
toPromise<Repository>(
|
||||||
|
this.repositoryService.getRepositories(
|
||||||
this.projectId,
|
this.projectId,
|
||||||
this.lastFilteredRepoName,
|
this.lastFilteredRepoName,
|
||||||
params))
|
params
|
||||||
|
)
|
||||||
|
)
|
||||||
.then((repo: Repository) => {
|
.then((repo: Repository) => {
|
||||||
this.totalCount = repo.metadata.xTotalCount;
|
this.totalCount = repo.metadata.xTotalCount;
|
||||||
this.repositories = repo.data;
|
this.repositories = repo.data;
|
||||||
|
|
||||||
this.signedCon = {};
|
this.signedCon = {};
|
||||||
// Do filtering and sorting
|
// Do filtering and sorting
|
||||||
this.repositories = doFiltering<RepositoryItem>(this.repositories, state);
|
this.repositories = doFiltering<RepositoryItem>(
|
||||||
|
this.repositories,
|
||||||
|
state
|
||||||
|
);
|
||||||
this.repositories = doSorting<RepositoryItem>(this.repositories, state);
|
this.repositories = doSorting<RepositoryItem>(this.repositories, state);
|
||||||
|
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
@ -367,7 +467,9 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
|
|
||||||
getStateAfterDeletion(): State {
|
getStateAfterDeletion(): State {
|
||||||
let total: number = this.totalCount - 1;
|
let total: number = this.totalCount - 1;
|
||||||
if (total <= 0) { return null; }
|
if (total <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
let totalPages: number = Math.ceil(total / this.pageSize);
|
let totalPages: number = Math.ceil(total / this.pageSize);
|
||||||
let targetPageNumber: number = this.currentPage;
|
let targetPageNumber: number = this.currentPage;
|
||||||
@ -392,25 +494,25 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getImgLink(repo: RepositoryItem): string {
|
getImgLink(repo: RepositoryItem): string {
|
||||||
return '/container-image-icons?container-image=' + repo.name
|
return "/container-image-icons?container-image=" + repo.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRepoDescrition(repo: RepositoryItem): string {
|
getRepoDescrition(repo: RepositoryItem): string {
|
||||||
if (repo && repo.description) {
|
if (repo && repo.description) {
|
||||||
return repo.description;
|
return repo.description;
|
||||||
}
|
}
|
||||||
return "No description for this repo. You can add it to this repository."
|
return "No description for this repo. You can add it to this repository.";
|
||||||
}
|
}
|
||||||
showCard(cardView: boolean) {
|
showCard(cardView: boolean) {
|
||||||
if (this.isCardView === cardView) {
|
if (this.isCardView === cardView) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.isCardView = cardView;
|
this.isCardView = cardView;
|
||||||
this.refresh();
|
this.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
mouseEnter(itemName: string) {
|
mouseEnter(itemName: string) {
|
||||||
if (itemName === 'card') {
|
if (itemName === "card") {
|
||||||
this.cardHover = true;
|
this.cardHover = true;
|
||||||
} else {
|
} else {
|
||||||
this.listHover = true;
|
this.listHover = true;
|
||||||
@ -418,7 +520,7 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mouseLeave(itemName: string) {
|
mouseLeave(itemName: string) {
|
||||||
if (itemName === 'card') {
|
if (itemName === "card") {
|
||||||
this.cardHover = false;
|
this.cardHover = false;
|
||||||
} else {
|
} else {
|
||||||
this.listHover = false;
|
this.listHover = false;
|
||||||
@ -426,7 +528,7 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isHovering(itemName: string) {
|
isHovering(itemName: string) {
|
||||||
if (itemName === 'card') {
|
if (itemName === "card") {
|
||||||
return this.cardHover;
|
return this.cardHover;
|
||||||
} else {
|
} else {
|
||||||
return this.listHover;
|
return this.listHover;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { ComponentFixture, TestBed, async, } from '@angular/core/testing';
|
import { ComponentFixture, TestBed, async, } from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import {Component, DebugElement} from '@angular/core';
|
import { DebugElement} from '@angular/core';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
|
|
||||||
import { SharedModule } from '../shared/shared.module';
|
import { SharedModule } from '../shared/shared.module';
|
||||||
@ -118,7 +118,7 @@ describe('RepositoryComponent (inline template)', () => {
|
|||||||
project_id: 0,
|
project_id: 0,
|
||||||
scope: "g",
|
scope: "g",
|
||||||
update_time: "",
|
update_time: "",
|
||||||
}]
|
}];
|
||||||
|
|
||||||
let mockLabels1: Label[] = [{
|
let mockLabels1: Label[] = [{
|
||||||
color: "#9b0d54",
|
color: "#9b0d54",
|
||||||
@ -139,7 +139,7 @@ describe('RepositoryComponent (inline template)', () => {
|
|||||||
project_id: 1,
|
project_id: 1,
|
||||||
scope: "p",
|
scope: "p",
|
||||||
update_time: "",
|
update_time: "",
|
||||||
}]
|
}];
|
||||||
|
|
||||||
let config: IServiceConfig = {
|
let config: IServiceConfig = {
|
||||||
repositoryBaseEndpoint: '/api/repository/testing',
|
repositoryBaseEndpoint: '/api/repository/testing',
|
||||||
|
@ -114,7 +114,7 @@ export interface IServiceConfig {
|
|||||||
* @type {string}
|
* @type {string}
|
||||||
* @memberOf IServiceConfig
|
* @memberOf IServiceConfig
|
||||||
*/
|
*/
|
||||||
langCookieKey?: string,
|
langCookieKey?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare what languages are supported.
|
* Declare what languages are supported.
|
||||||
@ -122,13 +122,13 @@ export interface IServiceConfig {
|
|||||||
* @type {string[]}
|
* @type {string[]}
|
||||||
* @memberOf IServiceConfig
|
* @memberOf IServiceConfig
|
||||||
*/
|
*/
|
||||||
supportedLangs?: string[],
|
supportedLangs?: string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define the default language the translate service uses.
|
* Define the default language the translate service uses.
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
* @memberOf i18nConfig
|
* @memberOf I18nConfig
|
||||||
*/
|
*/
|
||||||
defaultLang?: string;
|
defaultLang?: string;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { URLSearchParams } from '@angular/http';
|
import { URLSearchParams } from "@angular/http";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap the class 'URLSearchParams' for future extending requirements.
|
* Wrap the class 'URLSearchParams' for future extending requirements.
|
||||||
@ -9,6 +9,7 @@ import { URLSearchParams } from '@angular/http';
|
|||||||
* @extends {URLSearchParams}
|
* @extends {URLSearchParams}
|
||||||
*/
|
*/
|
||||||
export class RequestQueryParams extends URLSearchParams {
|
export class RequestQueryParams extends URLSearchParams {
|
||||||
|
constructor() {
|
||||||
constructor() { super(); }
|
super();
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,11 +1,11 @@
|
|||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from "rxjs/Observable";
|
||||||
import { RequestQueryParams } from './RequestQueryParams';
|
import { RequestQueryParams } from "./RequestQueryParams";
|
||||||
import { AccessLog, AccessLogItem } from './interface';
|
import { AccessLog, AccessLogItem } from "./interface";
|
||||||
import { Injectable, Inject } from "@angular/core";
|
import { Injectable, Inject } from "@angular/core";
|
||||||
import 'rxjs/add/observable/of';
|
import "rxjs/add/observable/of";
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import { SERVICE_CONFIG, IServiceConfig } from "../service.config";
|
||||||
import { Http, URLSearchParams } from '@angular/http';
|
import { Http } from "@angular/http";
|
||||||
import { buildHttpRequestOptions, HTTP_GET_OPTIONS } from '../utils';
|
import { buildHttpRequestOptions, HTTP_GET_OPTIONS } from "../utils";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define service methods to handle the access log related things.
|
* Define service methods to handle the access log related things.
|
||||||
@ -28,7 +28,10 @@ export abstract class AccessLogService {
|
|||||||
*
|
*
|
||||||
* @memberOf AccessLogService
|
* @memberOf AccessLogService
|
||||||
*/
|
*/
|
||||||
abstract getAuditLogs(projectId: number | string, queryParams?: RequestQueryParams): Observable<AccessLog> | Promise<AccessLog> | AccessLog;
|
abstract getAuditLogs(
|
||||||
|
projectId: number | string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<AccessLog> | Promise<AccessLog> | AccessLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the recent logs.
|
* Get the recent logs.
|
||||||
@ -39,7 +42,9 @@ export abstract class AccessLogService {
|
|||||||
*
|
*
|
||||||
* @memberOf AccessLogService
|
* @memberOf AccessLogService
|
||||||
*/
|
*/
|
||||||
abstract getRecentLogs(queryParams?: RequestQueryParams): Observable<AccessLog> | Promise<AccessLog> | AccessLog;
|
abstract getRecentLogs(
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<AccessLog> | Promise<AccessLog> | AccessLog;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,21 +58,34 @@ export abstract class AccessLogService {
|
|||||||
export class AccessLogDefaultService extends AccessLogService {
|
export class AccessLogDefaultService extends AccessLogService {
|
||||||
constructor(
|
constructor(
|
||||||
private http: Http,
|
private http: Http,
|
||||||
@Inject(SERVICE_CONFIG) private config: IServiceConfig) {
|
@Inject(SERVICE_CONFIG) private config: IServiceConfig
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public getAuditLogs(projectId: number | string, queryParams?: RequestQueryParams): Observable<AccessLog> | Promise<AccessLog> | AccessLog {
|
public getAuditLogs(
|
||||||
return Observable.of({});
|
projectId: number | string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<AccessLog> | Promise<AccessLog> | AccessLog {
|
||||||
|
return Observable.of({} as AccessLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRecentLogs(queryParams?: RequestQueryParams): Observable<AccessLog> | Promise<AccessLog> | AccessLog {
|
public getRecentLogs(
|
||||||
let url: string = this.config.logBaseEndpoint ? this.config.logBaseEndpoint : "";
|
queryParams?: RequestQueryParams
|
||||||
if (url === '') {
|
): Observable<AccessLog> | Promise<AccessLog> | AccessLog {
|
||||||
url = '/api/logs';
|
let url: string = this.config.logBaseEndpoint
|
||||||
|
? this.config.logBaseEndpoint
|
||||||
|
: "";
|
||||||
|
if (url === "") {
|
||||||
|
url = "/api/logs";
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.http.get(url, queryParams ? buildHttpRequestOptions(queryParams) : HTTP_GET_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.get(
|
||||||
|
url,
|
||||||
|
queryParams ? buildHttpRequestOptions(queryParams) : HTTP_GET_OPTIONS
|
||||||
|
)
|
||||||
|
.toPromise()
|
||||||
.then(response => {
|
.then(response => {
|
||||||
let result: AccessLog = {
|
let result: AccessLog = {
|
||||||
metadata: {
|
metadata: {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
import { Injectable, Inject } from "@angular/core";
|
import { Injectable, Inject } from "@angular/core";
|
||||||
import 'rxjs/add/observable/of';
|
import { Http } from "@angular/http";
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import { Observable } from "rxjs/Observable";
|
||||||
import { Http } from '@angular/http';
|
import "rxjs/add/observable/of";
|
||||||
import { HTTP_JSON_OPTIONS, HTTP_GET_OPTIONS } from '../utils';
|
|
||||||
import { Configuration } from '../config/config';
|
|
||||||
|
|
||||||
|
import { SERVICE_CONFIG, IServiceConfig } from "../service.config";
|
||||||
|
import { HTTP_JSON_OPTIONS, HTTP_GET_OPTIONS } from "../utils";
|
||||||
|
import { Configuration } from "../config/config";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service used to get and save registry-related configurations.
|
* Service used to get and save registry-related configurations.
|
||||||
@ -15,7 +15,6 @@ import { Configuration } from '../config/config';
|
|||||||
* @class ConfigurationService
|
* @class ConfigurationService
|
||||||
*/
|
*/
|
||||||
export abstract class ConfigurationService {
|
export abstract class ConfigurationService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get configurations.
|
* Get configurations.
|
||||||
*
|
*
|
||||||
@ -24,7 +23,10 @@ export abstract class ConfigurationService {
|
|||||||
*
|
*
|
||||||
* @memberOf ConfigurationService
|
* @memberOf ConfigurationService
|
||||||
*/
|
*/
|
||||||
abstract getConfigurations(): Observable<Configuration> | Promise<Configuration> | Configuration;
|
abstract getConfigurations():
|
||||||
|
| Observable<Configuration>
|
||||||
|
| Promise<Configuration>
|
||||||
|
| Configuration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save configurations.
|
* Save configurations.
|
||||||
@ -34,7 +36,9 @@ export abstract class ConfigurationService {
|
|||||||
*
|
*
|
||||||
* @memberOf ConfigurationService
|
* @memberOf ConfigurationService
|
||||||
*/
|
*/
|
||||||
abstract saveConfigurations(changedConfigs: any | { [key: string]: any | any[] }): Observable<any> | Promise<any> | any;
|
abstract saveConfigurations(
|
||||||
|
changedConfigs: any | { [key: string]: any | any[] }
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -43,25 +47,36 @@ export class ConfigurationDefaultService extends ConfigurationService {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private http: Http,
|
private http: Http,
|
||||||
@Inject(SERVICE_CONFIG) private config: IServiceConfig) {
|
@Inject(SERVICE_CONFIG) private config: IServiceConfig
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this._baseUrl = this.config && this.config.configurationEndpoint ?
|
this._baseUrl =
|
||||||
this.config.configurationEndpoint : "/api/configurations";
|
this.config && this.config.configurationEndpoint
|
||||||
|
? this.config.configurationEndpoint
|
||||||
|
: "/api/configurations";
|
||||||
}
|
}
|
||||||
|
|
||||||
getConfigurations(): Observable<Configuration> | Promise<Configuration> | Configuration {
|
getConfigurations():
|
||||||
return this.http.get(this._baseUrl, HTTP_GET_OPTIONS).toPromise()
|
| Observable<Configuration>
|
||||||
|
| Promise<Configuration>
|
||||||
|
| Configuration {
|
||||||
|
return this.http
|
||||||
|
.get(this._baseUrl, HTTP_GET_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response.json() as Configuration)
|
.then(response => response.json() as Configuration)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
saveConfigurations(changedConfigs: any | { [key: string]: any | any[] }): Observable<any> | Promise<any> | any {
|
saveConfigurations(
|
||||||
|
changedConfigs: any | { [key: string]: any | any[] }
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!changedConfigs) {
|
if (!changedConfigs) {
|
||||||
return Promise.reject("Bad argument!");
|
return Promise.reject("Bad argument!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.http.put(this._baseUrl, JSON.stringify(changedConfigs), HTTP_JSON_OPTIONS)
|
return this.http
|
||||||
|
.put(this._baseUrl, JSON.stringify(changedConfigs), HTTP_JSON_OPTIONS)
|
||||||
.toPromise()
|
.toPromise()
|
||||||
.then(() => {})
|
.then(() => {})
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { TestBed, inject } from '@angular/core/testing';
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
import { SharedModule } from '../shared/shared.module';
|
import { SharedModule } from '../shared/shared.module';
|
||||||
import { EndpointService, EndpointDefaultService } from './endpoint.service';
|
|
||||||
import { IServiceConfig, SERVICE_CONFIG } from '../service.config';
|
import { IServiceConfig, SERVICE_CONFIG } from '../service.config';
|
||||||
|
import { EndpointService, EndpointDefaultService } from './endpoint.service';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
describe('EndpointService', () => {
|
describe('EndpointService', () => {
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
import { RequestQueryParams } from './RequestQueryParams';
|
|
||||||
import { Endpoint, ReplicationRule } from './interface';
|
|
||||||
import { Injectable, Inject } from "@angular/core";
|
import { Injectable, Inject } from "@angular/core";
|
||||||
import { Http } from '@angular/http';
|
import { Http } from "@angular/http";
|
||||||
import 'rxjs/add/observable/of';
|
import { Observable } from "rxjs/Observable";
|
||||||
|
import "rxjs/add/observable/of";
|
||||||
|
|
||||||
import { IServiceConfig, SERVICE_CONFIG } from '../service.config';
|
import { IServiceConfig, SERVICE_CONFIG } from "../service.config";
|
||||||
|
import {
|
||||||
import {buildHttpRequestOptions, HTTP_JSON_OPTIONS, HTTP_GET_OPTIONS} from '../utils';
|
buildHttpRequestOptions,
|
||||||
|
HTTP_JSON_OPTIONS,
|
||||||
|
HTTP_GET_OPTIONS
|
||||||
|
} from "../utils";
|
||||||
|
import { RequestQueryParams } from "./RequestQueryParams";
|
||||||
|
import { Endpoint, ReplicationRule } from "./interface";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define the service methods to handle the endpoint related things.
|
* Define the service methods to handle the endpoint related things.
|
||||||
@ -28,7 +31,10 @@ export abstract class EndpointService {
|
|||||||
*
|
*
|
||||||
* @memberOf EndpointService
|
* @memberOf EndpointService
|
||||||
*/
|
*/
|
||||||
abstract getEndpoints(endpointName?: string, queryParams?: RequestQueryParams): Observable<Endpoint[]> | Promise<Endpoint[]> | Endpoint[];
|
abstract getEndpoints(
|
||||||
|
endpointName?: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<Endpoint[]> | Promise<Endpoint[]> | Endpoint[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the specified endpoint.
|
* Get the specified endpoint.
|
||||||
@ -39,7 +45,9 @@ export abstract class EndpointService {
|
|||||||
*
|
*
|
||||||
* @memberOf EndpointService
|
* @memberOf EndpointService
|
||||||
*/
|
*/
|
||||||
abstract getEndpoint(endpointId: number | string): Observable<Endpoint> | Promise<Endpoint> | Endpoint;
|
abstract getEndpoint(
|
||||||
|
endpointId: number | string
|
||||||
|
): Observable<Endpoint> | Promise<Endpoint> | Endpoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new endpoint.
|
* Create new endpoint.
|
||||||
@ -50,7 +58,9 @@ export abstract class EndpointService {
|
|||||||
*
|
*
|
||||||
* @memberOf EndpointService
|
* @memberOf EndpointService
|
||||||
*/
|
*/
|
||||||
abstract createEndpoint(endpoint: Endpoint): Observable<any> | Promise<any> | any;
|
abstract createEndpoint(
|
||||||
|
endpoint: Endpoint
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the specified endpoint.
|
* Update the specified endpoint.
|
||||||
@ -62,7 +72,10 @@ export abstract class EndpointService {
|
|||||||
*
|
*
|
||||||
* @memberOf EndpointService
|
* @memberOf EndpointService
|
||||||
*/
|
*/
|
||||||
abstract updateEndpoint(endpointId: number | string, endpoint: Endpoint): Observable<any> | Promise<any> | any;
|
abstract updateEndpoint(
|
||||||
|
endpointId: number | string,
|
||||||
|
endpoint: Endpoint
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the specified endpoint.
|
* Delete the specified endpoint.
|
||||||
@ -73,7 +86,9 @@ export abstract class EndpointService {
|
|||||||
*
|
*
|
||||||
* @memberOf EndpointService
|
* @memberOf EndpointService
|
||||||
*/
|
*/
|
||||||
abstract deleteEndpoint(endpointId: number | string): Observable<any> | Promise<any> | any;
|
abstract deleteEndpoint(
|
||||||
|
endpointId: number | string
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ping the specified endpoint.
|
* Ping the specified endpoint.
|
||||||
@ -84,7 +99,9 @@ export abstract class EndpointService {
|
|||||||
*
|
*
|
||||||
* @memberOf EndpointService
|
* @memberOf EndpointService
|
||||||
*/
|
*/
|
||||||
abstract pingEndpoint(endpoint: Endpoint): Observable<any> | Promise<any> | any;
|
abstract pingEndpoint(
|
||||||
|
endpoint: Endpoint
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check endpoint whether in used with specific replication rule.
|
* Check endpoint whether in used with specific replication rule.
|
||||||
@ -93,7 +110,9 @@ export abstract class EndpointService {
|
|||||||
* @param {{number | string}} endpointId
|
* @param {{number | string}} endpointId
|
||||||
* @returns {{Observable<any> | any}}
|
* @returns {{Observable<any> | any}}
|
||||||
*/
|
*/
|
||||||
abstract getEndpointWithReplicationRules(endpointId: number | string): Observable<any> | Promise<any> | any;
|
abstract getEndpointWithReplicationRules(
|
||||||
|
endpointId: number | string
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,22 +124,27 @@ export abstract class EndpointService {
|
|||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class EndpointDefaultService extends EndpointService {
|
export class EndpointDefaultService extends EndpointService {
|
||||||
|
|
||||||
_endpointUrl: string;
|
_endpointUrl: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(SERVICE_CONFIG) config: IServiceConfig,
|
@Inject(SERVICE_CONFIG) config: IServiceConfig,
|
||||||
private http: Http){
|
private http: Http
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
this._endpointUrl = config.targetBaseEndpoint ? config.targetBaseEndpoint : '/api/targets';
|
this._endpointUrl = config.targetBaseEndpoint
|
||||||
|
? config.targetBaseEndpoint
|
||||||
|
: "/api/targets";
|
||||||
}
|
}
|
||||||
|
|
||||||
public getEndpoints(endpointName?: string, queryParams?: RequestQueryParams): Observable<Endpoint[]> | Promise<Endpoint[]> | Endpoint[] {
|
public getEndpoints(
|
||||||
|
endpointName?: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<Endpoint[]> | Promise<Endpoint[]> | Endpoint[] {
|
||||||
if (!queryParams) {
|
if (!queryParams) {
|
||||||
queryParams = new RequestQueryParams();
|
queryParams = new RequestQueryParams();
|
||||||
}
|
}
|
||||||
if (endpointName) {
|
if (endpointName) {
|
||||||
queryParams.set('name', endpointName);
|
queryParams.set("name", endpointName);
|
||||||
}
|
}
|
||||||
let requestUrl: string = `${this._endpointUrl}`;
|
let requestUrl: string = `${this._endpointUrl}`;
|
||||||
return this.http
|
return this.http
|
||||||
@ -130,9 +154,11 @@ export class EndpointDefaultService extends EndpointService {
|
|||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getEndpoint(endpointId: number | string): Observable<Endpoint> | Promise<Endpoint> | Endpoint {
|
public getEndpoint(
|
||||||
|
endpointId: number | string
|
||||||
|
): Observable<Endpoint> | Promise<Endpoint> | Endpoint {
|
||||||
if (!endpointId || endpointId <= 0) {
|
if (!endpointId || endpointId <= 0) {
|
||||||
return Promise.reject('Bad request argument.');
|
return Promise.reject("Bad request argument.");
|
||||||
}
|
}
|
||||||
let requestUrl: string = `${this._endpointUrl}/${endpointId}`;
|
let requestUrl: string = `${this._endpointUrl}/${endpointId}`;
|
||||||
return this.http
|
return this.http
|
||||||
@ -142,9 +168,11 @@ export class EndpointDefaultService extends EndpointService {
|
|||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public createEndpoint(endpoint: Endpoint): Observable<any> | Promise<any> | any {
|
public createEndpoint(
|
||||||
|
endpoint: Endpoint
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!endpoint) {
|
if (!endpoint) {
|
||||||
return Promise.reject('Invalid endpoint.');
|
return Promise.reject("Invalid endpoint.");
|
||||||
}
|
}
|
||||||
let requestUrl: string = `${this._endpointUrl}`;
|
let requestUrl: string = `${this._endpointUrl}`;
|
||||||
return this.http
|
return this.http
|
||||||
@ -154,12 +182,15 @@ export class EndpointDefaultService extends EndpointService {
|
|||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateEndpoint(endpointId: number | string, endpoint: Endpoint): Observable<any> | Promise<any> | any {
|
public updateEndpoint(
|
||||||
|
endpointId: number | string,
|
||||||
|
endpoint: Endpoint
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!endpointId || endpointId <= 0) {
|
if (!endpointId || endpointId <= 0) {
|
||||||
return Promise.reject('Bad request argument.');
|
return Promise.reject("Bad request argument.");
|
||||||
}
|
}
|
||||||
if (!endpoint) {
|
if (!endpoint) {
|
||||||
return Promise.reject('Invalid endpoint.');
|
return Promise.reject("Invalid endpoint.");
|
||||||
}
|
}
|
||||||
let requestUrl: string = `${this._endpointUrl}/${endpointId}`;
|
let requestUrl: string = `${this._endpointUrl}/${endpointId}`;
|
||||||
return this.http
|
return this.http
|
||||||
@ -169,9 +200,11 @@ export class EndpointDefaultService extends EndpointService {
|
|||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteEndpoint(endpointId: number | string): Observable<any> | Promise<any> | any {
|
public deleteEndpoint(
|
||||||
|
endpointId: number | string
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!endpointId || endpointId <= 0) {
|
if (!endpointId || endpointId <= 0) {
|
||||||
return Promise.reject('Bad request argument.');
|
return Promise.reject("Bad request argument.");
|
||||||
}
|
}
|
||||||
let requestUrl: string = `${this._endpointUrl}/${endpointId}`;
|
let requestUrl: string = `${this._endpointUrl}/${endpointId}`;
|
||||||
return this.http
|
return this.http
|
||||||
@ -181,9 +214,11 @@ export class EndpointDefaultService extends EndpointService {
|
|||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public pingEndpoint(endpoint: Endpoint): Observable<any> | Promise<any> | any {
|
public pingEndpoint(
|
||||||
|
endpoint: Endpoint
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!endpoint) {
|
if (!endpoint) {
|
||||||
return Promise.reject('Invalid endpoint.');
|
return Promise.reject("Invalid endpoint.");
|
||||||
}
|
}
|
||||||
let requestUrl: string = `${this._endpointUrl}/ping`;
|
let requestUrl: string = `${this._endpointUrl}/ping`;
|
||||||
return this.http
|
return this.http
|
||||||
@ -193,9 +228,11 @@ export class EndpointDefaultService extends EndpointService {
|
|||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getEndpointWithReplicationRules(endpointId: number | string): Observable<any> | Promise<any> | any {
|
public getEndpointWithReplicationRules(
|
||||||
|
endpointId: number | string
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!endpointId || endpointId <= 0) {
|
if (!endpointId || endpointId <= 0) {
|
||||||
return Promise.reject('Bad request argument.');
|
return Promise.reject("Bad request argument.");
|
||||||
}
|
}
|
||||||
let requestUrl: string = `${this._endpointUrl}/${endpointId}/policies`;
|
let requestUrl: string = `${this._endpointUrl}/${endpointId}/policies`;
|
||||||
return this.http
|
return this.http
|
||||||
|
@ -20,7 +20,7 @@ export interface Base {
|
|||||||
* @extends {Base}
|
* @extends {Base}
|
||||||
*/
|
*/
|
||||||
export interface RepositoryItem extends Base {
|
export interface RepositoryItem extends Base {
|
||||||
[key: string]: any | any[]
|
[key: string]: any | any[];
|
||||||
name: string;
|
name: string;
|
||||||
tags_count: number;
|
tags_count: number;
|
||||||
owner_id?: number;
|
owner_id?: number;
|
||||||
@ -112,10 +112,12 @@ export class Filter {
|
|||||||
|
|
||||||
export class Trigger {
|
export class Trigger {
|
||||||
kind: string;
|
kind: string;
|
||||||
schedule_param: any | {
|
schedule_param:
|
||||||
|
| any
|
||||||
|
| {
|
||||||
[key: string]: any | any[];
|
[key: string]: any | any[];
|
||||||
};
|
};
|
||||||
constructor(kind: string, param: any | { [key: string]: any | any[]; }) {
|
constructor(kind: string, param: any | { [key: string]: any | any[] }) {
|
||||||
this.kind = kind;
|
this.kind = kind;
|
||||||
this.schedule_param = param;
|
this.schedule_param = param;
|
||||||
}
|
}
|
||||||
@ -227,7 +229,12 @@ export interface ClairDBStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum VulnerabilitySeverity {
|
export enum VulnerabilitySeverity {
|
||||||
_SEVERITY, NONE, UNKNOWN, LOW, MEDIUM, HIGH
|
_SEVERITY,
|
||||||
|
NONE,
|
||||||
|
UNKNOWN,
|
||||||
|
LOW,
|
||||||
|
MEDIUM,
|
||||||
|
HIGH
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VulnerabilityBase {
|
export interface VulnerabilityBase {
|
||||||
@ -288,4 +295,4 @@ export interface ScrollPosition {
|
|||||||
sH: number;
|
sH: number;
|
||||||
sT: number;
|
sT: number;
|
||||||
cH: number;
|
cH: number;
|
||||||
};
|
}
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from "rxjs/Observable";
|
||||||
import { RequestQueryParams } from './RequestQueryParams';
|
|
||||||
import { ReplicationJob, ReplicationRule } from './interface';
|
|
||||||
import { Injectable, Inject } from "@angular/core";
|
import { Injectable, Inject } from "@angular/core";
|
||||||
import 'rxjs/add/observable/of';
|
import "rxjs/add/observable/of";
|
||||||
import { Http, RequestOptions } from '@angular/http';
|
import { Http } from "@angular/http";
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import { SERVICE_CONFIG, IServiceConfig } from "../service.config";
|
||||||
import { buildHttpRequestOptions, HTTP_JSON_OPTIONS, HTTP_GET_OPTIONS } from '../utils';
|
import { HTTP_GET_OPTIONS } from "../utils";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define the service methods to handle the job log related things.
|
* Define the service methods to handle the job log related things.
|
||||||
@ -15,7 +13,6 @@ import { buildHttpRequestOptions, HTTP_JSON_OPTIONS, HTTP_GET_OPTIONS } from '..
|
|||||||
* @class JobLogService
|
* @class JobLogService
|
||||||
*/
|
*/
|
||||||
export abstract class JobLogService {
|
export abstract class JobLogService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the log of the specified job
|
* Get the log of the specified job
|
||||||
*
|
*
|
||||||
@ -25,7 +22,10 @@ export abstract class JobLogService {
|
|||||||
* @returns {(Observable<string> | Promise<string> | string)}
|
* @returns {(Observable<string> | Promise<string> | string)}
|
||||||
* @memberof JobLogService
|
* @memberof JobLogService
|
||||||
*/
|
*/
|
||||||
abstract getJobLog(jobType: string, jobId: number | string): Observable<string> | Promise<string> | string;
|
abstract getJobLog(
|
||||||
|
jobType: string,
|
||||||
|
jobId: number | string
|
||||||
|
): Observable<string> | Promise<string> | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,14 +46,19 @@ export class JobLogDefaultService extends JobLogService {
|
|||||||
@Inject(SERVICE_CONFIG) config: IServiceConfig
|
@Inject(SERVICE_CONFIG) config: IServiceConfig
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._replicationJobBaseUrl = config.replicationJobEndpoint ?
|
this._replicationJobBaseUrl = config.replicationJobEndpoint
|
||||||
config.replicationJobEndpoint : '/api/jobs/replication';
|
? config.replicationJobEndpoint
|
||||||
this._scanningJobBaseUrl = config.scanJobEndpoint ? config.scanJobEndpoint : "/api/jobs/scan";
|
: "/api/jobs/replication";
|
||||||
|
this._scanningJobBaseUrl = config.scanJobEndpoint
|
||||||
|
? config.scanJobEndpoint
|
||||||
|
: "/api/jobs/scan";
|
||||||
this._supportedJobTypes = ["replication", "scan"];
|
this._supportedJobTypes = ["replication", "scan"];
|
||||||
}
|
}
|
||||||
|
|
||||||
_getJobLog(logUrl: string): Observable<string> | Promise<string> | string {
|
_getJobLog(logUrl: string): Observable<string> | Promise<string> | string {
|
||||||
return this.http.get(logUrl, HTTP_GET_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.get(logUrl, HTTP_GET_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
@ -66,12 +71,15 @@ export class JobLogDefaultService extends JobLogService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getJobLog(jobType: string, jobId: number | string): Observable<string> | Promise<string> | string {
|
public getJobLog(
|
||||||
|
jobType: string,
|
||||||
|
jobId: number | string
|
||||||
|
): Observable<string> | Promise<string> | string {
|
||||||
if (!this._isSupportedJobType(jobType)) {
|
if (!this._isSupportedJobType(jobType)) {
|
||||||
return Promise.reject("Unsupport job type: " + jobType);
|
return Promise.reject("Unsupport job type: " + jobType);
|
||||||
}
|
}
|
||||||
if (!jobId || jobId <= 0) {
|
if (!jobId || jobId <= 0) {
|
||||||
return Promise.reject('Bad argument');
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
let logUrl: string = `${this._replicationJobBaseUrl}/${jobId}/log`;
|
let logUrl: string = `${this._replicationJobBaseUrl}/${jobId}/log`;
|
||||||
|
@ -7,17 +7,34 @@ import {buildHttpRequestOptions, HTTP_JSON_OPTIONS} from "../utils";
|
|||||||
import { RequestQueryParams } from "./RequestQueryParams";
|
import { RequestQueryParams } from "./RequestQueryParams";
|
||||||
|
|
||||||
export abstract class LabelService {
|
export abstract class LabelService {
|
||||||
abstract getGLabels(name?: string, queryParams?: RequestQueryParams): Observable<Label[]> | Promise<Label[]>;
|
abstract getGLabels(
|
||||||
|
name?: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<Label[]> | Promise<Label[]>;
|
||||||
|
|
||||||
abstract getPLabels(projectId: number, name?: string, queryParams?: RequestQueryParams): Observable<Label[]> | Promise<Label[]>;
|
abstract getPLabels(
|
||||||
|
projectId: number,
|
||||||
|
name?: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<Label[]> | Promise<Label[]>;
|
||||||
|
|
||||||
abstract getLabels(scope: string, projectId: number, name?: string, queryParams?: RequestQueryParams): Observable<Label[]> | Promise<Label[]>;
|
abstract getLabels(
|
||||||
|
scope: string,
|
||||||
|
projectId: number,
|
||||||
|
name?: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<Label[]> | Promise<Label[]>;
|
||||||
|
|
||||||
abstract createLabel(label: Label): Observable<Label> | Promise<Label> | Label;
|
abstract createLabel(
|
||||||
|
label: Label
|
||||||
|
): Observable<Label> | Promise<Label> | Label;
|
||||||
|
|
||||||
abstract getLabel(id: number): Observable<Label> | Promise<Label> | Label;
|
abstract getLabel(id: number): Observable<Label> | Promise<Label> | Label;
|
||||||
|
|
||||||
abstract updateLabel(id: number, param: Label): Observable<any> | Promise<any> | any;
|
abstract updateLabel(
|
||||||
|
id: number,
|
||||||
|
param: Label
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
abstract deleteLabel(id: number): Observable<any> | Promise<any> | any;
|
abstract deleteLabel(id: number): Observable<any> | Promise<any> | any;
|
||||||
}
|
}
|
||||||
@ -31,94 +48,122 @@ export class LabelDefaultService extends LabelService {
|
|||||||
private http: Http
|
private http: Http
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._labelUrl = config.labelEndpoint ? config.labelEndpoint : "/api/labels";
|
this._labelUrl = config.labelEndpoint
|
||||||
|
? config.labelEndpoint
|
||||||
|
: "/api/labels";
|
||||||
}
|
}
|
||||||
|
|
||||||
getLabels(scope: string, projectId: number, name?: string, queryParams?: RequestQueryParams): Observable<Label[]> | Promise<Label[]> {
|
getLabels(
|
||||||
|
scope: string,
|
||||||
|
projectId: number,
|
||||||
|
name?: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<Label[]> | Promise<Label[]> {
|
||||||
if (!queryParams) {
|
if (!queryParams) {
|
||||||
queryParams = new RequestQueryParams();
|
queryParams = new RequestQueryParams();
|
||||||
}
|
}
|
||||||
if (scope) {
|
if (scope) {
|
||||||
queryParams.set('scope', scope);
|
queryParams.set("scope", scope);
|
||||||
}
|
}
|
||||||
if (projectId) {
|
if (projectId) {
|
||||||
queryParams.set('project_id', '' + projectId);
|
queryParams.set("project_id", "" + projectId);
|
||||||
}
|
}
|
||||||
if (name) {
|
if (name) {
|
||||||
queryParams.set('name', '' + name);
|
queryParams.set("name", "" + name);
|
||||||
}
|
}
|
||||||
return this.http.get(this._labelUrl, buildHttpRequestOptions(queryParams)).toPromise()
|
return this.http
|
||||||
|
.get(this._labelUrl, buildHttpRequestOptions(queryParams))
|
||||||
|
.toPromise()
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
getGLabels(name?: string, queryParams?: RequestQueryParams): Observable<Label[]> | Promise<Label[]> {
|
getGLabels(
|
||||||
|
name?: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<Label[]> | Promise<Label[]> {
|
||||||
if (!queryParams) {
|
if (!queryParams) {
|
||||||
queryParams = new RequestQueryParams();
|
queryParams = new RequestQueryParams();
|
||||||
}
|
}
|
||||||
queryParams.set('scope', 'g');
|
queryParams.set("scope", "g");
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
queryParams.set('name', '' + name);
|
queryParams.set("name", "" + name);
|
||||||
}
|
}
|
||||||
return this.http.get(this._labelUrl, buildHttpRequestOptions(queryParams)).toPromise()
|
return this.http
|
||||||
|
.get(this._labelUrl, buildHttpRequestOptions(queryParams))
|
||||||
|
.toPromise()
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
getPLabels(projectId: number, name?: string, queryParams?: RequestQueryParams): Observable<Label[]> | Promise<Label[]> {
|
getPLabels(
|
||||||
|
projectId: number,
|
||||||
|
name?: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<Label[]> | Promise<Label[]> {
|
||||||
if (!queryParams) {
|
if (!queryParams) {
|
||||||
queryParams = new RequestQueryParams();
|
queryParams = new RequestQueryParams();
|
||||||
}
|
}
|
||||||
queryParams.set('scope', 'p');
|
queryParams.set("scope", "p");
|
||||||
if (projectId) {
|
if (projectId) {
|
||||||
queryParams.set('project_id', '' + projectId);
|
queryParams.set("project_id", "" + projectId);
|
||||||
}
|
}
|
||||||
if (name) {
|
if (name) {
|
||||||
queryParams.set('name', '' + name);
|
queryParams.set("name", "" + name);
|
||||||
}
|
}
|
||||||
return this.http.get(this._labelUrl, buildHttpRequestOptions(queryParams)).toPromise()
|
return this.http
|
||||||
|
.get(this._labelUrl, buildHttpRequestOptions(queryParams))
|
||||||
|
.toPromise()
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
createLabel(label: Label): Observable<any> | Promise<any> | any {
|
createLabel(label: Label): Observable<any> | Promise<any> | any {
|
||||||
if (!label) {
|
if (!label) {
|
||||||
return Promise.reject('Invalid label.');
|
return Promise.reject("Invalid label.");
|
||||||
}
|
}
|
||||||
return this.http.post(this._labelUrl, JSON.stringify(label), HTTP_JSON_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.post(this._labelUrl, JSON.stringify(label), HTTP_JSON_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response.status)
|
.then(response => response.status)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
getLabel(id: number): Observable<Label> | Promise<Label> | Label {
|
getLabel(id: number): Observable<Label> | Promise<Label> | Label {
|
||||||
if (!id || id <= 0) {
|
if (!id || id <= 0) {
|
||||||
return Promise.reject('Bad request argument.');
|
return Promise.reject("Bad request argument.");
|
||||||
}
|
}
|
||||||
let reqUrl = `${this._labelUrl}/${id}`
|
let reqUrl = `${this._labelUrl}/${id}`;
|
||||||
return this.http.get(reqUrl).toPromise()
|
return this.http
|
||||||
|
.get(reqUrl)
|
||||||
|
.toPromise()
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLabel(id: number, label: Label): Observable<any> | Promise<any> | any {
|
updateLabel(id: number, label: Label): Observable<any> | Promise<any> | any {
|
||||||
if (!id || id <= 0) {
|
if (!id || id <= 0) {
|
||||||
return Promise.reject('Bad request argument.');
|
return Promise.reject("Bad request argument.");
|
||||||
}
|
}
|
||||||
if (!label) {
|
if (!label) {
|
||||||
return Promise.reject('Invalid endpoint.');
|
return Promise.reject("Invalid endpoint.");
|
||||||
}
|
}
|
||||||
let reqUrl = `${this._labelUrl}/${id}`
|
let reqUrl = `${this._labelUrl}/${id}`;
|
||||||
return this.http.put(reqUrl, JSON.stringify(label), HTTP_JSON_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.put(reqUrl, JSON.stringify(label), HTTP_JSON_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response.status)
|
.then(response => response.status)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
deleteLabel(id: number): Observable<any> | Promise<any> | any {
|
deleteLabel(id: number): Observable<any> | Promise<any> | any {
|
||||||
if (!id || id <= 0) {
|
if (!id || id <= 0) {
|
||||||
return Promise.reject('Bad request argument.');
|
return Promise.reject("Bad request argument.");
|
||||||
}
|
}
|
||||||
let reqUrl = `${this._labelUrl}/${id}`
|
let reqUrl = `${this._labelUrl}/${id}`;
|
||||||
return this.http.delete(reqUrl).toPromise()
|
return this.http
|
||||||
|
.delete(reqUrl)
|
||||||
|
.toPromise()
|
||||||
.then(response => response.status)
|
.then(response => response.status)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from "rxjs/Observable";
|
||||||
import { Injectable, Inject } from '@angular/core';
|
import { Injectable, Inject } from "@angular/core";
|
||||||
import { Http, Headers, RequestOptions } from '@angular/http';
|
import { Http } from "@angular/http";
|
||||||
import 'rxjs/add/observable/of';
|
import "rxjs/add/observable/of";
|
||||||
|
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import { SERVICE_CONFIG, IServiceConfig } from "../service.config";
|
||||||
import { Project } from '../project-policy-config/project';
|
import { Project } from "../project-policy-config/project";
|
||||||
import { ProjectPolicy } from '../project-policy-config/project-policy-config.component';
|
import { ProjectPolicy } from "../project-policy-config/project-policy-config.component";
|
||||||
import {HTTP_JSON_OPTIONS, HTTP_GET_OPTIONS, buildHttpRequestOptions} from "../utils";
|
import {
|
||||||
|
HTTP_JSON_OPTIONS,
|
||||||
|
HTTP_GET_OPTIONS,
|
||||||
|
buildHttpRequestOptions
|
||||||
|
} from "../utils";
|
||||||
import { RequestQueryParams } from "./RequestQueryParams";
|
import { RequestQueryParams } from "./RequestQueryParams";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,7 +30,9 @@ export abstract class ProjectService {
|
|||||||
*
|
*
|
||||||
* @memberOf ProjectService
|
* @memberOf ProjectService
|
||||||
*/
|
*/
|
||||||
abstract getProject(projectId: number | string): Observable<Project> | Promise<Project> | Project;
|
abstract getProject(
|
||||||
|
projectId: number | string
|
||||||
|
): Observable<Project> | Promise<Project> | Project;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the specified project.
|
* Update the specified project.
|
||||||
@ -38,7 +44,10 @@ export abstract class ProjectService {
|
|||||||
*
|
*
|
||||||
* @memberOf EndpointService
|
* @memberOf EndpointService
|
||||||
*/
|
*/
|
||||||
abstract updateProjectPolicy(projectId: number | string, projectPolicy: ProjectPolicy): Observable<any> | Promise<any> | any;
|
abstract updateProjectPolicy(
|
||||||
|
projectId: number | string,
|
||||||
|
projectPolicy: ProjectPolicy
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all projects
|
* Get all projects
|
||||||
@ -52,7 +61,12 @@ export abstract class ProjectService {
|
|||||||
*
|
*
|
||||||
* @memberOf EndpointService
|
* @memberOf EndpointService
|
||||||
*/
|
*/
|
||||||
abstract listProjects(name: string, isPublic: number, page?: number, pageSize?: number): Observable<Project[]> | Promise<Project[]> | Project[];
|
abstract listProjects(
|
||||||
|
name: string,
|
||||||
|
isPublic: number,
|
||||||
|
page?: number,
|
||||||
|
pageSize?: number
|
||||||
|
): Observable<Project[]> | Promise<Project[]> | Project[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,7 +78,6 @@ export abstract class ProjectService {
|
|||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ProjectDefaultService extends ProjectService {
|
export class ProjectDefaultService extends ProjectService {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private http: Http,
|
private http: Http,
|
||||||
@Inject(SERVICE_CONFIG) private config: IServiceConfig
|
@Inject(SERVICE_CONFIG) private config: IServiceConfig
|
||||||
@ -72,30 +85,40 @@ export class ProjectDefaultService extends ProjectService {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public getProject(projectId: number | string): Observable<Project> | Promise<Project> | Project {
|
public getProject(
|
||||||
|
projectId: number | string
|
||||||
|
): Observable<Project> | Promise<Project> | Project {
|
||||||
if (!projectId) {
|
if (!projectId) {
|
||||||
return Promise.reject('Bad argument');
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
let baseUrl: string = this.config.projectBaseEndpoint ? this.config.projectBaseEndpoint : '/api/projects';
|
let baseUrl: string = this.config.projectBaseEndpoint
|
||||||
|
? this.config.projectBaseEndpoint
|
||||||
|
: "/api/projects";
|
||||||
return this.http
|
return this.http
|
||||||
.get(`${baseUrl}/${projectId}`, HTTP_GET_OPTIONS)
|
.get(`${baseUrl}/${projectId}`, HTTP_GET_OPTIONS)
|
||||||
.map(response => response.json())
|
.map(response => response.json())
|
||||||
.catch(error => Observable.throw(error));
|
.catch(error => Observable.throw(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public listProjects(name: string, isPublic: number, page?: number, pageSize?: number): Observable<Project[]> | Promise<Project[]> | Project[] {
|
public listProjects(
|
||||||
let baseUrl: string = this.config.projectBaseEndpoint ? this.config.projectBaseEndpoint : '/api/projects';
|
name: string,
|
||||||
|
isPublic: number,
|
||||||
|
page?: number,
|
||||||
|
pageSize?: number
|
||||||
|
): Observable<Project[]> | Promise<Project[]> | Project[] {
|
||||||
|
let baseUrl: string = this.config.projectBaseEndpoint
|
||||||
|
? this.config.projectBaseEndpoint
|
||||||
|
: "/api/projects";
|
||||||
let params = new RequestQueryParams();
|
let params = new RequestQueryParams();
|
||||||
if (page && pageSize) {
|
if (page && pageSize) {
|
||||||
params.set('page', page + '');
|
params.set("page", page + "");
|
||||||
params.set('page_size', pageSize + '');
|
params.set("page_size", pageSize + "");
|
||||||
}
|
}
|
||||||
if (name && name.trim() !== "") {
|
if (name && name.trim() !== "") {
|
||||||
params.set('name', name);
|
params.set("name", name);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (isPublic !== undefined) {
|
if (isPublic !== undefined) {
|
||||||
params.set('public', '' + isPublic);
|
params.set("public", "" + isPublic);
|
||||||
}
|
}
|
||||||
|
|
||||||
// let options = new RequestOptions({ headers: this.getHeaders, search: params });
|
// let options = new RequestOptions({ headers: this.getHeaders, search: params });
|
||||||
@ -105,19 +128,27 @@ export class ProjectDefaultService extends ProjectService {
|
|||||||
.catch(error => Observable.throw(error));
|
.catch(error => Observable.throw(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateProjectPolicy(projectId: number | string, projectPolicy: ProjectPolicy): any {
|
public updateProjectPolicy(
|
||||||
let baseUrl: string = this.config.projectBaseEndpoint ? this.config.projectBaseEndpoint : '/api/projects';
|
projectId: number | string,
|
||||||
|
projectPolicy: ProjectPolicy
|
||||||
|
): any {
|
||||||
|
let baseUrl: string = this.config.projectBaseEndpoint
|
||||||
|
? this.config.projectBaseEndpoint
|
||||||
|
: "/api/projects";
|
||||||
return this.http
|
return this.http
|
||||||
.put(`${baseUrl}/${projectId}`, {
|
.put(
|
||||||
'metadata': {
|
`${baseUrl}/${projectId}`,
|
||||||
'public': projectPolicy.Public ? 'true' : 'false',
|
{
|
||||||
'enable_content_trust': projectPolicy.ContentTrust ? 'true' : 'false',
|
metadata: {
|
||||||
'prevent_vul': projectPolicy.PreventVulImg ? 'true' : 'false',
|
public: projectPolicy.Public ? "true" : "false",
|
||||||
'severity': projectPolicy.PreventVulImgSeverity,
|
enable_content_trust: projectPolicy.ContentTrust ? "true" : "false",
|
||||||
'auto_scan': projectPolicy.ScanImgOnPush ? 'true' : 'false'
|
prevent_vul: projectPolicy.PreventVulImg ? "true" : "false",
|
||||||
|
severity: projectPolicy.PreventVulImgSeverity,
|
||||||
|
auto_scan: projectPolicy.ScanImgOnPush ? "true" : "false"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
HTTP_JSON_OPTIONS)
|
HTTP_JSON_OPTIONS
|
||||||
|
)
|
||||||
.map(response => response.status)
|
.map(response => response.status)
|
||||||
.catch(error => Observable.throw(error));
|
.catch(error => Observable.throw(error));
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,20 @@
|
|||||||
import { Observable } from 'rxjs/Observable';
|
import { Http } from "@angular/http";
|
||||||
import { RequestQueryParams } from './RequestQueryParams';
|
|
||||||
import {ReplicationJob, ReplicationRule, ReplicationJobItem} from './interface';
|
|
||||||
import { Injectable, Inject } from "@angular/core";
|
import { Injectable, Inject } from "@angular/core";
|
||||||
import 'rxjs/add/observable/of';
|
import { Observable } from "rxjs/Observable";
|
||||||
import { Http, RequestOptions } from '@angular/http';
|
import "rxjs/add/observable/of";
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
|
||||||
import { buildHttpRequestOptions, HTTP_JSON_OPTIONS, HTTP_GET_OPTIONS } from '../utils';
|
import { SERVICE_CONFIG, IServiceConfig } from "../service.config";
|
||||||
|
import {
|
||||||
|
buildHttpRequestOptions,
|
||||||
|
HTTP_JSON_OPTIONS,
|
||||||
|
HTTP_GET_OPTIONS
|
||||||
|
} from "../utils";
|
||||||
|
import {
|
||||||
|
ReplicationJob,
|
||||||
|
ReplicationRule,
|
||||||
|
ReplicationJobItem
|
||||||
|
} from "./interface";
|
||||||
|
import { RequestQueryParams } from "./RequestQueryParams";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define the service methods to handle the replication (rule and job) related things.
|
* Define the service methods to handle the replication (rule and job) related things.
|
||||||
@ -29,7 +38,14 @@ export abstract class ReplicationService {
|
|||||||
*
|
*
|
||||||
* @memberOf ReplicationService
|
* @memberOf ReplicationService
|
||||||
*/
|
*/
|
||||||
abstract getReplicationRules(projectId?: number | string, ruleName?: string, queryParams?: RequestQueryParams): Observable<ReplicationRule[]> | Promise<ReplicationRule[]> | ReplicationRule[];
|
abstract getReplicationRules(
|
||||||
|
projectId?: number | string,
|
||||||
|
ruleName?: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
):
|
||||||
|
| Observable<ReplicationRule[]>
|
||||||
|
| Promise<ReplicationRule[]>
|
||||||
|
| ReplicationRule[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the specified replication rule.
|
* Get the specified replication rule.
|
||||||
@ -40,7 +56,9 @@ export abstract class ReplicationService {
|
|||||||
*
|
*
|
||||||
* @memberOf ReplicationService
|
* @memberOf ReplicationService
|
||||||
*/
|
*/
|
||||||
abstract getReplicationRule(ruleId: number | string): Observable<ReplicationRule> | Promise<ReplicationRule> | ReplicationRule;
|
abstract getReplicationRule(
|
||||||
|
ruleId: number | string
|
||||||
|
): Observable<ReplicationRule> | Promise<ReplicationRule> | ReplicationRule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new replication rule.
|
* Create new replication rule.
|
||||||
@ -51,7 +69,9 @@ export abstract class ReplicationService {
|
|||||||
*
|
*
|
||||||
* @memberOf ReplicationService
|
* @memberOf ReplicationService
|
||||||
*/
|
*/
|
||||||
abstract createReplicationRule(replicationRule: ReplicationRule): Observable<any> | Promise<any> | any;
|
abstract createReplicationRule(
|
||||||
|
replicationRule: ReplicationRule
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the specified replication rule.
|
* Update the specified replication rule.
|
||||||
@ -62,7 +82,10 @@ export abstract class ReplicationService {
|
|||||||
*
|
*
|
||||||
* @memberOf ReplicationService
|
* @memberOf ReplicationService
|
||||||
*/
|
*/
|
||||||
abstract updateReplicationRule(id: number, rep: ReplicationRule): Observable<any> | Promise<any> | any;
|
abstract updateReplicationRule(
|
||||||
|
id: number,
|
||||||
|
rep: ReplicationRule
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the specified replication rule.
|
* Delete the specified replication rule.
|
||||||
@ -73,7 +96,9 @@ export abstract class ReplicationService {
|
|||||||
*
|
*
|
||||||
* @memberOf ReplicationService
|
* @memberOf ReplicationService
|
||||||
*/
|
*/
|
||||||
abstract deleteReplicationRule(ruleId: number | string): Observable<any> | Promise<any> | any;
|
abstract deleteReplicationRule(
|
||||||
|
ruleId: number | string
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable the specified replication rule.
|
* Enable the specified replication rule.
|
||||||
@ -84,7 +109,10 @@ export abstract class ReplicationService {
|
|||||||
*
|
*
|
||||||
* @memberOf ReplicationService
|
* @memberOf ReplicationService
|
||||||
*/
|
*/
|
||||||
abstract enableReplicationRule(ruleId: number | string, enablement: number): Observable<any> | Promise<any> | any;
|
abstract enableReplicationRule(
|
||||||
|
ruleId: number | string,
|
||||||
|
enablement: number
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable the specified replication rule.
|
* Disable the specified replication rule.
|
||||||
@ -95,10 +123,13 @@ export abstract class ReplicationService {
|
|||||||
*
|
*
|
||||||
* @memberOf ReplicationService
|
* @memberOf ReplicationService
|
||||||
*/
|
*/
|
||||||
abstract disableReplicationRule(ruleId: number | string): Observable<any> | Promise<any> | any;
|
abstract disableReplicationRule(
|
||||||
|
ruleId: number | string
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
|
abstract replicateRule(
|
||||||
abstract replicateRule(ruleId: number | string): Observable<any> | Promise<any> | any;
|
ruleId: number | string
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the jobs for the specified replication rule.
|
* Get the jobs for the specified replication rule.
|
||||||
@ -116,7 +147,10 @@ export abstract class ReplicationService {
|
|||||||
*
|
*
|
||||||
* @memberOf ReplicationService
|
* @memberOf ReplicationService
|
||||||
*/
|
*/
|
||||||
abstract getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable<ReplicationJob> | Promise<ReplicationJob> | ReplicationJob;
|
abstract getJobs(
|
||||||
|
ruleId: number | string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<ReplicationJob> | Promise<ReplicationJob> | ReplicationJob;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the log of the specified job.
|
* Get the log of the specified job.
|
||||||
@ -126,9 +160,13 @@ export abstract class ReplicationService {
|
|||||||
* @returns {(Observable<string> | Promise<string> | string)}
|
* @returns {(Observable<string> | Promise<string> | string)}
|
||||||
* @memberof ReplicationService
|
* @memberof ReplicationService
|
||||||
*/
|
*/
|
||||||
abstract getJobLog(jobId: number | string): Observable<string> | Promise<string> | string;
|
abstract getJobLog(
|
||||||
|
jobId: number | string
|
||||||
|
): Observable<string> | Promise<string> | string;
|
||||||
|
|
||||||
abstract stopJobs(jobId: number | string): Observable<string> | Promise<string> | string;
|
abstract stopJobs(
|
||||||
|
jobId: number | string
|
||||||
|
): Observable<string> | Promise<string> | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -149,122 +187,182 @@ export class ReplicationDefaultService extends ReplicationService {
|
|||||||
@Inject(SERVICE_CONFIG) config: IServiceConfig
|
@Inject(SERVICE_CONFIG) config: IServiceConfig
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._ruleBaseUrl = config.replicationRuleEndpoint ? config.replicationRuleEndpoint : '/api/policies/replication';
|
this._ruleBaseUrl = config.replicationRuleEndpoint
|
||||||
this._jobBaseUrl = config.replicationJobEndpoint ? config.replicationJobEndpoint : '/api/jobs/replication';
|
? config.replicationRuleEndpoint
|
||||||
this._replicateUrl = config.replicationBaseEndpoint ? config.replicationBaseEndpoint : '/api/replications';
|
: "/api/policies/replication";
|
||||||
|
this._jobBaseUrl = config.replicationJobEndpoint
|
||||||
|
? config.replicationJobEndpoint
|
||||||
|
: "/api/jobs/replication";
|
||||||
|
this._replicateUrl = config.replicationBaseEndpoint
|
||||||
|
? config.replicationBaseEndpoint
|
||||||
|
: "/api/replications";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private methods
|
// Private methods
|
||||||
// Check if the rule object is valid
|
// Check if the rule object is valid
|
||||||
_isValidRule(rule: ReplicationRule): boolean {
|
_isValidRule(rule: ReplicationRule): boolean {
|
||||||
return rule !== undefined && rule != null && rule.name !== undefined && rule.name.trim() !== '' && rule.targets.length !== 0;
|
return (
|
||||||
|
rule !== undefined &&
|
||||||
|
rule != null &&
|
||||||
|
rule.name !== undefined &&
|
||||||
|
rule.name.trim() !== "" &&
|
||||||
|
rule.targets.length !== 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getReplicationRules(projectId?: number | string, ruleName?: string, queryParams?: RequestQueryParams): Observable<ReplicationRule[]> | Promise<ReplicationRule[]> | ReplicationRule[] {
|
public getReplicationRules(
|
||||||
|
projectId?: number | string,
|
||||||
|
ruleName?: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
):
|
||||||
|
| Observable<ReplicationRule[]>
|
||||||
|
| Promise<ReplicationRule[]>
|
||||||
|
| ReplicationRule[] {
|
||||||
if (!queryParams) {
|
if (!queryParams) {
|
||||||
queryParams = new RequestQueryParams();
|
queryParams = new RequestQueryParams();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (projectId) {
|
if (projectId) {
|
||||||
queryParams.set('project_id', '' + projectId);
|
queryParams.set("project_id", "" + projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ruleName) {
|
if (ruleName) {
|
||||||
queryParams.set('name', ruleName);
|
queryParams.set("name", ruleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.http.get(this._ruleBaseUrl, buildHttpRequestOptions(queryParams)).toPromise()
|
return this.http
|
||||||
|
.get(this._ruleBaseUrl, buildHttpRequestOptions(queryParams))
|
||||||
|
.toPromise()
|
||||||
.then(response => response.json() as ReplicationRule[])
|
.then(response => response.json() as ReplicationRule[])
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getReplicationRule(ruleId: number | string): Observable<ReplicationRule> | Promise<ReplicationRule> | ReplicationRule {
|
public getReplicationRule(
|
||||||
|
ruleId: number | string
|
||||||
|
): Observable<ReplicationRule> | Promise<ReplicationRule> | ReplicationRule {
|
||||||
if (!ruleId) {
|
if (!ruleId) {
|
||||||
return Promise.reject("Bad argument");
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
let url: string = `${this._ruleBaseUrl}/${ruleId}`;
|
let url: string = `${this._ruleBaseUrl}/${ruleId}`;
|
||||||
return this.http.get(url, HTTP_GET_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.get(url, HTTP_GET_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response.json() as ReplicationRule)
|
.then(response => response.json() as ReplicationRule)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public createReplicationRule(replicationRule: ReplicationRule): Observable<any> | Promise<any> | any {
|
public createReplicationRule(
|
||||||
|
replicationRule: ReplicationRule
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!this._isValidRule(replicationRule)) {
|
if (!this._isValidRule(replicationRule)) {
|
||||||
return Promise.reject('Bad argument');
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.http.post(this._ruleBaseUrl, JSON.stringify(replicationRule), HTTP_JSON_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.post(
|
||||||
|
this._ruleBaseUrl,
|
||||||
|
JSON.stringify(replicationRule),
|
||||||
|
HTTP_JSON_OPTIONS
|
||||||
|
)
|
||||||
|
.toPromise()
|
||||||
.then(response => response)
|
.then(response => response)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateReplicationRule(id: number, rep: ReplicationRule): Observable<any> | Promise<any> | any {
|
public updateReplicationRule(
|
||||||
|
id: number,
|
||||||
|
rep: ReplicationRule
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!this._isValidRule(rep)) {
|
if (!this._isValidRule(rep)) {
|
||||||
return Promise.reject('Bad argument');
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = `${this._ruleBaseUrl}/${id}`;
|
let url = `${this._ruleBaseUrl}/${id}`;
|
||||||
return this.http.put(url, JSON.stringify(rep), HTTP_JSON_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.put(url, JSON.stringify(rep), HTTP_JSON_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response)
|
.then(response => response)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteReplicationRule(ruleId: number | string): Observable<any> | Promise<any> | any {
|
public deleteReplicationRule(
|
||||||
|
ruleId: number | string
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!ruleId || ruleId <= 0) {
|
if (!ruleId || ruleId <= 0) {
|
||||||
return Promise.reject('Bad argument');
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
let url: string = `${this._ruleBaseUrl}/${ruleId}`;
|
let url: string = `${this._ruleBaseUrl}/${ruleId}`;
|
||||||
return this.http.delete(url, HTTP_JSON_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.delete(url, HTTP_JSON_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response)
|
.then(response => response)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public replicateRule(ruleId: number | string): Observable<any> | Promise<any> | any {
|
public replicateRule(
|
||||||
|
ruleId: number | string
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!ruleId) {
|
if (!ruleId) {
|
||||||
return Promise.reject("Bad argument");
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
let url: string = `${this._replicateUrl}`;
|
let url: string = `${this._replicateUrl}`;
|
||||||
return this.http.post(url, {policy_id: ruleId}, HTTP_JSON_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.post(url, { policy_id: ruleId }, HTTP_JSON_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response)
|
.then(response => response)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public enableReplicationRule(ruleId: number | string, enablement: number): Observable<any> | Promise<any> | any {
|
public enableReplicationRule(
|
||||||
|
ruleId: number | string,
|
||||||
|
enablement: number
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!ruleId || ruleId <= 0) {
|
if (!ruleId || ruleId <= 0) {
|
||||||
return Promise.reject('Bad argument');
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
let url: string = `${this._ruleBaseUrl}/${ruleId}/enablement`;
|
let url: string = `${this._ruleBaseUrl}/${ruleId}/enablement`;
|
||||||
return this.http.put(url, { enabled: enablement }, HTTP_JSON_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.put(url, { enabled: enablement }, HTTP_JSON_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response)
|
.then(response => response)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public disableReplicationRule(ruleId: number | string): Observable<any> | Promise<any> | any {
|
public disableReplicationRule(
|
||||||
|
ruleId: number | string
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!ruleId || ruleId <= 0) {
|
if (!ruleId || ruleId <= 0) {
|
||||||
return Promise.reject('Bad argument');
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
let url: string = `${this._ruleBaseUrl}/${ruleId}/enablement`;
|
let url: string = `${this._ruleBaseUrl}/${ruleId}/enablement`;
|
||||||
return this.http.put(url, { enabled: 0 }, HTTP_JSON_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.put(url, { enabled: 0 }, HTTP_JSON_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response)
|
.then(response => response)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable<ReplicationJob> | Promise<ReplicationJob> | ReplicationJob {
|
public getJobs(
|
||||||
|
ruleId: number | string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<ReplicationJob> | Promise<ReplicationJob> | ReplicationJob {
|
||||||
if (!ruleId || ruleId <= 0) {
|
if (!ruleId || ruleId <= 0) {
|
||||||
return Promise.reject('Bad argument');
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!queryParams) {
|
if (!queryParams) {
|
||||||
queryParams = new RequestQueryParams();
|
queryParams = new RequestQueryParams();
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParams.set('policy_id', '' + ruleId);
|
queryParams.set("policy_id", "" + ruleId);
|
||||||
return this.http.get(this._jobBaseUrl, buildHttpRequestOptions(queryParams)).toPromise()
|
return this.http
|
||||||
|
.get(this._jobBaseUrl, buildHttpRequestOptions(queryParams))
|
||||||
|
.toPromise()
|
||||||
.then(response => {
|
.then(response => {
|
||||||
let result: ReplicationJob = {
|
let result: ReplicationJob = {
|
||||||
metadata: {
|
metadata: {
|
||||||
@ -291,19 +389,31 @@ export class ReplicationDefaultService extends ReplicationService {
|
|||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getJobLog(jobId: number | string): Observable<string> | Promise<string> | string {
|
public getJobLog(
|
||||||
|
jobId: number | string
|
||||||
|
): Observable<string> | Promise<string> | string {
|
||||||
if (!jobId || jobId <= 0) {
|
if (!jobId || jobId <= 0) {
|
||||||
return Promise.reject('Bad argument');
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
let logUrl = `${this._jobBaseUrl}/${jobId}/log`;
|
let logUrl = `${this._jobBaseUrl}/${jobId}/log`;
|
||||||
return this.http.get(logUrl, HTTP_GET_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.get(logUrl, HTTP_GET_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public stopJobs(jobId: number | string): Observable<any> | Promise<any> | any {
|
public stopJobs(
|
||||||
return this.http.put(this._jobBaseUrl, JSON.stringify({'policy_id': jobId, 'status': 'stop' }), HTTP_JSON_OPTIONS).toPromise()
|
jobId: number | string
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
|
return this.http
|
||||||
|
.put(
|
||||||
|
this._jobBaseUrl,
|
||||||
|
JSON.stringify({ policy_id: jobId, status: "stop" }),
|
||||||
|
HTTP_JSON_OPTIONS
|
||||||
|
)
|
||||||
|
.toPromise()
|
||||||
.then(response => response)
|
.then(response => response)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
import { Observable } from 'rxjs/Observable';
|
import { Http } from "@angular/http";
|
||||||
import 'rxjs/add/observable/of';
|
|
||||||
import { Injectable, Inject } from "@angular/core";
|
import { Injectable, Inject } from "@angular/core";
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import { Observable } from "rxjs/Observable";
|
||||||
import { Http, URLSearchParams } from '@angular/http';
|
import "rxjs/add/observable/of";
|
||||||
import { buildHttpRequestOptions, HTTP_JSON_OPTIONS } from '../utils';
|
|
||||||
import { RequestQueryParams } from './RequestQueryParams';
|
|
||||||
|
|
||||||
import {
|
import { SERVICE_CONFIG, IServiceConfig } from "../service.config";
|
||||||
VulnerabilityItem,
|
import { buildHttpRequestOptions, HTTP_JSON_OPTIONS } from "../utils";
|
||||||
VulnerabilitySummary
|
import { RequestQueryParams } from "./RequestQueryParams";
|
||||||
} from './interface';
|
import { VulnerabilityItem, VulnerabilitySummary } from "./interface";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the vulnerabilities scanning results for the specified tag.
|
* Get the vulnerabilities scanning results for the specified tag.
|
||||||
@ -28,7 +25,14 @@ export abstract class ScanningResultService {
|
|||||||
*
|
*
|
||||||
* @memberOf ScanningResultService
|
* @memberOf ScanningResultService
|
||||||
*/
|
*/
|
||||||
abstract getVulnerabilityScanningSummary(repoName: string, tagId: string, queryParams?: RequestQueryParams): Observable<VulnerabilitySummary> | Promise<VulnerabilitySummary> | VulnerabilitySummary;
|
abstract getVulnerabilityScanningSummary(
|
||||||
|
repoName: string,
|
||||||
|
tagId: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
):
|
||||||
|
| Observable<VulnerabilitySummary>
|
||||||
|
| Promise<VulnerabilitySummary>
|
||||||
|
| VulnerabilitySummary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the detailed vulnerabilities scanning results.
|
* Get the detailed vulnerabilities scanning results.
|
||||||
@ -39,8 +43,14 @@ export abstract class ScanningResultService {
|
|||||||
*
|
*
|
||||||
* @memberOf ScanningResultService
|
* @memberOf ScanningResultService
|
||||||
*/
|
*/
|
||||||
abstract getVulnerabilityScanningResults(repoName: string, tagId: string, queryParams?: RequestQueryParams): Observable<VulnerabilityItem[]> | Promise<VulnerabilityItem[]> | VulnerabilityItem[];
|
abstract getVulnerabilityScanningResults(
|
||||||
|
repoName: string,
|
||||||
|
tagId: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
):
|
||||||
|
| Observable<VulnerabilityItem[]>
|
||||||
|
| Promise<VulnerabilityItem[]>
|
||||||
|
| VulnerabilityItem[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a new vulnerability scanning
|
* Start a new vulnerability scanning
|
||||||
@ -52,7 +62,10 @@ export abstract class ScanningResultService {
|
|||||||
*
|
*
|
||||||
* @memberOf ScanningResultService
|
* @memberOf ScanningResultService
|
||||||
*/
|
*/
|
||||||
abstract startVulnerabilityScanning(repoName: string, tagId: string): Observable<any> | Promise<any> | any;
|
abstract startVulnerabilityScanning(
|
||||||
|
repoName: string,
|
||||||
|
tagId: string
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger the scanning all action.
|
* Trigger the scanning all action.
|
||||||
@ -67,48 +80,82 @@ export abstract class ScanningResultService {
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ScanningResultDefaultService extends ScanningResultService {
|
export class ScanningResultDefaultService extends ScanningResultService {
|
||||||
_baseUrl: string = '/api/repositories';
|
_baseUrl: string = "/api/repositories";
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private http: Http,
|
private http: Http,
|
||||||
@Inject(SERVICE_CONFIG) private config: IServiceConfig) {
|
@Inject(SERVICE_CONFIG) private config: IServiceConfig
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
if (this.config && this.config.vulnerabilityScanningBaseEndpoint) {
|
if (this.config && this.config.vulnerabilityScanningBaseEndpoint) {
|
||||||
this._baseUrl = this.config.vulnerabilityScanningBaseEndpoint;
|
this._baseUrl = this.config.vulnerabilityScanningBaseEndpoint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getVulnerabilityScanningSummary(repoName: string, tagId: string, queryParams?: RequestQueryParams): Observable<VulnerabilitySummary> | Promise<VulnerabilitySummary> | VulnerabilitySummary {
|
getVulnerabilityScanningSummary(
|
||||||
if (!repoName || repoName.trim() === '' || !tagId || tagId.trim() === '') {
|
repoName: string,
|
||||||
return Promise.reject('Bad argument');
|
tagId: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
):
|
||||||
|
| Observable<VulnerabilitySummary>
|
||||||
|
| Promise<VulnerabilitySummary>
|
||||||
|
| VulnerabilitySummary {
|
||||||
|
if (!repoName || repoName.trim() === "" || !tagId || tagId.trim() === "") {
|
||||||
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Observable.of({});
|
return Observable.of({} as VulnerabilitySummary);
|
||||||
}
|
}
|
||||||
|
|
||||||
getVulnerabilityScanningResults(repoName: string, tagId: string, queryParams?: RequestQueryParams): Observable<VulnerabilityItem[]> | Promise<VulnerabilityItem[]> | VulnerabilityItem[] {
|
getVulnerabilityScanningResults(
|
||||||
if (!repoName || repoName.trim() === '' || !tagId || tagId.trim() === '') {
|
repoName: string,
|
||||||
return Promise.reject('Bad argument');
|
tagId: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
):
|
||||||
|
| Observable<VulnerabilityItem[]>
|
||||||
|
| Promise<VulnerabilityItem[]>
|
||||||
|
| VulnerabilityItem[] {
|
||||||
|
if (!repoName || repoName.trim() === "" || !tagId || tagId.trim() === "") {
|
||||||
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.http.get(`${this._baseUrl}/${repoName}/tags/${tagId}/vulnerability/details`, buildHttpRequestOptions(queryParams)).toPromise()
|
return this.http
|
||||||
|
.get(
|
||||||
|
`${this._baseUrl}/${repoName}/tags/${tagId}/vulnerability/details`,
|
||||||
|
buildHttpRequestOptions(queryParams)
|
||||||
|
)
|
||||||
|
.toPromise()
|
||||||
.then(response => response.json() as VulnerabilityItem[])
|
.then(response => response.json() as VulnerabilityItem[])
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
startVulnerabilityScanning(repoName: string, tagId: string): Observable<any> | Promise<any> | any {
|
startVulnerabilityScanning(
|
||||||
if (!repoName || repoName.trim() === '' || !tagId || tagId.trim() === '') {
|
repoName: string,
|
||||||
return Promise.reject('Bad argument');
|
tagId: string
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
|
if (!repoName || repoName.trim() === "" || !tagId || tagId.trim() === "") {
|
||||||
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.http.post(`${this._baseUrl}/${repoName}/tags/${tagId}/scan`, HTTP_JSON_OPTIONS).toPromise()
|
return this.http
|
||||||
.then(() => { return true })
|
.post(
|
||||||
|
`${this._baseUrl}/${repoName}/tags/${tagId}/scan`,
|
||||||
|
HTTP_JSON_OPTIONS
|
||||||
|
)
|
||||||
|
.toPromise()
|
||||||
|
.then(() => {
|
||||||
|
return true;
|
||||||
|
})
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
startScanningAll(): Observable<any> | Promise<any> | any {
|
startScanningAll(): Observable<any> | Promise<any> | any {
|
||||||
return this.http.post(`${this._baseUrl}/scanAll`, HTTP_JSON_OPTIONS).toPromise()
|
return this.http
|
||||||
.then(() => {return true})
|
.post(`${this._baseUrl}/scanAll`, HTTP_JSON_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
|
.then(() => {
|
||||||
|
return true;
|
||||||
|
})
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,29 +1,25 @@
|
|||||||
import { TestBed, inject, async } from '@angular/core/testing';
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
import { TagService, TagDefaultService } from './tag.service';
|
|
||||||
import { SharedModule } from '../shared/shared.module';
|
import { SharedModule } from '../shared/shared.module';
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
||||||
|
import { TagService, TagDefaultService } from './tag.service';
|
||||||
|
|
||||||
import { Tag } from './interface';
|
|
||||||
|
|
||||||
import { VerifiedSignature } from './tag.service';
|
|
||||||
import { toPromise } from '../utils';
|
|
||||||
|
|
||||||
describe('TagService', () => {
|
describe('TagService', () => {
|
||||||
let mockTags: Tag[] = [
|
// let mockTags: Tag[] = [
|
||||||
{
|
// {
|
||||||
"digest": "sha256:e5c82328a509aeb7c18c1d7fb36633dc638fcf433f651bdcda59c1cc04d3ee55",
|
// "digest": "sha256:e5c82328a509aeb7c18c1d7fb36633dc638fcf433f651bdcda59c1cc04d3ee55",
|
||||||
"name": "1.11.5",
|
// "name": "1.11.5",
|
||||||
"size": "2049",
|
// "size": "2049",
|
||||||
"architecture": "amd64",
|
// "architecture": "amd64",
|
||||||
"os": "linux",
|
// "os": "linux",
|
||||||
"docker_version": "1.12.3",
|
// "docker_version": "1.12.3",
|
||||||
"author": "NGINX Docker Maintainers \"docker-maint@nginx.com\"",
|
// "author": "NGINX Docker Maintainers \"docker-maint@nginx.com\"",
|
||||||
"created": new Date("2016-11-08T22:41:15.912313785Z"),
|
// "created": new Date("2016-11-08T22:41:15.912313785Z"),
|
||||||
"signature": null,
|
// "signature": null,
|
||||||
'labels': []
|
// 'labels': []
|
||||||
}
|
// }
|
||||||
];
|
// ];
|
||||||
|
|
||||||
const mockConfig: IServiceConfig = {
|
const mockConfig: IServiceConfig = {
|
||||||
repositoryBaseEndpoint: "/api/repositories/testing"
|
repositoryBaseEndpoint: "/api/repositories/testing"
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
import { RequestQueryParams } from './RequestQueryParams';
|
|
||||||
import {Label, Tag} from './interface';
|
|
||||||
import { Injectable, Inject } from "@angular/core";
|
import { Injectable, Inject } from "@angular/core";
|
||||||
import 'rxjs/add/observable/of';
|
import { Http } from "@angular/http";
|
||||||
import { Http } from '@angular/http';
|
import { Observable } from "rxjs/Observable";
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import "rxjs/add/observable/of";
|
||||||
import { buildHttpRequestOptions, HTTP_JSON_OPTIONS, HTTP_GET_OPTIONS } from '../utils';
|
|
||||||
|
import { SERVICE_CONFIG, IServiceConfig } from "../service.config";
|
||||||
|
import {
|
||||||
|
buildHttpRequestOptions,
|
||||||
|
HTTP_JSON_OPTIONS,
|
||||||
|
HTTP_GET_OPTIONS
|
||||||
|
} from "../utils";
|
||||||
|
import { RequestQueryParams } from "./RequestQueryParams";
|
||||||
|
import { Tag } from "./interface";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For getting tag signatures.
|
* For getting tag signatures.
|
||||||
@ -18,7 +23,7 @@ export class VerifiedSignature {
|
|||||||
tag: string;
|
tag: string;
|
||||||
hashes: {
|
hashes: {
|
||||||
sha256: string;
|
sha256: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,7 +45,10 @@ export abstract class TagService {
|
|||||||
*
|
*
|
||||||
* @memberOf TagService
|
* @memberOf TagService
|
||||||
*/
|
*/
|
||||||
abstract getTags(repositoryName: string, queryParams?: RequestQueryParams): Observable<Tag[]> | Promise<Tag[]> | Tag[];
|
abstract getTags(
|
||||||
|
repositoryName: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<Tag[]> | Promise<Tag[]> | Tag[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the specified tag.
|
* Delete the specified tag.
|
||||||
@ -52,7 +60,10 @@ export abstract class TagService {
|
|||||||
*
|
*
|
||||||
* @memberOf TagService
|
* @memberOf TagService
|
||||||
*/
|
*/
|
||||||
abstract deleteTag(repositoryName: string, tag: string): Observable<any> | Promise<any> | any;
|
abstract deleteTag(
|
||||||
|
repositoryName: string,
|
||||||
|
tag: string
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the specified tag.
|
* Get the specified tag.
|
||||||
@ -64,10 +75,22 @@ export abstract class TagService {
|
|||||||
*
|
*
|
||||||
* @memberOf TagService
|
* @memberOf TagService
|
||||||
*/
|
*/
|
||||||
abstract getTag(repositoryName: string, tag: string, queryParams?: RequestQueryParams): Observable<Tag> | Promise<Tag> | Tag;
|
abstract getTag(
|
||||||
|
repositoryName: string,
|
||||||
|
tag: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<Tag> | Promise<Tag> | Tag;
|
||||||
|
|
||||||
abstract addLabelToImages(repoName: string, tagName: string, labelId: number): Observable<any> | Promise<any> | any;
|
abstract addLabelToImages(
|
||||||
abstract deleteLabelToImages(repoName: string, tagName: string, labelId: number): Observable<any> | Promise<any> | any;
|
repoName: string,
|
||||||
|
tagName: string,
|
||||||
|
labelId: number
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
|
abstract deleteLabelToImages(
|
||||||
|
repoName: string,
|
||||||
|
tagName: string,
|
||||||
|
labelId: number
|
||||||
|
): Observable<any> | Promise<any> | any;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,81 +109,120 @@ export class TagDefaultService extends TagService {
|
|||||||
@Inject(SERVICE_CONFIG) private config: IServiceConfig
|
@Inject(SERVICE_CONFIG) private config: IServiceConfig
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._baseUrl = this.config.repositoryBaseEndpoint ? this.config.repositoryBaseEndpoint : '/api/repositories';
|
this._baseUrl = this.config.repositoryBaseEndpoint
|
||||||
this._labelUrl = this.config.labelEndpoint? this.config.labelEndpoint : '/api/labels';
|
? this.config.repositoryBaseEndpoint
|
||||||
|
: "/api/repositories";
|
||||||
|
this._labelUrl = this.config.labelEndpoint
|
||||||
|
? this.config.labelEndpoint
|
||||||
|
: "/api/labels";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private methods
|
// Private methods
|
||||||
// These two methods are temporary, will be deleted in future after API refactored
|
// These two methods are temporary, will be deleted in future after API refactored
|
||||||
_getTags(repositoryName: string, queryParams?: RequestQueryParams): Promise<Tag[]> {
|
_getTags(
|
||||||
|
repositoryName: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Promise<Tag[]> {
|
||||||
if (!queryParams) {
|
if (!queryParams) {
|
||||||
queryParams = new RequestQueryParams();
|
queryParams = new RequestQueryParams();
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParams.set('detail', '1');
|
queryParams.set("detail", "1");
|
||||||
let url: string = `${this._baseUrl}/${repositoryName}/tags`;
|
let url: string = `${this._baseUrl}/${repositoryName}/tags`;
|
||||||
|
|
||||||
return this.http.get(url, buildHttpRequestOptions(queryParams)).toPromise()
|
return this.http
|
||||||
|
.get(url, buildHttpRequestOptions(queryParams))
|
||||||
|
.toPromise()
|
||||||
.then(response => response.json() as Tag[])
|
.then(response => response.json() as Tag[])
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
_getSignatures(repositoryName: string): Promise<VerifiedSignature[]> {
|
_getSignatures(repositoryName: string): Promise<VerifiedSignature[]> {
|
||||||
let url: string = `${this._baseUrl}/${repositoryName}/signatures`;
|
let url: string = `${this._baseUrl}/${repositoryName}/signatures`;
|
||||||
return this.http.get(url, HTTP_GET_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.get(url, HTTP_GET_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response.json() as VerifiedSignature[])
|
.then(response => response.json() as VerifiedSignature[])
|
||||||
.catch(error => Promise.reject(error))
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTags(repositoryName: string, queryParams?: RequestQueryParams): Observable<Tag[]> | Promise<Tag[]> | Tag[] {
|
public getTags(
|
||||||
|
repositoryName: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<Tag[]> | Promise<Tag[]> | Tag[] {
|
||||||
if (!repositoryName) {
|
if (!repositoryName) {
|
||||||
return Promise.reject("Bad argument");
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
return this._getTags(repositoryName, queryParams);
|
return this._getTags(repositoryName, queryParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteTag(repositoryName: string, tag: string): Observable<any> | Promise<Tag> | any {
|
public deleteTag(
|
||||||
|
repositoryName: string,
|
||||||
|
tag: string
|
||||||
|
): Observable<any> | Promise<Tag> | any {
|
||||||
if (!repositoryName || !tag) {
|
if (!repositoryName || !tag) {
|
||||||
return Promise.reject("Bad argument");
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
let url: string = `${this._baseUrl}/${repositoryName}/tags/${tag}`;
|
let url: string = `${this._baseUrl}/${repositoryName}/tags/${tag}`;
|
||||||
return this.http.delete(url, HTTP_JSON_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.delete(url, HTTP_JSON_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response)
|
.then(response => response)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTag(repositoryName: string, tag: string, queryParams?: RequestQueryParams): Observable<Tag> | Promise<Tag> | Tag {
|
public getTag(
|
||||||
|
repositoryName: string,
|
||||||
|
tag: string,
|
||||||
|
queryParams?: RequestQueryParams
|
||||||
|
): Observable<Tag> | Promise<Tag> | Tag {
|
||||||
if (!repositoryName || !tag) {
|
if (!repositoryName || !tag) {
|
||||||
return Promise.reject("Bad argument");
|
return Promise.reject("Bad argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
let url: string = `${this._baseUrl}/${repositoryName}/tags/${tag}`;
|
let url: string = `${this._baseUrl}/${repositoryName}/tags/${tag}`;
|
||||||
return this.http.get(url, HTTP_GET_OPTIONS).toPromise()
|
return this.http
|
||||||
|
.get(url, HTTP_GET_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response.json() as Tag)
|
.then(response => response.json() as Tag)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public addLabelToImages(repoName: string, tagName: string, labelId: number): Observable<any> | Promise<any> | any {
|
public addLabelToImages(
|
||||||
|
repoName: string,
|
||||||
|
tagName: string,
|
||||||
|
labelId: number
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!labelId || !tagName || !repoName) {
|
if (!labelId || !tagName || !repoName) {
|
||||||
return Promise.reject('Invalid parameters.');
|
return Promise.reject("Invalid parameters.");
|
||||||
}
|
}
|
||||||
|
|
||||||
let _addLabelToImageUrl = `${this._baseUrl}/${repoName}/tags/${tagName}/labels`;
|
let _addLabelToImageUrl = `${
|
||||||
return this.http.post(_addLabelToImageUrl, {id: labelId}, HTTP_JSON_OPTIONS).toPromise()
|
this._baseUrl
|
||||||
|
}/${repoName}/tags/${tagName}/labels`;
|
||||||
|
return this.http
|
||||||
|
.post(_addLabelToImageUrl, { id: labelId }, HTTP_JSON_OPTIONS)
|
||||||
|
.toPromise()
|
||||||
.then(response => response.status)
|
.then(response => response.status)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteLabelToImages(repoName: string, tagName: string, labelId: number): Observable<any> | Promise<any> | any {
|
public deleteLabelToImages(
|
||||||
|
repoName: string,
|
||||||
|
tagName: string,
|
||||||
|
labelId: number
|
||||||
|
): Observable<any> | Promise<any> | any {
|
||||||
if (!labelId || !tagName || !repoName) {
|
if (!labelId || !tagName || !repoName) {
|
||||||
return Promise.reject('Invalid parameters.');
|
return Promise.reject("Invalid parameters.");
|
||||||
}
|
}
|
||||||
|
|
||||||
let _addLabelToImageUrl = `${this._baseUrl}/${repoName}/tags/${tagName}/labels/${labelId}`;
|
let _addLabelToImageUrl = `${
|
||||||
return this.http.delete(_addLabelToImageUrl).toPromise()
|
this._baseUrl
|
||||||
|
}/${repoName}/tags/${tagName}/labels/${labelId}`;
|
||||||
|
return this.http
|
||||||
|
.delete(_addLabelToImageUrl)
|
||||||
|
.toPromise()
|
||||||
.then(response => response.status)
|
.then(response => response.status)
|
||||||
.catch(error => Promise.reject(error));
|
.catch(error => Promise.reject(error));
|
||||||
}
|
}
|
||||||
|
@ -70,12 +70,20 @@ export const enum ConfirmationButtons {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const LabelColor = [
|
export const LabelColor = [
|
||||||
{'color': '#000000', 'textColor' : 'white'}, {'color': '#61717D', 'textColor': 'white'}, {'color': '#737373', 'textColor' : 'white'}, {'color': '#80746D', 'textColor': 'white'},
|
{ 'color': '#000000', 'textColor': 'white' }, { 'color': '#61717D', 'textColor': 'white' },
|
||||||
{'color': '#FFFFFF', 'textColor' : 'black'}, {'color': '#A9B6BE', 'textColor': 'black'}, {'color': '#DDDDDD', 'textColor' : 'black'}, {'color': '#BBB3A9', 'textColor': 'black'},
|
{ 'color': '#737373', 'textColor': 'white' }, { 'color': '#80746D', 'textColor': 'white' },
|
||||||
{'color': '#0065AB', 'textColor' : 'white'}, {'color': '#343DAC', 'textColor': 'white'}, {'color': '#781DA0', 'textColor' : 'white'}, {'color': '#9B0D54', 'textColor': 'white'},
|
{ 'color': '#FFFFFF', 'textColor': 'black' }, { 'color': '#A9B6BE', 'textColor': 'black' },
|
||||||
{'color': '#0095D3', 'textColor' : 'black'}, {'color': '#9DA3DB', 'textColor': 'black'}, {'color': '#BE90D6', 'textColor' : 'black'}, {'color': '#F1428A', 'textColor': 'black'},
|
{ 'color': '#DDDDDD', 'textColor': 'black' }, { 'color': '#BBB3A9', 'textColor': 'black' },
|
||||||
{'color': '#1D5100', 'textColor' : 'white'}, {'color': '#006668', 'textColor': 'white'}, {'color': '#006690', 'textColor' : 'white'}, {'color': '#004A70', 'textColor': 'white'},
|
{ 'color': '#0065AB', 'textColor': 'white' }, { 'color': '#343DAC', 'textColor': 'white' },
|
||||||
{'color': '#48960C', 'textColor' : 'black'}, {'color': '#00AB9A', 'textColor': 'black'}, {'color': '#00B7D6', 'textColor' : 'black'}, {'color': '#0081A7', 'textColor': 'black'},
|
{ 'color': '#781DA0', 'textColor': 'white' }, { 'color': '#9B0D54', 'textColor': 'white' },
|
||||||
{'color': '#C92100', 'textColor' : 'white'}, {'color': '#CD3517', 'textColor': 'white'}, {'color': '#C25400', 'textColor' : 'white'}, {'color': '#D28F00', 'textColor': 'white'},
|
{ 'color': '#0095D3', 'textColor': 'black' }, { 'color': '#9DA3DB', 'textColor': 'black' },
|
||||||
{'color': '#F52F52', 'textColor' : 'black'}, {'color': '#FF5501', 'textColor': 'black'}, {'color': '#F57600', 'textColor' : 'black'}, {'color': '#FFDC0B', 'textColor': 'black'},
|
{ 'color': '#BE90D6', 'textColor': 'black' }, { 'color': '#F1428A', 'textColor': 'black' },
|
||||||
|
{ 'color': '#1D5100', 'textColor': 'white' }, { 'color': '#006668', 'textColor': 'white' },
|
||||||
|
{ 'color': '#006690', 'textColor': 'white' }, { 'color': '#004A70', 'textColor': 'white' },
|
||||||
|
{ 'color': '#48960C', 'textColor': 'black' }, { 'color': '#00AB9A', 'textColor': 'black' },
|
||||||
|
{ 'color': '#00B7D6', 'textColor': 'black' }, { 'color': '#0081A7', 'textColor': 'black' },
|
||||||
|
{ 'color': '#C92100', 'textColor': 'white' }, { 'color': '#CD3517', 'textColor': 'white' },
|
||||||
|
{ 'color': '#C25400', 'textColor': 'white' }, { 'color': '#D28F00', 'textColor': 'white' },
|
||||||
|
{ 'color': '#F52F52', 'textColor': 'black' }, { 'color': '#FF5501', 'textColor': 'black' },
|
||||||
|
{ 'color': '#F57600', 'textColor': 'black' }, { 'color': '#FFDC0B', 'textColor': 'black' },
|
||||||
];
|
];
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { NgForm } from '@angular/forms';
|
|
||||||
import { httpStatusCode, AlertType } from './shared.const';
|
|
||||||
/**
|
/**
|
||||||
* To handle the error message body
|
* To handle the error message body
|
||||||
*
|
*
|
||||||
@ -46,7 +44,7 @@ export const errorHandler = function (error: any): string {
|
|||||||
return "UNKNOWN_ERROR";
|
return "UNKNOWN_ERROR";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
export class CancelablePromise<T> {
|
export class CancelablePromise<T> {
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ export class TagDetailComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => this.errorHandler.error(error))
|
.catch(error => this.errorHandler.error(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<div id="filterArea">
|
<div id="filterArea">
|
||||||
<div class='filterLabelPiece' *ngIf="!withAdmiral" [hidden]="!openLabelFilterPiece" [style.left.px]='filterLabelPieceWidth' ><hbr-label-piece [hidden]='!filterOneLabel' [label]="filterOneLabel" [labelWidth]="130"></hbr-label-piece></div>
|
<div class='filterLabelPiece' *ngIf="!withAdmiral" [hidden]="!openLabelFilterPiece" [style.left.px]='filterLabelPieceWidth' ><hbr-label-piece [hidden]='!filterOneLabel' [label]="filterOneLabel" [labelWidth]="130"></hbr-label-piece></div>
|
||||||
<div class="flex-xs-middle">
|
<div class="flex-xs-middle">
|
||||||
<hbr-filter [withDivider]="true" filterPlaceholder="{{'TAG.FILTER_FOR_TAGS' | translate}}" (filter)="doSearchTagNames($event)" (openFlag)="openFlagEvent($event)" [currentValue]="lastFilteredTagName"></hbr-filter>
|
<hbr-filter [withDivider]="true" filterPlaceholder="{{'TAG.FILTER_FOR_TAGS' | translate}}" (filterEvt)="doSearchTagNames($event)" (openFlag)="openFlagEvent($event)" [currentValue]="lastFilteredTagName"></hbr-filter>
|
||||||
<div class="labelFilterPanel" *ngIf="!withAdmiral" [hidden]="!openLabelFilterPanel">
|
<div class="labelFilterPanel" *ngIf="!withAdmiral" [hidden]="!openLabelFilterPanel">
|
||||||
<a class="filterClose" (click)="closeFilter()">×</a>
|
<a class="filterClose" (click)="closeFilter()">×</a>
|
||||||
<label class="filterLabelHeader">{{'REPOSITORY.FILTER_BY_LABEL' | translate}}</label>
|
<label class="filterLabelHeader">{{'REPOSITORY.FILTER_BY_LABEL' | translate}}</label>
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import { ComponentFixture, TestBed, async, fakeAsync, tick } from '@angular/core/testing';
|
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
|
||||||
import { DebugElement } from '@angular/core';
|
import { DebugElement } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
|
||||||
|
|
||||||
import { SharedModule } from '../shared/shared.module';
|
import { SharedModule } from '../shared/shared.module';
|
||||||
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
||||||
@ -12,9 +10,8 @@ import {Label, Tag} from '../service/interface';
|
|||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
||||||
import { TagService, TagDefaultService, ScanningResultService, ScanningResultDefaultService } from '../service/index';
|
import { TagService, TagDefaultService, ScanningResultService, ScanningResultDefaultService } from '../service/index';
|
||||||
import { VULNERABILITY_DIRECTIVES } from '../vulnerability-scanning/index';
|
import { VULNERABILITY_DIRECTIVES } from '../vulnerability-scanning/index';
|
||||||
import { FILTER_DIRECTIVES } from '../filter/index'
|
import { FILTER_DIRECTIVES } from '../filter/index';
|
||||||
|
|
||||||
import { Observable, Subscription } from 'rxjs/Rx';
|
|
||||||
import { ChannelService } from '../channel/index';
|
import { ChannelService } from '../channel/index';
|
||||||
|
|
||||||
import { JobLogViewerComponent } from '../job-log-viewer/index';
|
import { JobLogViewerComponent } from '../job-log-viewer/index';
|
||||||
|
@ -18,9 +18,8 @@ import {
|
|||||||
Input,
|
Input,
|
||||||
Output,
|
Output,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
ChangeDetectionStrategy,
|
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
ElementRef, AfterContentInit, AfterViewInit
|
ElementRef, AfterViewInit
|
||||||
} from "@angular/core";
|
} from "@angular/core";
|
||||||
|
|
||||||
import { TagService, VulnerabilitySeverity, RequestQueryParams } from "../service/index";
|
import { TagService, VulnerabilitySeverity, RequestQueryParams } from "../service/index";
|
||||||
@ -193,7 +192,7 @@ export class TagComponent implements OnInit, AfterViewInit {
|
|||||||
}else {
|
}else {
|
||||||
data.show = false;
|
data.show = false;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setInterval(() => this.ref.markForCheck(), 200);
|
setInterval(() => this.ref.markForCheck(), 200);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
@ -303,7 +302,7 @@ export class TagComponent implements OnInit, AfterViewInit {
|
|||||||
this.imageStickLabels.forEach(data => {
|
this.imageStickLabels.forEach(data => {
|
||||||
data.iconsShow = false;
|
data.iconsShow = false;
|
||||||
data.show = true;
|
data.show = true;
|
||||||
})
|
});
|
||||||
if (tag[0].labels.length) {
|
if (tag[0].labels.length) {
|
||||||
tag[0].labels.forEach((labelInfo: Label) => {
|
tag[0].labels.forEach((labelInfo: Label) => {
|
||||||
let findedLabel = this.imageStickLabels.find(data => labelInfo.id === data['label'].id);
|
let findedLabel = this.imageStickLabels.find(data => labelInfo.id === data['label'].id);
|
||||||
@ -388,7 +387,6 @@ export class TagComponent implements OnInit, AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
filterLabel(labelInfo: LabelState): void {
|
filterLabel(labelInfo: LabelState): void {
|
||||||
let labelName = labelInfo.label.name;
|
|
||||||
let labelId = labelInfo.label.id;
|
let labelId = labelInfo.label.id;
|
||||||
// insert the unselected label to groups with the same icons
|
// insert the unselected label to groups with the same icons
|
||||||
let preLabelInfo = this.imageFilterLabels.find(data => data.label.id === this.filterOneLabel.id);
|
let preLabelInfo = this.imageFilterLabels.find(data => data.label.id === this.filterOneLabel.id);
|
||||||
@ -613,7 +611,8 @@ export class TagComponent implements OnInit, AfterViewInit {
|
|||||||
if (signature) {
|
if (signature) {
|
||||||
Observable.forkJoin(this.translateService.get("BATCH.DELETED_FAILURE"),
|
Observable.forkJoin(this.translateService.get("BATCH.DELETED_FAILURE"),
|
||||||
this.translateService.get("REPOSITORY.DELETION_SUMMARY_TAG_DENIED")).subscribe(res => {
|
this.translateService.get("REPOSITORY.DELETION_SUMMARY_TAG_DENIED")).subscribe(res => {
|
||||||
let wrongInfo: string = res[1] + "notary -s https://" + this.registryUrl + ":4443 -d ~/.docker/trust remove -p " + this.registryUrl + "/" + this.repoName + " " + name;
|
let wrongInfo: string = res[1] + "notary -s https://" + this.registryUrl + ":4443 -d ~/.docker/trust remove -p " +
|
||||||
|
this.registryUrl + "/" + this.repoName + " " + name;
|
||||||
findedList = BathInfoChanges(findedList, res[0], false, true, wrongInfo);
|
findedList = BathInfoChanges(findedList, res[0], false, true, wrongInfo);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -5,6 +5,7 @@ import { Directive, EventEmitter, HostListener, Input, OnDestroy, OnInit, Output
|
|||||||
selector: '[ngxClipboard]'
|
selector: '[ngxClipboard]'
|
||||||
})
|
})
|
||||||
export class ClipboardDirective implements OnInit, OnDestroy {
|
export class ClipboardDirective implements OnInit, OnDestroy {
|
||||||
|
// tslint:disable-next-line:no-input-rename
|
||||||
@Input('ngxClipboard') public targetElm: HTMLInputElement;
|
@Input('ngxClipboard') public targetElm: HTMLInputElement;
|
||||||
|
|
||||||
@Input() public cbContent: string;
|
@Input() public cbContent: string;
|
||||||
@ -24,7 +25,9 @@ export class ClipboardDirective implements OnInit, OnDestroy {
|
|||||||
this.clipboardSrv.destroy();
|
this.clipboardSrv.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('click', ['$event.target']) private onClick(button: ElementRef) {
|
@HostListener('click', ['$event.target'])
|
||||||
|
// tslint:disable-next-line:no-unused-variable
|
||||||
|
private onClick(button: ElementRef) {
|
||||||
if (!this.clipboardSrv.isSupported) {
|
if (!this.clipboardSrv.isSupported) {
|
||||||
this.handleResult(false, undefined);
|
this.handleResult(false, undefined);
|
||||||
} else if (this.targetElm && this.clipboardSrv.isTargetValid(this.targetElm)) {
|
} else if (this.targetElm && this.clipboardSrv.isTargetValid(this.targetElm)) {
|
||||||
|
@ -1,34 +1,53 @@
|
|||||||
import { Inject, InjectionToken, Injectable, Optional, Renderer, SkipSelf } from '@angular/core';
|
import {
|
||||||
import { DOCUMENT } from '@angular/platform-browser';
|
Inject,
|
||||||
|
// tslint:disable-next-line:no-unused-variable
|
||||||
|
InjectionToken,
|
||||||
|
Injectable,
|
||||||
|
Optional,
|
||||||
|
Renderer,
|
||||||
|
SkipSelf
|
||||||
|
} from "@angular/core";
|
||||||
|
import { DOCUMENT } from "@angular/platform-browser";
|
||||||
import { WINDOW } from "../ngx-window-token/index";
|
import { WINDOW } from "../ngx-window-token/index";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ClipboardService {
|
export class ClipboardService {
|
||||||
private tempTextArea: HTMLTextAreaElement;
|
private tempTextArea: HTMLTextAreaElement;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DOCUMENT) private document: any,
|
@Inject(DOCUMENT) private document: any,
|
||||||
@Inject(WINDOW) private window: any,
|
@Inject(WINDOW) private window: any
|
||||||
) {}
|
) {}
|
||||||
public get isSupported(): boolean {
|
public get isSupported(): boolean {
|
||||||
return !!this.document.queryCommandSupported && !!this.document.queryCommandSupported('copy');
|
return (
|
||||||
|
!!this.document.queryCommandSupported &&
|
||||||
|
!!this.document.queryCommandSupported("copy")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public isTargetValid(element: HTMLInputElement | HTMLTextAreaElement): boolean {
|
public isTargetValid(
|
||||||
if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
|
element: HTMLInputElement | HTMLTextAreaElement
|
||||||
if (element.hasAttribute('disabled')) {
|
): boolean {
|
||||||
// tslint:disable-next-line:max-line-length
|
if (
|
||||||
throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');
|
element instanceof HTMLInputElement ||
|
||||||
|
element instanceof HTMLTextAreaElement
|
||||||
|
) {
|
||||||
|
if (element.hasAttribute("disabled")) {
|
||||||
|
throw new Error(
|
||||||
|
'Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
throw new Error('Target should be input or textarea');
|
throw new Error("Target should be input or textarea");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* copyFromInputElement
|
* copyFromInputElement
|
||||||
*/
|
*/
|
||||||
public copyFromInputElement(targetElm: HTMLInputElement | HTMLTextAreaElement, renderer: Renderer): boolean {
|
public copyFromInputElement(
|
||||||
|
targetElm: HTMLInputElement | HTMLTextAreaElement,
|
||||||
|
renderer: Renderer
|
||||||
|
): boolean {
|
||||||
try {
|
try {
|
||||||
this.selectTarget(targetElm, renderer);
|
this.selectTarget(targetElm, renderer);
|
||||||
const re = this.copyText();
|
const re = this.copyText();
|
||||||
@ -61,47 +80,62 @@ export class ClipboardService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// select the target html input element
|
// select the target html input element
|
||||||
private selectTarget(inputElement: HTMLInputElement | HTMLTextAreaElement, renderer: Renderer): number | undefined {
|
private selectTarget(
|
||||||
renderer.invokeElementMethod(inputElement, 'select');
|
inputElement: HTMLInputElement | HTMLTextAreaElement,
|
||||||
renderer.invokeElementMethod(inputElement, 'setSelectionRange', [0, inputElement.value.length]);
|
renderer: Renderer
|
||||||
|
): number | undefined {
|
||||||
|
renderer.invokeElementMethod(inputElement, "select");
|
||||||
|
renderer.invokeElementMethod(inputElement, "setSelectionRange", [
|
||||||
|
0,
|
||||||
|
inputElement.value.length
|
||||||
|
]);
|
||||||
return inputElement.value.length;
|
return inputElement.value.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
private copyText(): boolean {
|
private copyText(): boolean {
|
||||||
return this.document.execCommand('copy');
|
return this.document.execCommand("copy");
|
||||||
}
|
}
|
||||||
// Removes current selection and focus from `target` element.
|
// Removes current selection and focus from `target` element.
|
||||||
private clearSelection(inputElement: HTMLInputElement | HTMLTextAreaElement, window: Window) {
|
private clearSelection(
|
||||||
// tslint:disable-next-line:no-unused-expression
|
inputElement: HTMLInputElement | HTMLTextAreaElement,
|
||||||
inputElement && inputElement.blur();
|
window: Window
|
||||||
|
) {
|
||||||
|
if (inputElement) { inputElement.blur(); }
|
||||||
window.getSelection().removeAllRanges();
|
window.getSelection().removeAllRanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a fake textarea for copy command
|
// create a fake textarea for copy command
|
||||||
private createTempTextArea(doc: Document, window: Window): HTMLTextAreaElement {
|
private createTempTextArea(
|
||||||
const isRTL = doc.documentElement.getAttribute('dir') === 'rtl';
|
doc: Document,
|
||||||
|
window: Window
|
||||||
|
): HTMLTextAreaElement {
|
||||||
|
const isRTL = doc.documentElement.getAttribute("dir") === "rtl";
|
||||||
let ta: HTMLTextAreaElement;
|
let ta: HTMLTextAreaElement;
|
||||||
ta = doc.createElement('textarea');
|
ta = doc.createElement("textarea");
|
||||||
// Prevent zooming on iOS
|
// Prevent zooming on iOS
|
||||||
ta.style.fontSize = '12pt';
|
ta.style.fontSize = "12pt";
|
||||||
// Reset box model
|
// Reset box model
|
||||||
ta.style.border = '0';
|
ta.style.border = "0";
|
||||||
ta.style.padding = '0';
|
ta.style.padding = "0";
|
||||||
ta.style.margin = '0';
|
ta.style.margin = "0";
|
||||||
// Move element out of screen horizontally
|
// Move element out of screen horizontally
|
||||||
ta.style.position = 'absolute';
|
ta.style.position = "absolute";
|
||||||
ta.style[isRTL ? 'right' : 'left'] = '-9999px';
|
ta.style[isRTL ? "right" : "left"] = "-9999px";
|
||||||
// Move element to the same position vertically
|
// Move element to the same position vertically
|
||||||
let yPosition = window.pageYOffset || doc.documentElement.scrollTop;
|
let yPosition = window.pageYOffset || doc.documentElement.scrollTop;
|
||||||
ta.style.top = yPosition + 'px';
|
ta.style.top = yPosition + "px";
|
||||||
ta.setAttribute('readonly', '');
|
ta.setAttribute("readonly", "");
|
||||||
return ta;
|
return ta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// this pattern is mentioned in https://github.com/angular/angular/issues/13854 in #43
|
// this pattern is mentioned in https://github.com/angular/angular/issues/13854 in #43
|
||||||
export function CLIPBOARD_SERVICE_PROVIDER_FACTORY(doc: Document, win: Window, parentDispatcher: ClipboardService) {
|
export function CLIPBOARD_SERVICE_PROVIDER_FACTORY(
|
||||||
|
doc: Document,
|
||||||
|
win: Window,
|
||||||
|
parentDispatcher: ClipboardService
|
||||||
|
) {
|
||||||
return parentDispatcher || new ClipboardService(doc, win);
|
return parentDispatcher || new ClipboardService(doc, win);
|
||||||
};
|
}
|
||||||
|
|
||||||
export const CLIPBOARD_SERVICE_PROVIDER = {
|
export const CLIPBOARD_SERVICE_PROVIDER = {
|
||||||
provide: ClipboardService,
|
provide: ClipboardService,
|
||||||
|
@ -260,8 +260,8 @@ export function doSorting<T extends { [key: string]: any | any[] }>(items: T[],
|
|||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function compareValue(a: any, b: any): boolean {
|
export function compareValue(a: any, b: any): boolean {
|
||||||
if ((a && !b) || (!a && b)) return false;
|
if ((a && !b) || (!a && b)) { return false; };
|
||||||
if (!a && !b) return true;
|
if (!a && !b) { return true; } ;
|
||||||
|
|
||||||
return JSON.stringify(a) === JSON.stringify(b);
|
return JSON.stringify(a) === JSON.stringify(b);
|
||||||
}
|
}
|
||||||
@ -285,6 +285,6 @@ export function isEmptyObject(obj: any): boolean {
|
|||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
export function clone(srcObj: any): any {
|
export function clone(srcObj: any): any {
|
||||||
if (!srcObj) { return null };
|
if (!srcObj) { return null; };
|
||||||
return JSON.parse(JSON.stringify(srcObj));
|
return JSON.parse(JSON.stringify(srcObj));
|
||||||
}
|
}
|
@ -1,5 +1,4 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
import { VulnerabilitySummary } from '../service/index';
|
import { VulnerabilitySummary } from '../service/index';
|
||||||
|
|
||||||
import { ResultBarChartComponent } from './result-bar-chart.component';
|
import { ResultBarChartComponent } from './result-bar-chart.component';
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
Input,
|
Input,
|
||||||
OnInit,
|
OnInit,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
ChangeDetectionStrategy,
|
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
@ -11,7 +10,6 @@ import {
|
|||||||
import { VULNERABILITY_SCAN_STATUS } from '../utils';
|
import { VULNERABILITY_SCAN_STATUS } from '../utils';
|
||||||
import {
|
import {
|
||||||
VulnerabilitySummary,
|
VulnerabilitySummary,
|
||||||
VulnerabilitySeverity,
|
|
||||||
TagService,
|
TagService,
|
||||||
ScanningResultService,
|
ScanningResultService,
|
||||||
Tag
|
Tag
|
||||||
@ -66,7 +64,7 @@ export class ResultBarChartComponent implements OnInit, OnDestroy {
|
|||||||
this.stateCheckTimer = null;
|
this.stateCheckTimer = null;
|
||||||
}
|
}
|
||||||
if (this.scanSubscription) {
|
if (this.scanSubscription) {
|
||||||
this.scanSubscription.unsubscribe()
|
this.scanSubscription.unsubscribe();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +139,7 @@ export class ResultBarChartComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
getSummary(): void {
|
getSummary(): void {
|
||||||
if (!this.repoName || !this.tagId) {
|
if (!this.repoName || !this.tagId) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
toPromise<Tag>(this.tagService.getTag(this.repoName, this.tagId))
|
toPromise<Tag>(this.tagService.getTag(this.repoName, this.tagId))
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="row flex-items-xs-right rightPos">
|
<div class="row flex-items-xs-right rightPos">
|
||||||
<div class="flex-xs-middle option-right">
|
<div class="flex-xs-middle option-right">
|
||||||
<hbr-filter [withDivider]="true" filterPlaceholder="{{'VULNERABILITY.PLACEHOLDER' | translate}}" (filter)="filterVulnerabilities($event)"></hbr-filter>
|
<hbr-filter [withDivider]="true" filterPlaceholder="{{'VULNERABILITY.PLACEHOLDER' | translate}}" (filterEvt)="filterVulnerabilities($event)"></hbr-filter>
|
||||||
<span class="refresh-btn" (click)="refresh()"><clr-icon shape="refresh"></clr-icon></span>
|
<span class="refresh-btn" (click)="refresh()"><clr-icon shape="refresh"></clr-icon></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
import { VulnerabilityItem, VulnerabilitySeverity } from '../service/index';
|
||||||
import { HttpModule } from '@angular/http';
|
|
||||||
import { DebugElement } from '@angular/core';
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
import { VulnerabilityItem, VulnerabilitySeverity, RequestQueryParams } from '../service/index';
|
|
||||||
|
|
||||||
import { ResultGridComponent } from './result-grid.component';
|
import { ResultGridComponent } from './result-grid.component';
|
||||||
import { ScanningResultService, ScanningResultDefaultService } from '../service/scanning.service';
|
import { ScanningResultService, ScanningResultDefaultService } from '../service/scanning.service';
|
||||||
|
@ -37,7 +37,7 @@ export class ResultGridComponent implements OnInit {
|
|||||||
this.dataCache = results;
|
this.dataCache = results;
|
||||||
this.scanningResults = this.dataCache.filter((item: VulnerabilityItem) => item.id !== '');
|
this.scanningResults = this.dataCache.filter((item: VulnerabilityItem) => item.id !== '');
|
||||||
})
|
})
|
||||||
.catch(error => { this.errorHandler.error(error) })
|
.catch(error => { this.errorHandler.error(error); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Should query from back-end service
|
// TODO: Should query from back-end service
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
|
||||||
import { HttpModule } from '@angular/http';
|
|
||||||
import { DebugElement } from '@angular/core';
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
import { VulnerabilitySummary } from '../service/index';
|
import { VulnerabilitySummary } from '../service/index';
|
||||||
|
|
||||||
import { ResultTipComponent } from './result-tip.component';
|
import { ResultTipComponent } from './result-tip.component';
|
||||||
|
@ -43,7 +43,7 @@ export class ResultTipComponent implements OnInit {
|
|||||||
level = VulnerabilitySeverity.LOW;
|
level = VulnerabilitySeverity.LOW;
|
||||||
}else if (this._unknownCount && this._unknownCount >= 1) {
|
}else if (this._unknownCount && this._unknownCount >= 1) {
|
||||||
level = VulnerabilitySeverity.UNKNOWN;
|
level = VulnerabilitySeverity.UNKNOWN;
|
||||||
}else if (this.totalPackages == 0) {
|
}else if (this.totalPackages === 0) {
|
||||||
level = VulnerabilitySeverity.UNKNOWN;
|
level = VulnerabilitySeverity.UNKNOWN;
|
||||||
} else {
|
} else {
|
||||||
level = VulnerabilitySeverity.NONE;
|
level = VulnerabilitySeverity.NONE;
|
||||||
@ -57,8 +57,8 @@ export class ResultTipComponent implements OnInit {
|
|||||||
this.totalPackages = this.summary && this.summary.components ? this.summary.components.total : 0;
|
this.totalPackages = this.summary && this.summary.components ? this.summary.components.total : 0;
|
||||||
if (this.summary && this.summary.components && this.summary.components.summary) {
|
if (this.summary && this.summary.components && this.summary.components.summary) {
|
||||||
this.summary.components.summary.forEach(item => {
|
this.summary.components.summary.forEach(item => {
|
||||||
if (item.severity != VulnerabilitySeverity.NONE) {
|
if (item.severity !== VulnerabilitySeverity.NONE) {
|
||||||
this.packagesWithVul += item.count
|
this.packagesWithVul += item.count;
|
||||||
}
|
}
|
||||||
switch (item.severity) {
|
switch (item.severity) {
|
||||||
case VulnerabilitySeverity.UNKNOWN:
|
case VulnerabilitySeverity.UNKNOWN:
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "ng serve --ssl 1 --ssl-key ssl/server.key --ssl-cert ssl/server.crt --host 0.0.0.0 --proxy-config proxy.config.json",
|
"start": "ng serve --ssl 1 --ssl-key ssl/server.key --ssl-cert ssl/server.crt --host 0.0.0.0 --proxy-config proxy.config.json",
|
||||||
"lint": "tslint \"src/**/*.ts\"",
|
"lint": "tslint \"src/**/*.ts\"",
|
||||||
|
"lint:lib": "tslint \"lib/**/*.ts\"",
|
||||||
"test": "ng test --single-run",
|
"test": "ng test --single-run",
|
||||||
"pree2e": "webdriver-manager update",
|
"pree2e": "webdriver-manager update",
|
||||||
"e2e": "protractor",
|
"e2e": "protractor",
|
||||||
@ -31,7 +32,7 @@
|
|||||||
"clarity-icons": "^0.10.27",
|
"clarity-icons": "^0.10.27",
|
||||||
"clarity-ui": "^0.10.27",
|
"clarity-ui": "^0.10.27",
|
||||||
"core-js": "^2.4.1",
|
"core-js": "^2.4.1",
|
||||||
"harbor-ui": "0.7.18-dev.6",
|
"harbor-ui": "0.7.18-dev.8",
|
||||||
"intl": "^1.2.5",
|
"intl": "^1.2.5",
|
||||||
"mutationobserver-shim": "^0.3.2",
|
"mutationobserver-shim": "^0.3.2",
|
||||||
"ngx-cookie": "^1.0.0",
|
"ngx-cookie": "^1.0.0",
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<div class="form-group form-group-override">
|
<div class="form-group form-group-override">
|
||||||
<label for="account_settings_username" aria-haspopup="true" class="form-group-label-override">{{'PROFILE.USER_NAME' | translate}}</label>
|
<label for="account_settings_username" aria-haspopup="true" class="form-group-label-override">{{'PROFILE.USER_NAME' | translate}}</label>
|
||||||
<input type="text" name="account_settings_username" [(ngModel)]="account.username" disabled id="account_settings_username" size="33">
|
<input type="text" name="account_settings_username" [(ngModel)]="account.username" disabled id="account_settings_username" size="33">
|
||||||
<clr-tooltip *ngIf="renamable">
|
<clr-tooltip *ngIf="canRename">
|
||||||
<button (dblclick)="openRenameAlert()" class="btn btn-link">
|
<button (dblclick)="openRenameAlert()" class="btn btn-link">
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
</button>
|
</button>
|
||||||
|
@ -75,7 +75,7 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
|
|||||||
this.validationStateMap[key] = cont.valid;
|
this.validationStateMap[key] = cont.valid;
|
||||||
// Check email existing from backend
|
// Check email existing from backend
|
||||||
if (cont.valid && key === "account_settings_email") {
|
if (cont.valid && key === "account_settings_email") {
|
||||||
if (this.formValueChanged && this.account.email != this.originalStaticData.email) {
|
if (this.formValueChanged && this.account.email !== this.originalStaticData.email) {
|
||||||
if (this.mailAlreadyChecked[this.account.email]) {
|
if (this.mailAlreadyChecked[this.account.email]) {
|
||||||
this.validationStateMap[key] = !this.mailAlreadyChecked[this.account.email].result;
|
this.validationStateMap[key] = !this.mailAlreadyChecked[this.account.email].result;
|
||||||
if (!this.validationStateMap[key]) {
|
if (!this.validationStateMap[key]) {
|
||||||
@ -116,8 +116,8 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var prop in this.originalStaticData) {
|
for (let prop in this.originalStaticData) {
|
||||||
if (this.originalStaticData[prop] != this.account[prop]) {
|
if (this.originalStaticData[prop] !== this.account[prop]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
|
|||||||
return this.checkOnGoing;
|
return this.checkOnGoing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get renamable(): boolean {
|
public get canRename(): boolean {
|
||||||
return this.account && this.account.has_admin_role && this.account.username === "admin" && this.account.user_id === 1;
|
return this.account && this.account.has_admin_role && this.account.username === "admin" && this.account.user_id === 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
confirmRename(): void {
|
confirmRename(): void {
|
||||||
if (this.renamable) {
|
if (this.canRename) {
|
||||||
this.session.renameAdmin(this.account)
|
this.session.renameAdmin(this.account)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.msgHandler.showSuccess("PROFILE.RENAME_SUCCESS");
|
this.msgHandler.showSuccess("PROFILE.RENAME_SUCCESS");
|
||||||
@ -164,7 +164,7 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewChecked(): void {
|
ngAfterViewChecked(): void {
|
||||||
if (this.accountFormRef != this.accountForm) {
|
if (this.accountFormRef !== this.accountForm) {
|
||||||
this.accountFormRef = this.accountForm;
|
this.accountFormRef = this.accountForm;
|
||||||
if (this.accountFormRef) {
|
if (this.accountFormRef) {
|
||||||
this.accountFormRef.valueChanges.subscribe(data => {
|
this.accountFormRef.valueChanges.subscribe(data => {
|
||||||
|
@ -13,19 +13,20 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
import { CoreModule } from '../core/core.module';
|
import { CoreModule } from '../core/core.module';
|
||||||
|
import { SharedModule } from '../shared/shared.module';
|
||||||
|
import { RepositoryModule } from '../repository/repository.module';
|
||||||
|
|
||||||
import { SignInComponent } from './sign-in/sign-in.component';
|
import { SignInComponent } from './sign-in/sign-in.component';
|
||||||
import { PasswordSettingComponent } from './password-setting/password-setting.component';
|
import { PasswordSettingComponent } from './password-setting/password-setting.component';
|
||||||
import { AccountSettingsModalComponent } from './account-settings/account-settings-modal.component';
|
import { AccountSettingsModalComponent } from './account-settings/account-settings-modal.component';
|
||||||
import { SharedModule } from '../shared/shared.module';
|
|
||||||
import { SignUpComponent } from './sign-up/sign-up.component';
|
import { SignUpComponent } from './sign-up/sign-up.component';
|
||||||
import { ForgotPasswordComponent } from './password-setting/forgot-password/forgot-password.component';
|
import { ForgotPasswordComponent } from './password-setting/forgot-password/forgot-password.component';
|
||||||
import { ResetPasswordComponent } from './password-setting/reset-password/reset-password.component';
|
import { ResetPasswordComponent } from './password-setting/reset-password/reset-password.component';
|
||||||
import { SignUpPageComponent } from './sign-up/sign-up-page.component';
|
import { SignUpPageComponent } from './sign-up/sign-up-page.component';
|
||||||
|
|
||||||
import { PasswordSettingService } from './password-setting/password-setting.service';
|
import { PasswordSettingService } from './password-setting/password-setting.service';
|
||||||
import { RepositoryModule } from '../repository/repository.module';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, ViewChild } from '@angular/core';
|
import { Component, ViewChild } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
|
||||||
import { NgForm } from '@angular/forms';
|
import { NgForm } from '@angular/forms';
|
||||||
|
|
||||||
import { PasswordSettingService } from '../password-setting.service';
|
import { PasswordSettingService } from '../password-setting.service';
|
||||||
@ -90,7 +89,7 @@ export class ForgotPasswordComponent {
|
|||||||
.catch(error => {
|
.catch(error => {
|
||||||
this.onGoing = false;
|
this.onGoing = false;
|
||||||
this.inlineAlert.showInlineError(error);
|
this.inlineAlert.showInlineError(error);
|
||||||
})
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, ViewChild, AfterViewChecked } from '@angular/core';
|
import { Component, ViewChild, AfterViewChecked } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
|
||||||
import { NgForm } from '@angular/forms';
|
import { NgForm } from '@angular/forms';
|
||||||
|
|
||||||
import { PasswordSettingService } from './password-setting.service';
|
import { PasswordSettingService } from './password-setting.service';
|
||||||
@ -95,7 +94,7 @@ export class PasswordSettingComponent implements AfterViewChecked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewChecked() {
|
ngAfterViewChecked() {
|
||||||
if (this.pwdFormRef != this.pwdForm) {
|
if (this.pwdFormRef !== this.pwdForm) {
|
||||||
this.pwdFormRef = this.pwdForm;
|
this.pwdFormRef = this.pwdForm;
|
||||||
if (this.pwdFormRef) {
|
if (this.pwdFormRef) {
|
||||||
this.pwdFormRef.valueChanges.subscribe(data => {
|
this.pwdFormRef.valueChanges.subscribe(data => {
|
||||||
@ -123,7 +122,7 @@ export class PasswordSettingComponent implements AfterViewChecked {
|
|||||||
this.opened = true;
|
this.opened = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Close the moal dialog
|
// Close the modal dialog
|
||||||
close(): void {
|
close(): void {
|
||||||
if (this.formValueChanged) {
|
if (this.formValueChanged) {
|
||||||
if (isEmptyForm(this.pwdForm)) {
|
if (isEmptyForm(this.pwdForm)) {
|
||||||
@ -169,7 +168,7 @@ export class PasswordSettingComponent implements AfterViewChecked {
|
|||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.onCalling = false;
|
this.onCalling = false;
|
||||||
this.opened = false
|
this.opened = false;
|
||||||
this.msgHandler.showSuccess("CHANGE_PWD.SAVE_SUCCESS");
|
this.msgHandler.showSuccess("CHANGE_PWD.SAVE_SUCCESS");
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Headers, Http, RequestOptions, URLSearchParams } from '@angular/http';
|
import { Http, URLSearchParams } from '@angular/http';
|
||||||
import 'rxjs/add/operator/toPromise';
|
import 'rxjs/add/operator/toPromise';
|
||||||
|
|
||||||
import { PasswordSetting } from './password-setting';
|
import { PasswordSetting } from './password-setting';
|
||||||
@ -51,7 +51,7 @@ export class PasswordSettingService {
|
|||||||
.then(response => response)
|
.then(response => response)
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
resetPassword(uuid: string, newPassword: string): Promise<any> {
|
resetPassword(uuid: string, newPassword: string): Promise<any> {
|
||||||
@ -59,7 +59,6 @@ export class PasswordSettingService {
|
|||||||
return Promise.reject("Invalid reset uuid or password");
|
return Promise.reject("Invalid reset uuid or password");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let body: URLSearchParams = new URLSearchParams();
|
let body: URLSearchParams = new URLSearchParams();
|
||||||
body.set("reset_uuid", uuid);
|
body.set("reset_uuid", uuid);
|
||||||
body.set("password", newPassword);
|
body.set("password", newPassword);
|
||||||
|
@ -147,7 +147,7 @@ export class ResetPasswordComponent implements OnInit {
|
|||||||
let control1 = this.resetPwdForm.controls["newPassword"];
|
let control1 = this.resetPwdForm.controls["newPassword"];
|
||||||
let control2 = this.resetPwdForm.controls["reNewPassword"];
|
let control2 = this.resetPwdForm.controls["reNewPassword"];
|
||||||
if (control1 && control2) {
|
if (control1 && control2) {
|
||||||
return control1.value == control2.value;
|
return control1.value === control2.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,12 +89,17 @@ export class SignInComponent implements AfterViewChecked, OnInit {
|
|||||||
|
|
||||||
// Make sure the updated configuration can be loaded
|
// Make sure the updated configuration can be loaded
|
||||||
this.appConfigService.load()
|
this.appConfigService.load()
|
||||||
.then(updatedConfig => this.appConfig = updatedConfig);
|
.then(updatedConfig => this.appConfig = updatedConfig)
|
||||||
|
.catch(error => {
|
||||||
|
// Catch the error
|
||||||
|
console.error("Failed to load bootstrap options with error: ", error);
|
||||||
|
});
|
||||||
|
|
||||||
this.route.queryParams
|
this.route.queryParams
|
||||||
.subscribe(params => {
|
.subscribe(params => {
|
||||||
this.redirectUrl = params["redirect_url"] || "";
|
this.redirectUrl = params["redirect_url"] || "";
|
||||||
let isSignUp = params["sign_up"] || "";
|
let isSignUp = params["sign_up"] || "";
|
||||||
if (isSignUp != "") {
|
if (isSignUp !== "") {
|
||||||
this.signUp(); // Open sign up
|
this.signUp(); // Open sign up
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -154,7 +159,7 @@ export class SignInComponent implements AfterViewChecked, OnInit {
|
|||||||
|
|
||||||
remeberMe(): void {
|
remeberMe(): void {
|
||||||
if (this.rememberMe) {
|
if (this.rememberMe) {
|
||||||
if (this.rememberedName != this.signInCredential.principal) {
|
if (this.rememberedName !== this.signInCredential.principal) {
|
||||||
// Set expire time
|
// Set expire time
|
||||||
let expires: number = expireDays * 3600 * 24 * 1000;
|
let expires: number = expireDays * 3600 * 24 * 1000;
|
||||||
let date = new Date(Date.now() + expires);
|
let date = new Date(Date.now() + expires);
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Headers, Http, URLSearchParams } from '@angular/http';
|
import { Http, URLSearchParams } from '@angular/http';
|
||||||
import 'rxjs/add/operator/toPromise';
|
import 'rxjs/add/operator/toPromise';
|
||||||
|
|
||||||
import { SignInCredential } from '../../shared/sign-in-credential';
|
import { SignInCredential } from '../../shared/sign-in-credential';
|
||||||
|
@ -11,17 +11,13 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, Output, ViewChild, OnInit } from '@angular/core';
|
import { Component, ViewChild, OnInit } from '@angular/core';
|
||||||
import { NgForm } from '@angular/forms';
|
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
import { NewUserFormComponent } from '../../shared/new-user-form/new-user-form.component';
|
import { NewUserFormComponent } from '../../shared/new-user-form/new-user-form.component';
|
||||||
import { User } from '../../user/user';
|
import { User } from '../../user/user';
|
||||||
|
|
||||||
import { UserService } from '../../user/user.service';
|
import { UserService } from '../../user/user.service';
|
||||||
import { errorHandler } from '../../shared/shared.utils';
|
|
||||||
import { AlertType } from '../../shared/shared.const';
|
import { AlertType } from '../../shared/shared.const';
|
||||||
|
|
||||||
import { MessageService } from '../../global-message/message.service';
|
import { MessageService } from '../../global-message/message.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -103,8 +99,8 @@ export class SignUpPageComponent implements OnInit {
|
|||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
this.onGoing = false;
|
this.onGoing = false;
|
||||||
this.error = error
|
this.error = error;
|
||||||
this.msgService.announceMessage(error.status | 500, "", AlertType.WARNING);
|
this.msgService.announceMessage(error.status || 500, "", AlertType.WARNING);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,16 +12,14 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, Output, ViewChild, EventEmitter } from '@angular/core';
|
import { Component, Output, ViewChild, EventEmitter } from '@angular/core';
|
||||||
import { NgForm } from '@angular/forms';
|
import { Modal } from 'clarity-angular';
|
||||||
|
|
||||||
import { NewUserFormComponent } from '../../shared/new-user-form/new-user-form.component';
|
import { NewUserFormComponent } from '../../shared/new-user-form/new-user-form.component';
|
||||||
import { User } from '../../user/user';
|
import { User } from '../../user/user';
|
||||||
|
|
||||||
import { SessionService } from '../../shared/session.service';
|
import { SessionService } from '../../shared/session.service';
|
||||||
import { UserService } from '../../user/user.service';
|
import { UserService } from '../../user/user.service';
|
||||||
import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component';
|
import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component';
|
||||||
|
|
||||||
import { Modal } from 'clarity-angular';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'sign-up',
|
selector: 'sign-up',
|
||||||
|
@ -12,13 +12,13 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Headers, Http, RequestOptions } from '@angular/http';
|
import { Http } from '@angular/http';
|
||||||
import 'rxjs/add/operator/toPromise';
|
import 'rxjs/add/operator/toPromise';
|
||||||
|
import { CookieService } from 'ngx-cookie';
|
||||||
|
|
||||||
import { AppConfig } from './app-config';
|
import { AppConfig } from './app-config';
|
||||||
import { CookieService } from 'ngx-cookie';
|
|
||||||
import { CookieKeyOfAdmiral, HarborQueryParamKey } from './shared/shared.const';
|
import { CookieKeyOfAdmiral, HarborQueryParamKey } from './shared/shared.const';
|
||||||
import {HTTP_JSON_OPTIONS, maintainUrlQueryParmas, HTTP_GET_OPTIONS} from './shared/shared.utils';
|
import { maintainUrlQueryParmas, HTTP_GET_OPTIONS} from './shared/shared.utils';
|
||||||
|
|
||||||
export const systemInfoEndpoint = "/api/systeminfo";
|
export const systemInfoEndpoint = "/api/systeminfo";
|
||||||
/**
|
/**
|
||||||
@ -51,10 +51,6 @@ export class AppConfigService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this.configurations;
|
return this.configurations;
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
//Catch the error
|
|
||||||
console.error("Failed to load bootstrap options with error: ", error);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +61,7 @@ export class AppConfigService {
|
|||||||
public isIntegrationMode(): boolean {
|
public isIntegrationMode(): boolean {
|
||||||
return this.configurations &&
|
return this.configurations &&
|
||||||
this.configurations.with_admiral &&
|
this.configurations.with_admiral &&
|
||||||
this.configurations.admiral_endpoint.trim() != "";
|
this.configurations.admiral_endpoint.trim() !== "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the reconstructed admiral url
|
// Return the reconstructed admiral url
|
||||||
@ -84,7 +80,7 @@ export class AppConfigService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save back to cookie
|
// Save back to cookie
|
||||||
this.cookie.put(CookieKeyOfAdmiral, endpoint, HTTP_JSON_OPTIONS);
|
this.cookie.put(CookieKeyOfAdmiral, endpoint);
|
||||||
this.configurations.admiral_endpoint = endpoint;
|
this.configurations.admiral_endpoint = endpoint;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,3 +6,7 @@
|
|||||||
background-image: url(../images/clarity_logo.svg);
|
background-image: url(../images/clarity_logo.svg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alert-icon-wrapper{
|
||||||
|
display: inline;
|
||||||
|
}
|
@ -11,14 +11,14 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, ReflectiveInjector, LOCALE_ID } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
import { Title } from '@angular/platform-browser';
|
||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { CookieService } from 'ngx-cookie';
|
import { CookieService } from 'ngx-cookie';
|
||||||
|
|
||||||
import { supportedLangs, enLang } from './shared/shared.const';
|
|
||||||
import { SessionService } from './shared/session.service';
|
import { SessionService } from './shared/session.service';
|
||||||
import { AppConfigService } from './app-config.service';
|
import { AppConfigService } from './app-config.service';
|
||||||
import { Title } from '@angular/platform-browser';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'harbor-app',
|
selector: 'harbor-app',
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user