Commit 1a551690 authored by System Administrator's avatar System Administrator Committed by Yogi_Wang
Browse files

promission reset


Signed-off-by: default avatarYogi_Wang <wang1084@126.com>
parent e12fd13c
......@@ -19,8 +19,8 @@ import {
ChangeDetectionStrategy,
ChangeDetectorRef
} from "@angular/core";
import { Subscription} from "rxjs";
import {forkJoin} from "rxjs";
import { Subscription } from "rxjs";
import { forkJoin } from "rxjs";
import { TranslateService } from "@ngx-translate/core";
import { Comparator } from "../service/interface";
......@@ -29,9 +29,9 @@ import { EndpointService } from "../service/endpoint.service";
import { ErrorHandler } from "../error-handler/index";
import {ConfirmationMessage} from "../confirmation-dialog/confirmation-message";
import {ConfirmationAcknowledgement} from "../confirmation-dialog/confirmation-state-message";
import {ConfirmationDialogComponent} from "../confirmation-dialog/confirmation-dialog.component";
import { ConfirmationMessage } from "../confirmation-dialog/confirmation-message";
import { ConfirmationAcknowledgement } from "../confirmation-dialog/confirmation-state-message";
import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation-dialog.component";
import {
ConfirmationTargets,
......@@ -42,8 +42,9 @@ import {
import { CreateEditEndpointComponent } from "../create-edit-endpoint/create-edit-endpoint.component";
import { toPromise, CustomComparator } from "../utils";
import {operateChanges, OperateInfo, OperationState} from "../operation/operate";
import {OperationService} from "../operation/operation.service";
import { operateChanges, OperateInfo, OperationState } from "../operation/operate";
import { OperationService } from "../operation/operation.service";
@Component({
selector: "hbr-endpoint",
......@@ -86,10 +87,10 @@ export class EndpointComponent implements OnInit, OnDestroy {
}
constructor(private endpointService: EndpointService,
private errorHandler: ErrorHandler,
private translateService: TranslateService,
private operationService: OperationService,
private ref: ChangeDetectorRef) {
private errorHandler: ErrorHandler,
private translateService: TranslateService,
private operationService: OperationService,
private ref: ChangeDetectorRef) {
this.forceRefreshView(1000);
}
......@@ -208,18 +209,18 @@ export class EndpointComponent implements OnInit, OnDestroy {
operateChanges(operMessage, OperationState.success);
});
}).catch(
error => {
if (error && error.status === 412) {
forkJoin(this.translateService.get('BATCH.DELETED_FAILURE'),
this.translateService.get('DESTINATION.FAILED_TO_DELETE_TARGET_IN_USED')).subscribe(res => {
operateChanges(operMessage, OperationState.failure, res[1]);
});
} else {
this.translateService.get('BATCH.DELETED_FAILURE').subscribe(res => {
operateChanges(operMessage, OperationState.failure, res);
});
}
});
error => {
if (error && error.status === 412) {
forkJoin(this.translateService.get('BATCH.DELETED_FAILURE'),
this.translateService.get('DESTINATION.FAILED_TO_DELETE_TARGET_IN_USED')).subscribe(res => {
operateChanges(operMessage, OperationState.failure, res[1]);
});
} else {
this.translateService.get('BATCH.DELETED_FAILURE').subscribe(res => {
operateChanges(operMessage, OperationState.failure, res);
});
}
});
}
// Forcely refresh the view
......
......@@ -29,7 +29,6 @@ import { CREATE_EDIT_LABEL_DIRECTIVES } from "./create-edit-label/index";
import { LABEL_PIECE_DIRECTIVES } from "./label-piece/index";
import { HELMCHART_DIRECTIVE } from "./helm-chart/index";
import { IMAGE_NAME_INPUT_DIRECTIVES } from "./image-name-input/index";
import {
SystemInfoService,
SystemInfoDefaultService,
......@@ -56,7 +55,9 @@ import {
HelmChartService,
HelmChartDefaultService,
RetagService,
RetagDefaultService
RetagDefaultService,
UserPermissionService,
UserPermissionDefaultService
} from './service/index';
import {
ErrorHandler,
......@@ -68,7 +69,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { TranslateServiceInitializer } from './i18n/index';
import { DEFAULT_LANG_COOKIE_KEY, DEFAULT_SUPPORTING_LANGS, DEFAULT_LANG } from './utils';
import { ChannelService } from './channel/index';
import { OperationService } from './operation/operation.service';
import { OperationService } from './operation/operation.service';
/**
* Declare default service configuration; all the endpoints will be defined in
......@@ -151,6 +152,8 @@ export interface HarborModuleConfig {
// Service implementation for helmchart
helmChartService?: Provider;
// Service implementation for userPermission
userPermissionService?: Provider;
}
/**
......@@ -248,8 +251,9 @@ export class HarborLibraryModule {
config.configService || { provide: ConfigurationService, useClass: ConfigurationDefaultService },
config.jobLogService || { provide: JobLogService, useClass: JobLogDefaultService },
config.projectPolicyService || { provide: ProjectService, useClass: ProjectDefaultService },
config.labelService || {provide: LabelService, useClass: LabelDefaultService},
config.helmChartService || {provide: HelmChartService, useClass: HelmChartDefaultService},
config.labelService || { provide: LabelService, useClass: LabelDefaultService },
config.helmChartService || { provide: HelmChartService, useClass: HelmChartDefaultService },
config.userPermissionService || { provide: UserPermissionService, useClass: UserPermissionDefaultService },
// Do initializing
TranslateServiceInitializer,
{
......@@ -281,8 +285,9 @@ export class HarborLibraryModule {
config.configService || { provide: ConfigurationService, useClass: ConfigurationDefaultService },
config.jobLogService || { provide: JobLogService, useClass: JobLogDefaultService },
config.projectPolicyService || { provide: ProjectService, useClass: ProjectDefaultService },
config.labelService || {provide: LabelService, useClass: LabelDefaultService},
config.helmChartService || {provide: HelmChartService, useClass: HelmChartDefaultService},
config.labelService || { provide: LabelService, useClass: LabelDefaultService },
config.helmChartService || { provide: HelmChartService, useClass: HelmChartDefaultService },
config.userPermissionService || { provide: UserPermissionService, useClass: UserPermissionDefaultService },
ChannelService,
OperationService
]
......
......@@ -23,14 +23,14 @@
<div *ngIf="!isCardView" class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<clr-datagrid (clrDgRefresh)="refresh()" [clrDgLoading]="loading" [(clrDgSelected)]="selectedRows">
<clr-dg-action-bar>
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!developerRoleOrAbove" (click)="onChartUpload()">
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!hasUploadHelmChartsPermission" (click)="onChartUpload()">
<clr-icon shape="upload" size="16"></clr-icon>{{'HELM_CHART.UPLOAD' | translate}}
</button>
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!hasProjectAdminRole || selectedRows.length<1"
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!hasDeleteHelmChartsPermission || selectedRows.length<1"
(click)="openChartDeleteModal(selectedRows)">
<clr-icon shape="trash" size="16"></clr-icon>{{'BUTTON.DELETE' | translate}}
</button>
<button type="button" class="btn btn-sm btn-secondary" [disabled]="selectedRows.length!==1" (click)="downloadLatestVersion()">
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!hasDownloadHelmChartsPermission ||selectedRows.length!==1" (click)="downloadLatestVersion()">
<clr-icon shape="download" size="16"></clr-icon>{{'HELM_CHART.DOWNLOAD' | translate}}
</button>
</clr-dg-action-bar>
......
......@@ -17,9 +17,11 @@ import { SystemInfo, SystemInfoService, HelmChartItem } from "../service/index";
import { ErrorHandler } from "../error-handler/error-handler";
import { toPromise, DEFAULT_PAGE_SIZE, downloadFile } from "../utils";
import { HelmChartService } from "../service/helm-chart.service";
import { DefaultHelmIcon} from "../shared/shared.const";
import { DefaultHelmIcon } from "../shared/shared.const";
import { Roles } from './../shared/shared.const';
import { OperationService } from "./../operation/operation.service";
import { UserPermissionService } from "../service/permission.service";
import { USERSTATICPERMISSION } from "../service/permission-static";
import {
OperateInfo,
OperationState,
......@@ -45,7 +47,6 @@ export class HelmChartComponent implements OnInit {
@Input() urlPrefix: string;
@Input() hasSignedIn: boolean;
@Input() projectRoleID = Roles.OTHER;
@Input() hasProjectAdminRole: boolean;
@Output() chartClickEvt = new EventEmitter<any>();
@Output() chartDownloadEve = new EventEmitter<string>();
@Input() chartDefaultIcon: string = DefaultHelmIcon;
......@@ -76,24 +77,23 @@ export class HelmChartComponent implements OnInit {
@ViewChild('chartUploadForm') uploadForm: NgForm;
@ViewChild("confirmationDialog") confirmationDialog: ConfirmationDialogComponent;
hasUploadHelmChartsPermission: boolean;
hasDownloadHelmChartsPermission: boolean;
hasDeleteHelmChartsPermission: boolean;
constructor(
private errorHandler: ErrorHandler,
private translateService: TranslateService,
private systemInfoService: SystemInfoService,
private helmChartService: HelmChartService,
private userPermissionService: UserPermissionService,
private operationService: OperationService,
private cdr: ChangeDetectorRef,
) {}
) { }
public get registryUrl(): string {
return this.systemInfo ? this.systemInfo.registry_url : "";
}
public get developerRoleOrAbove(): boolean {
return this.projectRoleID === Roles.DEVELOPER || this.hasProjectAdminRole;
}
ngOnInit(): void {
// Get system info for tag views
toPromise<SystemInfo>(this.systemInfoService.getSystemInfo())
......@@ -101,8 +101,21 @@ export class HelmChartComponent implements OnInit {
.catch(error => this.errorHandler.error(error));
this.lastFilteredChartName = "";
this.refresh();
this.getHelmPermissionRule(this.projectId);
}
getHelmPermissionRule(projectId: number): void {
let hasUploadHelmChartsPermission = this.userPermissionService.getPermission(projectId,
USERSTATICPERMISSION.HELM_CHART.KEY, USERSTATICPERMISSION.HELM_CHART.VALUE.UPLOAD);
let hasDownloadHelmChartsPermission = this.userPermissionService.getPermission(projectId,
USERSTATICPERMISSION.HELM_CHART.KEY, USERSTATICPERMISSION.HELM_CHART.VALUE.DOWNLOAD);
let hasDeleteHelmChartsPermission = this.userPermissionService.getPermission(projectId,
USERSTATICPERMISSION.HELM_CHART.KEY, USERSTATICPERMISSION.HELM_CHART.VALUE.DELETE);
forkJoin(hasUploadHelmChartsPermission, hasDownloadHelmChartsPermission, hasDeleteHelmChartsPermission).subscribe(permissions => {
this.hasUploadHelmChartsPermission = permissions[0] as boolean;
this.hasDownloadHelmChartsPermission = permissions[1] as boolean;
this.hasDeleteHelmChartsPermission = permissions[2] as boolean;
}, error => this.errorHandler.error(error));
}
updateFilterValue(value: string) {
this.lastFilteredChartName = value;
this.refresh();
......@@ -111,22 +124,22 @@ export class HelmChartComponent implements OnInit {
refresh() {
this.loading = true;
this.helmChartService
.getHelmCharts(this.projectName)
.pipe(finalize(() => {
.getHelmCharts(this.projectName)
.pipe(finalize(() => {
let hnd = setInterval(() => this.cdr.markForCheck(), 100);
setTimeout(() => clearInterval(hnd), 3000);
this.loading = false;
}))
.subscribe(
charts => {
this.charts = charts.filter(x => x.name.includes(this.lastFilteredChartName));
this.chartsCopy = charts.map(x => Object.assign({}, x));
this.totalCount = charts.length;
},
err => {
this.errorHandler.error(err);
}
);
}))
.subscribe(
charts => {
this.charts = charts.filter(x => x.name.includes(this.lastFilteredChartName));
this.chartsCopy = charts.map(x => Object.assign({}, x));
this.totalCount = charts.length;
},
err => {
this.errorHandler.error(err);
}
);
}
onChartClick(item: HelmChartItem) {
......@@ -163,10 +176,10 @@ export class HelmChartComponent implements OnInit {
this.refresh();
}))
.subscribe(() => {
this.translateService
.get("HELM_CHART.FILE_UPLOADED")
.subscribe(res => this.errorHandler.info(res));
},
this.translateService
.get("HELM_CHART.FILE_UPLOADED")
.subscribe(res => this.errorHandler.info(res));
},
err => this.errorHandler.error(err)
);
}
......@@ -192,23 +205,23 @@ export class HelmChartComponent implements OnInit {
this.operationService.publishInfo(operateMsg);
return this.helmChartService.deleteHelmChart(this.projectName, chartName)
.pipe(map(
() => operateChanges(operateMsg, OperationState.success),
err => operateChanges(operateMsg, OperationState.failure, err)
));
.pipe(map(
() => operateChanges(operateMsg, OperationState.success),
err => operateChanges(operateMsg, OperationState.failure, err)
));
}
deleteCharts(charts: HelmChartItem[]) {
if (charts && charts.length < 1) { return; }
let chartsDelete$ = charts.map(chart => this.deleteChart(chart.name));
forkJoin(chartsDelete$)
.pipe(
catchError(err => throwError(err)),
finalize(() => {
this.refresh();
this.selectedRows = [];
}))
.subscribe(() => {});
.pipe(
catchError(err => throwError(err)),
finalize(() => {
this.refresh();
this.selectedRows = [];
}))
.subscribe(() => { });
}
downloadLatestVersion(evt?: Event, item?: HelmChartItem) {
......
......@@ -38,18 +38,18 @@
<clr-datagrid (clrDgRefresh)="refresh()" [clrDgLoading]="loading" [(clrDgSelected)]="selectedRows">
<clr-dg-action-bar>
<button type="button" class="btn btn-sm btn-secondary"
[disabled]="!(selectedRows.length===1)"
[disabled]="!(selectedRows.length===1) || !hasDownloadHelmChartVersionPermission"
(click)="versionDownload()">
<clr-icon shape="download" size="16"></clr-icon>&nbsp;{{'HELM_CHART.DOWNLOAD' | translate}}
</button>
<button type="button" class="btn btn-sm btn-secondary"
[disabled]="selectedRows.length<=0 || !hasProjectAdminRole"
[disabled]="selectedRows.length<=0 || !hasDeleteHelmChartVersionPermission"
(click)="openVersionDeleteModal(selectedRows)">
<clr-icon shape="times" size="16"></clr-icon>&nbsp;{{'BUTTON.DELETE' | translate}}
</button>
<clr-dropdown>
<button type="button" class="btn btn-sm btn-secondary" clrDropdownTrigger
[disabled]="!(selectedRows.length===1 && developerRoleOrAbove)">
<button type="button" class="btn btn-sm btn-secondary" clrDropdownTrigger
[disabled]="!(selectedRows.length===1)|| !hasAddRemoveHelmChartVersionPermission">
<clr-icon shape="plus" size="16"></clr-icon>{{'REPOSITORY.ADD_LABELS' | translate}}
</button>
<clr-dropdown-menu clrPosition="bottom-left" *clrIfOpen>
......@@ -144,7 +144,7 @@
<button type="button" class="btn btn-link"
(click)="versionDownload($event, item)">{{'HELM_CHART.DOWNLOAD' | translate}}</button>
<button type="button" class="btn btn-link"
[disabled]="selectedRows.length<=0 || !hasProjectAdminRole"
[disabled]="selectedRows.length<=0 || !hasDeleteHelmChartVersionPermission"
(click)="deleteVersionCard($event, item)">{{'BUTTON.DELETE' | translate}}</button>
</clr-dropdown>
</div>
......
......@@ -26,6 +26,8 @@ import { ErrorHandler } from "./../../error-handler/error-handler";
import { toPromise, DEFAULT_PAGE_SIZE, downloadFile } from "../../utils";
import { OperationService } from "./../../operation/operation.service";
import { HelmChartService } from "./../../service/helm-chart.service";
import { UserPermissionService } from "../../service/permission.service";
import { USERSTATICPERMISSION } from "../../service/permission-static";
import { ConfirmationAcknowledgement, ConfirmationDialogComponent, ConfirmationMessage } from "./../../confirmation-dialog";
import {
OperateInfo,
......@@ -49,13 +51,11 @@ import {
})
export class ChartVersionComponent implements OnInit {
signedCon: { [key: string]: any | string[] } = {};
@Input() projectRoleID: number;
@Input() projectId: number;
@Input() projectName: string;
@Input() chartName: string;
@Input() roleName: string;
@Input() hasSignedIn: boolean;
@Input() hasProjectAdminRole: boolean;
@Input() chartDefaultIcon: string = DefaultHelmIcon;
@Output() versionClickEvt = new EventEmitter<string>();
@Output() backEvt = new EventEmitter<any>();
......@@ -85,12 +85,15 @@ export class ChartVersionComponent implements OnInit {
@ViewChild("confirmationDialog")
confirmationDialog: ConfirmationDialogComponent;
hasAddRemoveHelmChartVersionPermission: boolean;
hasDownloadHelmChartVersionPermission: boolean;
hasDeleteHelmChartVersionPermission: boolean;
constructor(
private errorHandler: ErrorHandler,
private systemInfoService: SystemInfoService,
private helmChartService: HelmChartService,
private resrouceLabelService: LabelService,
public userPermissionService: UserPermissionService,
private cdr: ChangeDetectorRef,
private operationService: OperationService,
) { }
......@@ -107,6 +110,7 @@ export class ChartVersionComponent implements OnInit {
this.refresh();
this.getLabels();
this.lastFilteredVersionName = "";
this.getHelmChartVersionPermission(this.projectId);
}
updateFilterValue(value: string) {
......@@ -326,7 +330,19 @@ export class ChartVersionComponent implements OnInit {
});
}
public get developerRoleOrAbove(): boolean {
return this.projectRoleID === Roles.DEVELOPER || this.hasProjectAdminRole;
getHelmChartVersionPermission(projectId: number): void {
let hasAddRemoveHelmChartVersionPermission = this.userPermissionService.getPermission(projectId,
USERSTATICPERMISSION.HELM_CHART_VERSION_LABEL.KEY, USERSTATICPERMISSION.HELM_CHART_VERSION_LABEL.VALUE.CREATE);
let hasDownloadHelmChartVersionPermission = this.userPermissionService.getPermission(projectId,
USERSTATICPERMISSION.HELM_CHART_VERSION.KEY, USERSTATICPERMISSION.HELM_CHART_VERSION.VALUE.READ);
let hasDeleteHelmChartVersionPermission = this.userPermissionService.getPermission(projectId,
USERSTATICPERMISSION.HELM_CHART_VERSION.KEY, USERSTATICPERMISSION.HELM_CHART_VERSION.VALUE.DELETE);
forkJoin(hasAddRemoveHelmChartVersionPermission, hasDownloadHelmChartVersionPermission, hasDeleteHelmChartVersionPermission)
.subscribe(permissions => {
this.hasAddRemoveHelmChartVersionPermission = permissions[0] as boolean;
this.hasDownloadHelmChartVersionPermission = permissions[1] as boolean;
this.hasDeleteHelmChartVersionPermission = permissions[2] as boolean;
}, error => this.errorHandler.error(error));
}
}
......@@ -11,9 +11,9 @@
</div>
</div>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 btnGroup">
<button type="button" class="btn btn-sm btn-secondary" (click)="openModal()"><clr-icon shape="plus" size="16"></clr-icon>&nbsp;{{'LABEL.NEW_LABEL' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!(selectedRow.length == 1)" (click)="editLabel(selectedRow)"><clr-icon shape="pencil" size="16"></clr-icon>&nbsp;{{'LABEL.EDIT' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!selectedRow.length" (click)="deleteLabels(selectedRow)"><clr-icon shape="times" size="16"></clr-icon>&nbsp;{{'LABEL.DELETE' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!hasCreateLabelPermission" (click)="openModal()"><clr-icon shape="plus" size="16"></clr-icon>&nbsp;{{'LABEL.NEW_LABEL' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!(selectedRow.length == 1) || !hasUpdateLabelPermission" (click)="editLabel(selectedRow)"><clr-icon shape="pencil" size="16"></clr-icon>&nbsp;{{'LABEL.EDIT' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!selectedRow.length || !hasDeleteLabelPermission" (click)="deleteLabels(selectedRow)"><clr-icon shape="times" size="16"></clr-icon>&nbsp;{{'LABEL.DELETE' | translate}}</button>
<hbr-create-edit-label [scope]="scope" [projectId]="projectId" (reload)="reload()"></hbr-create-edit-label>
</div>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 content-mt">
......
......@@ -19,22 +19,22 @@ import {
ChangeDetectorRef,
Input
} from "@angular/core";
import {Label} from "../service/interface";
import {LabelService} from "../service/label.service";
import {toPromise} from "../utils";
import {ErrorHandler} from "../error-handler/error-handler";
import {CreateEditLabelComponent} from "../create-edit-label/create-edit-label.component";
import {ConfirmationMessage} from "../confirmation-dialog/confirmation-message";
import { Label } from "../service/interface";
import { LabelService } from "../service/label.service";
import { toPromise } from "../utils";
import { ErrorHandler } from "../error-handler/error-handler";
import { CreateEditLabelComponent } from "../create-edit-label/create-edit-label.component";
import { ConfirmationMessage } from "../confirmation-dialog/confirmation-message";
import {
ConfirmationButtons,
ConfirmationState,
ConfirmationTargets
} from "../shared/shared.const";
import {ConfirmationAcknowledgement} from "../confirmation-dialog/confirmation-state-message";
import {TranslateService} from "@ngx-translate/core";
import {ConfirmationDialogComponent} from "../confirmation-dialog/confirmation-dialog.component";
import {operateChanges, OperateInfo, OperationState} from "../operation/operate";
import {OperationService} from "../operation/operation.service";
import { ConfirmationAcknowledgement } from "../confirmation-dialog/confirmation-state-message";
import { TranslateService } from "@ngx-translate/core";
import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation-dialog.component";
import { operateChanges, OperateInfo, OperationState } from "../operation/operate";
import { OperationService } from "../operation/operation.service";
@Component({
selector: "hbr-label",
......@@ -51,7 +51,9 @@ export class LabelComponent implements OnInit {
@Input() scope: string;
@Input() projectId = 0;
@Input() hasProjectAdminRole: boolean;
@Input() hasCreateLabelPermission: boolean;
@Input() hasUpdateLabelPermission: boolean;
@Input() hasDeleteLabelPermission: boolean;
@ViewChild(CreateEditLabelComponent)
createEditLabel: CreateEditLabelComponent;
......@@ -59,10 +61,10 @@ export class LabelComponent implements OnInit {
confirmationDialogComponent: ConfirmationDialogComponent;
constructor(private labelService: LabelService,
private errorHandler: ErrorHandler,
private translateService: TranslateService,
private operationService: OperationService,
private ref: ChangeDetectorRef) {
private errorHandler: ErrorHandler,
private translateService: TranslateService,
private operationService: OperationService,
private ref: ChangeDetectorRef) {
}
ngOnInit(): void {
......@@ -162,11 +164,11 @@ export class LabelComponent implements OnInit {
operateChanges(operMessage, OperationState.success);
});
}).catch(
error => {
this.translateService.get('BATCH.DELETED_FAILURE').subscribe(res => {
operateChanges(operMessage, OperationState.failure, res);
error => {
this.translateService.get('BATCH.DELETED_FAILURE').subscribe(res => {
operateChanges(operMessage, OperationState.failure, res);
});
});
});
}
// Forcely refresh the view
......@@ -183,4 +185,5 @@ export class LabelComponent implements OnInit {
}
}, duration);
}
}
<div class="list-rule">
<clr-datagrid [clrDgLoading]="loading" [(clrDgSingleSelected)]="selectedRow" (clrDgSingleSelectedChange)="selectRule($event)" [clrDgRowSelection]="true">
<clr-dg-action-bar>
<button type="button" class="btn btn-sm btn-secondary" *ngIf="isSystemAdmin" (click)="openModal()"><clr-icon shape="plus" size="16"></clr-icon>&nbsp;{{'REPLICATION.NEW_REPLICATION_RULE' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" *ngIf="isSystemAdmin" [disabled]="!selectedRow" (click)="editRule(selectedRow)"><clr-icon shape="pencil" size="16"></clr-icon>&nbsp;{{'REPLICATION.EDIT_POLICY' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" *ngIf="isSystemAdmin" [disabled]="!selectedRow" (click)="deleteRule(selectedRow)"><clr-icon shape="times" size="16"></clr-icon>&nbsp;{{'REPLICATION.DELETE_POLICY' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" *ngIf="isSystemAdmin" [disabled]="!selectedRow" (click)="replicateRule(selectedRow)"><clr-icon shape="export" size="16"></clr-icon>&nbsp;{{'REPLICATION.REPLICATE' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" *ngIf="hasCreateReplicationPermission" (click)="openModal()"><clr-icon shape="plus" size="16"></clr-icon>&nbsp;{{'REPLICATION.NEW_REPLICATION_RULE' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" *ngIf="hasUpdateReplicationPermission" [disabled]="!selectedRow" (click)="editRule(selectedRow)"><clr-icon shape="pencil" size="16"></clr-icon>&nbsp;{{'REPLICATION.EDIT_POLICY' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" *ngIf="hasDeleteReplicationPermission" [disabled]="!selectedRow" (click)="deleteRule(selectedRow)"><clr-icon shape="times" size="16"></clr-icon>&nbsp;{{'REPLICATION.DELETE_POLICY' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" *ngIf="hasExecuteReplicationPermission" [disabled]="!selectedRow" (click)="replicateRule(selectedRow)"><clr-icon shape="export" size="16"></clr-icon>&nbsp;{{'REPLICATION.REPLICATE' | translate}}</button>
</clr-dg-action-bar>
<clr-dg-column [clrDgField]="'name'">{{'REPLICATION.NAME' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'status'">{{'REPLICATION.STATUS' | translate}}</clr-dg-column>
......
......@@ -24,28 +24,29 @@ import {
SimpleChange,
SimpleChanges
} from "@angular/core";
import { forkJoin} from "rxjs";
import { forkJoin } from "rxjs";
import { Comparator } from "../service/interface";
import { TranslateService } from "@ngx-translate/core";
import {ReplicationService} from "../service/replication.service";
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 { 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 {operateChanges, OperateInfo, OperationState} from "../operation/operate";
import {OperationService} from "../operation/operation.service";
import { ErrorHandler } from "../error-handler/error-handler";
import { toPromise, CustomComparator } from "../utils";
import { operateChanges, OperateInfo, OperationState } from "../operation/operate";
import { OperationService } from "../operation/operation.service";
@Component({
......@@ -58,12 +59,14 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
nullTime = "0001-01-01T00:00:00Z";
@Input()