mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-03 06:28:06 +01:00
Fix issues about confirm buttons and date validation.
This commit is contained in:
parent
35489e40ff
commit
adee392c3c
@ -22,8 +22,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</clr-dropdown>
|
</clr-dropdown>
|
||||||
<div class="flex-xs-middle">
|
<div class="flex-xs-middle">
|
||||||
<clr-icon shape="date"></clr-icon><input type="date" #fromTime (change)="doSearchByTimeRange(fromTime.value, 'begin')">
|
<clr-icon shape="date"></clr-icon>
|
||||||
<clr-icon shape="date"></clr-icon><input type="date" #toTime (change)="doSearchByTimeRange(toTime.value, 'end')">
|
<label for="fromDateInput" aria-haspopup="true" role="tooltip" [class.invalid]="fromTime.errors && fromTime.errors.dateValidator && (fromTime.dirty || fromTime.touched)" [class.valid]="fromTime.valid" class="tooltip tooltip-validation invalid tooltip-sm">
|
||||||
|
<input id="fromDateInput" type="date" #fromTime="ngModel" name="from" [(ngModel)]="queryParam.fromTime" dateValidator placeholder="dd/mm/yyyy" (change)="doSearchByStartTime(!(fromTime.errors && fromTime.errors.dateValidator), fromTime.value)">
|
||||||
|
<span *ngIf="fromTime.errors && fromTime.errors.dateValidator && (fromTime.dirty || fromTime.touched)" class="tooltip-content">
|
||||||
|
{{'AUDIT_LOG.INVALID_DATE' | translate }}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<clr-icon shape="date"></clr-icon>
|
||||||
|
<label for="toDateInput" aria-haspopup="true" role="tooltip" [class.invalid]="toTime.errors && toTime.errors.dateValidator && (toTime.dirty || toTime.touched)" [class.valid]="toTime.valid" class="tooltip tooltip-validation invalid tooltip-sm">
|
||||||
|
<input id="toDateInput" type="date" #toTime="ngModel" name="to" [(ngModel)]="queryParam.toTime" dateValidator placeholder="dd/mm/yyyy" (change)="doSearchByEndTime(!(toTime.errors && toTime.errors.dateValidator),toTime.value)">
|
||||||
|
<span *ngIf="toTime.errors && toTime.errors.dateValidator && (toTime.dirty || toTime.touched)" class="tooltip-content">
|
||||||
|
{{'AUDIT_LOG.INVALID_DATE' | translate }}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -105,15 +105,29 @@ export class AuditLogComponent implements OnInit {
|
|||||||
this.retrieve();
|
this.retrieve();
|
||||||
}
|
}
|
||||||
|
|
||||||
doSearchByTimeRange(strDate: string, target: string): void {
|
convertDate(strDate: string): string {
|
||||||
let oneDayOffset = 3600 * 24;
|
if(/^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/.test(strDate)) {
|
||||||
switch(target) {
|
let parts = strDate.split(/[-\/]/);
|
||||||
case 'begin':
|
strDate = parts[2] /*Year*/ + '-' +parts[1] /*Month*/ + '-' + parts[0] /*Date*/;
|
||||||
|
}
|
||||||
|
return strDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
doSearchByStartTime(valid: boolean, strDate: string): void {
|
||||||
|
this.queryParam.begin_timestamp = 0;
|
||||||
|
if(valid && strDate){
|
||||||
|
strDate = this.convertDate(strDate);
|
||||||
this.queryParam.begin_timestamp = new Date(strDate).getTime() / 1000;
|
this.queryParam.begin_timestamp = new Date(strDate).getTime() / 1000;
|
||||||
break;
|
}
|
||||||
case 'end':
|
this.retrieve();
|
||||||
|
}
|
||||||
|
|
||||||
|
doSearchByEndTime(valid: boolean, strDate: string): void {
|
||||||
|
this.queryParam.end_timestamp = 0;
|
||||||
|
if(valid && strDate) {
|
||||||
|
strDate = this.convertDate(strDate);
|
||||||
|
let oneDayOffset = 3600 * 24;
|
||||||
this.queryParam.end_timestamp = new Date(strDate).getTime() / 1000 + oneDayOffset;
|
this.queryParam.end_timestamp = new Date(strDate).getTime() / 1000 + oneDayOffset;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
this.retrieve();
|
this.retrieve();
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,8 @@ import { RecentLogComponent } from './recent-log.component';
|
|||||||
imports: [SharedModule],
|
imports: [SharedModule],
|
||||||
declarations: [
|
declarations: [
|
||||||
AuditLogComponent,
|
AuditLogComponent,
|
||||||
RecentLogComponent],
|
RecentLogComponent
|
||||||
|
],
|
||||||
providers: [AuditLogService],
|
providers: [AuditLogService],
|
||||||
exports: [
|
exports: [
|
||||||
AuditLogComponent,
|
AuditLogComponent,
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" style="padding-left: 135px;">
|
<div class="form-group" style="padding-left: 135px;">
|
||||||
<label class="col-md-3 form-group-label-override">{{'PROJECT.PUBLIC_OR_PRIVATE' | translate}}</label>
|
<label class="col-md-3 form-group-label-override">{{'PROJECT.ACCESS_LEVEL' | translate}}</label>
|
||||||
<div class="checkbox-inline">
|
<div class="checkbox-inline">
|
||||||
<input type="checkbox" id="create_project_public" [(ngModel)]="project.public" name="public">
|
<input type="checkbox" id="create_project_public" [(ngModel)]="project.public" name="public">
|
||||||
<label for="create_project_public"></label>
|
<label for="create_project_public"></label>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<clr-datagrid (clrDgRefresh)="refresh($event)">
|
<clr-datagrid (clrDgRefresh)="refresh($event)">
|
||||||
<clr-dg-column>{{'PROJECT.NAME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'PROJECT.NAME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'PROJECT.PUBLIC_OR_PRIVATE' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'PROJECT.ACCESS_LEVEL' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column *ngIf="showRoleInfo">{{'PROJECT.ROLE' | translate}}</clr-dg-column>
|
<clr-dg-column *ngIf="showRoleInfo">{{'PROJECT.ROLE' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'PROJECT.REPO_COUNT'| translate}}</clr-dg-column>
|
<clr-dg-column>{{'PROJECT.REPO_COUNT'| translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'PROJECT.CREATION_TIME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'PROJECT.CREATION_TIME' | translate}}</clr-dg-column>
|
||||||
|
@ -22,7 +22,7 @@ import { MemberService } from './member.service';
|
|||||||
import { AddMemberComponent } from './add-member/add-member.component';
|
import { AddMemberComponent } from './add-member/add-member.component';
|
||||||
|
|
||||||
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
|
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
|
||||||
import { ConfirmationTargets, ConfirmationState } from '../../shared/shared.const';
|
import { ConfirmationTargets, ConfirmationState, ConfirmationButtons } from '../../shared/shared.const';
|
||||||
|
|
||||||
import { ConfirmationDialogService } from '../../shared/confirmation-dialog/confirmation-dialog.service';
|
import { ConfirmationDialogService } from '../../shared/confirmation-dialog/confirmation-dialog.service';
|
||||||
import { ConfirmationMessage } from '../../shared/confirmation-dialog/confirmation-message';
|
import { ConfirmationMessage } from '../../shared/confirmation-dialog/confirmation-message';
|
||||||
@ -149,7 +149,8 @@ export class MemberComponent implements OnInit, OnDestroy {
|
|||||||
'MEMBER.DELETION_SUMMARY',
|
'MEMBER.DELETION_SUMMARY',
|
||||||
m.username,
|
m.username,
|
||||||
m.user_id,
|
m.user_id,
|
||||||
ConfirmationTargets.PROJECT_MEMBER
|
ConfirmationTargets.PROJECT_MEMBER,
|
||||||
|
ConfirmationButtons.DELETE_CANCEL
|
||||||
);
|
);
|
||||||
this.deletionDialogService.openComfirmDialog(deletionMessage);
|
this.deletionDialogService.openComfirmDialog(deletionMessage);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ import { Response } from '@angular/http';
|
|||||||
|
|
||||||
import { ConfirmationDialogService } from '../shared/confirmation-dialog/confirmation-dialog.service';
|
import { ConfirmationDialogService } from '../shared/confirmation-dialog/confirmation-dialog.service';
|
||||||
import { ConfirmationMessage } from '../shared/confirmation-dialog/confirmation-message';
|
import { ConfirmationMessage } from '../shared/confirmation-dialog/confirmation-message';
|
||||||
import { ConfirmationTargets, ConfirmationState } from '../shared/shared.const';
|
import { ConfirmationTargets, ConfirmationState, ConfirmationButtons } from '../shared/shared.const';
|
||||||
|
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
|
||||||
@ -178,7 +178,8 @@ export class ProjectComponent implements OnInit, OnDestroy {
|
|||||||
'PROJECT.DELETION_SUMMARY',
|
'PROJECT.DELETION_SUMMARY',
|
||||||
p.name,
|
p.name,
|
||||||
p.project_id,
|
p.project_id,
|
||||||
ConfirmationTargets.PROJECT
|
ConfirmationTargets.PROJECT,
|
||||||
|
ConfirmationButtons.DELETE_CANCEL
|
||||||
);
|
);
|
||||||
this.deletionDialogService.openComfirmDialog(deletionMessage);
|
this.deletionDialogService.openComfirmDialog(deletionMessage);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import { MessageHandlerService } from '../../shared/message-handler/message-hand
|
|||||||
import { ConfirmationDialogService } from '../../shared/confirmation-dialog/confirmation-dialog.service';
|
import { ConfirmationDialogService } from '../../shared/confirmation-dialog/confirmation-dialog.service';
|
||||||
import { ConfirmationMessage } from '../../shared/confirmation-dialog/confirmation-message';
|
import { ConfirmationMessage } from '../../shared/confirmation-dialog/confirmation-message';
|
||||||
|
|
||||||
import { ConfirmationTargets, ConfirmationState } from '../../shared/shared.const';
|
import { ConfirmationTargets, ConfirmationState, ConfirmationButtons } from '../../shared/shared.const';
|
||||||
|
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
|
||||||
@ -149,7 +149,8 @@ export class DestinationComponent implements OnInit {
|
|||||||
'REPLICATION.DELETION_SUMMARY_TARGET',
|
'REPLICATION.DELETION_SUMMARY_TARGET',
|
||||||
target.name,
|
target.name,
|
||||||
target.id,
|
target.id,
|
||||||
ConfirmationTargets.TARGET);
|
ConfirmationTargets.TARGET,
|
||||||
|
ConfirmationButtons.DELETE_CANCEL);
|
||||||
this.deletionDialogService.openComfirmDialog(deletionMessage);
|
this.deletionDialogService.openComfirmDialog(deletionMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,20 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-items-xs-middle">
|
<div class="flex-items-xs-middle">
|
||||||
<clr-icon shape="date"></clr-icon><input type="date" #fromTime (change)="doJobSearchByStartTime(fromTime.value)">
|
<clr-icon shape="date"></clr-icon>
|
||||||
<clr-icon shape="date"></clr-icon><input type="date" #toTime (change)="doJobSearchByEndTime(toTime.value)">
|
<label for="fromDateInput" aria-haspopup="true" role="tooltip" [class.invalid]="fromTime.errors && fromTime.errors.dateValidator && (fromTime.dirty || fromTime.touched)" [class.valid]="fromTime.valid" class="tooltip tooltip-validation invalid tooltip-sm">
|
||||||
|
<input id="fromDateInput" type="date" #fromTime="ngModel" name="from" [(ngModel)]="currentJobSearchOption.fromTime" dateValidator placeholder="dd/mm/yyyy" (change)="doJobSearchByStartTime(!(fromTime.errors && fromTime.errors.dateValidator), fromTime.value)">
|
||||||
|
<span *ngIf="fromTime.errors && fromTime.errors.dateValidator && (fromTime.dirty || fromTime.touched)" class="tooltip-content">
|
||||||
|
{{'AUDIT_LOG.INVALID_DATE' | translate }}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<clr-icon shape="date"></clr-icon>
|
||||||
|
<label for="toDateInput" aria-haspopup="true" role="tooltip" [class.invalid]="toTime.errors && toTime.errors.dateValidator && (toTime.dirty || toTime.touched)" [class.valid]="toTime.valid" class="tooltip tooltip-validation invalid tooltip-sm">
|
||||||
|
<input id="toDateInput" type="date" #toTime="ngModel" name="to" [(ngModel)]="currentJobSearchOption.toTime" dateValidator placeholder="dd/mm/yyyy" (change)="doJobSearchByEndTime(!(toTime.errors && toTime.errors.dateValidator),toTime.value)">
|
||||||
|
<span *ngIf="toTime.errors && toTime.errors.dateValidator && (toTime.dirty || toTime.touched)" class="tooltip-content">
|
||||||
|
{{'AUDIT_LOG.INVALID_DATE' | translate }}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -232,20 +232,31 @@ export class ReplicationComponent implements OnInit {
|
|||||||
(option === 1) ? this.currentJobSearchOption = 0 : this.currentJobSearchOption = 1;
|
(option === 1) ? this.currentJobSearchOption = 0 : this.currentJobSearchOption = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
doJobSearchByStartTime(strDate: string) {
|
convertDate(strDate: string): string {
|
||||||
if(!strDate || strDate.trim() === '') {
|
if(/^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/.test(strDate)) {
|
||||||
strDate = 0 + '';
|
let parts = strDate.split(/[-\/]/);
|
||||||
}
|
strDate = parts[2] /*Year*/ + '-' +parts[1] /*Month*/ + '-' + parts[0] /*Date*/;
|
||||||
(strDate === '0') ? this.search.startTime = '' : this.search.startTime = (new Date(strDate).getTime() / 1000) + '';
|
}
|
||||||
|
return strDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
doJobSearchByStartTime(valid: boolean, strDate: string) {
|
||||||
|
this.search.startTime = '';
|
||||||
|
if(valid && strDate) {
|
||||||
|
strDate = this.convertDate(strDate);
|
||||||
|
console.log(strDate);
|
||||||
|
this.search.startTime = (new Date(strDate).getTime() / 1000) + '';
|
||||||
|
}
|
||||||
this.fetchPolicyJobs();
|
this.fetchPolicyJobs();
|
||||||
}
|
}
|
||||||
|
|
||||||
doJobSearchByEndTime(strDate: string) {
|
doJobSearchByEndTime(valid: boolean, strDate: string) {
|
||||||
if(!strDate || strDate.trim() === '') {
|
this.search.endTime = '';
|
||||||
strDate = 0 + '';
|
if(valid && strDate) {
|
||||||
|
strDate = this.convertDate(strDate);
|
||||||
|
let oneDayOffset = 3600 * 24;
|
||||||
|
this.search.endTime = (new Date(strDate).getTime() / 1000 + oneDayOffset) + '';
|
||||||
}
|
}
|
||||||
let oneDayOffset = 3600 * 24;
|
|
||||||
(strDate === '0') ? this.search.endTime = '' : this.search.endTime = (new Date(strDate).getTime() / 1000 + oneDayOffset) + '';
|
|
||||||
this.fetchPolicyJobs();
|
this.fetchPolicyJobs();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,7 +18,7 @@ import { RepositoryService } from './repository.service';
|
|||||||
import { Repository } from './repository';
|
import { Repository } from './repository';
|
||||||
|
|
||||||
import { MessageHandlerService } from '../shared/message-handler/message-handler.service';
|
import { MessageHandlerService } from '../shared/message-handler/message-handler.service';
|
||||||
import { ConfirmationState, ConfirmationTargets } from '../shared/shared.const';
|
import { ConfirmationState, ConfirmationTargets, ConfirmationButtons } from '../shared/shared.const';
|
||||||
|
|
||||||
|
|
||||||
import { ConfirmationDialogService } from '../shared/confirmation-dialog/confirmation-dialog.service';
|
import { ConfirmationDialogService } from '../shared/confirmation-dialog/confirmation-dialog.service';
|
||||||
@ -115,7 +115,8 @@ export class RepositoryComponent implements OnInit {
|
|||||||
'REPOSITORY.DELETION_SUMMARY_REPO',
|
'REPOSITORY.DELETION_SUMMARY_REPO',
|
||||||
repoName,
|
repoName,
|
||||||
repoName,
|
repoName,
|
||||||
ConfirmationTargets.REPOSITORY);
|
ConfirmationTargets.REPOSITORY,
|
||||||
|
ConfirmationButtons.DELETE_CANCEL);
|
||||||
this.deletionDialogService.openComfirmDialog(message);
|
this.deletionDialogService.openComfirmDialog(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import { ActivatedRoute } from '@angular/router';
|
|||||||
|
|
||||||
import { RepositoryService } from '../repository.service';
|
import { RepositoryService } from '../repository.service';
|
||||||
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
|
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
|
||||||
import { ConfirmationTargets, ConfirmationState } from '../../shared/shared.const';
|
import { ConfirmationTargets, ConfirmationState, ConfirmationButtons } from '../../shared/shared.const';
|
||||||
|
|
||||||
import { ConfirmationDialogService } from '../../shared/confirmation-dialog/confirmation-dialog.service';
|
import { ConfirmationDialogService } from '../../shared/confirmation-dialog/confirmation-dialog.service';
|
||||||
import { ConfirmationMessage } from '../../shared/confirmation-dialog/confirmation-message';
|
import { ConfirmationMessage } from '../../shared/confirmation-dialog/confirmation-message';
|
||||||
@ -155,25 +155,25 @@ export class TagRepositoryComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
deleteTag(tag: TagView) {
|
deleteTag(tag: TagView) {
|
||||||
if (tag) {
|
if (tag) {
|
||||||
let titleKey: string, summaryKey: string, content: string, confirmOnly: boolean;
|
let titleKey: string, summaryKey: string, content: string, buttons: ConfirmationButtons;
|
||||||
if (tag.signed) {
|
if (tag.signed) {
|
||||||
titleKey = 'REPOSITORY.DELETION_TITLE_TAG_DENIED';
|
titleKey = 'REPOSITORY.DELETION_TITLE_TAG_DENIED';
|
||||||
summaryKey = 'REPOSITORY.DELETION_SUMMARY_TAG_DENIED';
|
summaryKey = 'REPOSITORY.DELETION_SUMMARY_TAG_DENIED';
|
||||||
confirmOnly = true;
|
buttons = ConfirmationButtons.CLOSE;
|
||||||
content = 'notary -s https://' + this.registryUrl + ':4443 -d ~/.docker/trust remove -p ' + this.registryUrl + '/' + this.repoName + ' ' + tag.tag;
|
content = 'notary -s https://' + this.registryUrl + ':4443 -d ~/.docker/trust remove -p ' + this.registryUrl + '/' + this.repoName + ' ' + tag.tag;
|
||||||
} else {
|
} else {
|
||||||
titleKey = 'REPOSITORY.DELETION_TITLE_TAG';
|
titleKey = 'REPOSITORY.DELETION_TITLE_TAG';
|
||||||
summaryKey = 'REPOSITORY.DELETION_SUMMARY_TAG';
|
summaryKey = 'REPOSITORY.DELETION_SUMMARY_TAG';
|
||||||
|
buttons = ConfirmationButtons.DELETE_CANCEL;
|
||||||
content = tag.tag;
|
content = tag.tag;
|
||||||
confirmOnly = false;
|
|
||||||
}
|
}
|
||||||
let message = new ConfirmationMessage(
|
let message = new ConfirmationMessage(
|
||||||
titleKey,
|
titleKey,
|
||||||
summaryKey,
|
summaryKey,
|
||||||
content,
|
content,
|
||||||
tag,
|
tag,
|
||||||
ConfirmationTargets.TAG);
|
ConfirmationTargets.TAG,
|
||||||
message.confirmOnly = confirmOnly;
|
buttons);
|
||||||
this.deletionDialogService.openComfirmDialog(message);
|
this.deletionDialogService.openComfirmDialog(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,21 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="confirmation-content">{{dialogContent}}</div>
|
<div class="confirmation-content">{{dialogContent}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer" [ngSwitch]="buttons">
|
||||||
<button type="button" class="btn btn-outline" *ngIf="!confirmOnly" (click)="cancel()">{{'BUTTON.NO' | translate}}</button>
|
<ng-template [ngSwitchCase]="0">
|
||||||
<button type="button" class="btn btn-primary" (click)="confirm()">{{ buttonKey | translate}}</button>
|
<button type="button" class="btn btn-outline" (click)="cancel()">{{'BUTTON.CANCEL' | translate}}</button>
|
||||||
|
<button type="button" class="btn btn-primary" (click)="confirm()">{{ 'BUTTON.CONFIRM' | translate}}</button>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template [ngSwitchCase]="1">
|
||||||
|
<button type="button" class="btn btn-outline" (click)="cancel()">{{'BUTTON.NO' | translate}}</button>
|
||||||
|
<button type="button" class="btn btn-primary" (click)="confirm()">{{ 'BUTTON.YES' | translate}}</button>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template [ngSwitchCase]="2">
|
||||||
|
<button type="button" class="btn btn-outline" (click)="cancel()">{{'BUTTON.CANCEL' | translate}}</button>
|
||||||
|
<button type="button" class="btn btn-danger" (click)="confirm()">{{ 'BUTTON.DELETE' | translate}}</button>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template [ngSwitchCase]="3">
|
||||||
|
<button type="button" class="btn btn-primary" (click)="cancel()">{{'BUTTON.CLOSE' | translate}}</button>
|
||||||
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
</clr-modal>
|
</clr-modal>
|
@ -18,7 +18,7 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
import { ConfirmationDialogService } from './confirmation-dialog.service';
|
import { ConfirmationDialogService } from './confirmation-dialog.service';
|
||||||
import { ConfirmationMessage } from './confirmation-message';
|
import { ConfirmationMessage } from './confirmation-message';
|
||||||
import { ConfirmationAcknowledgement } from './confirmation-state-message';
|
import { ConfirmationAcknowledgement } from './confirmation-state-message';
|
||||||
import { ConfirmationState, ConfirmationTargets } from '../shared.const';
|
import { ConfirmationState, ConfirmationTargets, ConfirmationButtons } from '../shared.const';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'confiramtion-dialog',
|
selector: 'confiramtion-dialog',
|
||||||
@ -30,10 +30,9 @@ export class ConfirmationDialogComponent implements OnDestroy {
|
|||||||
opened: boolean = false;
|
opened: boolean = false;
|
||||||
dialogTitle: string = "";
|
dialogTitle: string = "";
|
||||||
dialogContent: string = "";
|
dialogContent: string = "";
|
||||||
buttonKey: string = 'BUTTON.OK';
|
|
||||||
confirmOnly: boolean = false;
|
|
||||||
message: ConfirmationMessage;
|
message: ConfirmationMessage;
|
||||||
annouceSubscription: Subscription;
|
annouceSubscription: Subscription;
|
||||||
|
buttons: ConfirmationButtons;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private confirmationService: ConfirmationDialogService,
|
private confirmationService: ConfirmationDialogService,
|
||||||
@ -42,11 +41,10 @@ export class ConfirmationDialogComponent implements OnDestroy {
|
|||||||
this.dialogTitle = msg.title;
|
this.dialogTitle = msg.title;
|
||||||
this.dialogContent = msg.message;
|
this.dialogContent = msg.message;
|
||||||
this.message = msg;
|
this.message = msg;
|
||||||
this.confirmOnly = this.message.confirmOnly;
|
|
||||||
this.buttonKey = this.confirmOnly ? 'BUTTON.CLOSE' : 'BUTTON.OK';
|
|
||||||
this.translate.get(this.dialogTitle).subscribe((res: string) => this.dialogTitle = res);
|
this.translate.get(this.dialogTitle).subscribe((res: string) => this.dialogTitle = res);
|
||||||
this.translate.get(this.dialogContent, { 'param': msg.param }).subscribe((res: string) => this.dialogContent = res);
|
this.translate.get(this.dialogContent, { 'param': msg.param }).subscribe((res: string) => this.dialogContent = res);
|
||||||
//Open dialog
|
//Open dialog
|
||||||
|
this.buttons = msg.buttons;
|
||||||
this.open();
|
this.open();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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 { ConfirmationTargets } 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) {
|
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;
|
||||||
this.targetId = targetId;
|
this.targetId = targetId;
|
||||||
this.param = param;
|
this.param = param;
|
||||||
|
this.buttons = buttons ? buttons : ConfirmationButtons.CONFIRM_CANCEL;
|
||||||
}
|
}
|
||||||
title: string;
|
title: string;
|
||||||
message: string;
|
message: string;
|
||||||
data: any = {};//default is empty
|
data: any = {};//default is empty
|
||||||
targetId: ConfirmationTargets = ConfirmationTargets.EMPTY;
|
targetId: ConfirmationTargets = ConfirmationTargets.EMPTY;
|
||||||
param: string;
|
param: string;
|
||||||
confirmOnly: boolean;
|
buttons: ConfirmationButtons;
|
||||||
}
|
}
|
50
src/ui_ng/src/app/shared/date-validator.directive.ts
Normal file
50
src/ui_ng/src/app/shared/date-validator.directive.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
import { Directive, OnChanges, Input, SimpleChanges } from '@angular/core';
|
||||||
|
import { NG_VALIDATORS, Validator, Validators, ValidatorFn, AbstractControl } from '@angular/forms';
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[dateValidator]',
|
||||||
|
providers: [{provide: NG_VALIDATORS, useExisting: DateValidatorDirective, multi: true}]
|
||||||
|
})
|
||||||
|
export class DateValidatorDirective implements Validator, OnChanges {
|
||||||
|
@Input() dateValidator: string;
|
||||||
|
private valFn = Validators.nullValidator;
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
|
const change = changes['dateValidator'];
|
||||||
|
if (change) {
|
||||||
|
this.valFn = dateValidator();
|
||||||
|
} else {
|
||||||
|
this.valFn = Validators.nullValidator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
validate(control: AbstractControl): {[key: string]: any} {
|
||||||
|
return this.valFn(control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dateValidator(): ValidatorFn {
|
||||||
|
return (control: AbstractControl): {[key: string]: any} => {
|
||||||
|
let controlValue = control.value;
|
||||||
|
let valid = true;
|
||||||
|
if(controlValue) {
|
||||||
|
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;
|
||||||
|
valid = (regYMD.test(controlValue) || regDMY.test(controlValue));
|
||||||
|
}
|
||||||
|
return valid ? null : {'dateValidator': { value: controlValue }};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ import { Policy } from '../../replication/policy';
|
|||||||
import { ConfirmationDialogService } from '../../shared/confirmation-dialog/confirmation-dialog.service';
|
import { ConfirmationDialogService } from '../../shared/confirmation-dialog/confirmation-dialog.service';
|
||||||
import { ConfirmationMessage } from '../../shared/confirmation-dialog/confirmation-message';
|
import { ConfirmationMessage } from '../../shared/confirmation-dialog/confirmation-message';
|
||||||
|
|
||||||
import { ConfirmationState, ConfirmationTargets } from '../../shared/shared.const';
|
import { ConfirmationState, ConfirmationTargets, ConfirmationButtons } from '../../shared/shared.const';
|
||||||
|
|
||||||
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
|
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
|
||||||
|
|
||||||
@ -135,7 +135,8 @@ export class ListPolicyComponent implements OnDestroy {
|
|||||||
'REPLICATION.DELETION_SUMMARY',
|
'REPLICATION.DELETION_SUMMARY',
|
||||||
policy.name,
|
policy.name,
|
||||||
policy.id,
|
policy.id,
|
||||||
ConfirmationTargets.POLICY);
|
ConfirmationTargets.POLICY,
|
||||||
|
ConfirmationButtons.DELETE_CANCEL);
|
||||||
this.deletionDialogService.openComfirmDialog(deletionMessage);
|
this.deletionDialogService.openComfirmDialog(deletionMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<clr-datagrid (clrDgRefresh)="refresh($event)">
|
<clr-datagrid (clrDgRefresh)="refresh($event)">
|
||||||
<clr-dg-column>{{'PROJECT.NAME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'PROJECT.NAME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'PROJECT.PUBLIC_OR_PRIVATE' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'PROJECT.ACCESS_LEVEL' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'PROJECT.REPO_COUNT'| translate}}</clr-dg-column>
|
<clr-dg-column>{{'PROJECT.REPO_COUNT'| translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'PROJECT.CREATION_TIME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'PROJECT.CREATION_TIME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-row *clrDgItems="let p of projects" [clrDgItem]="p">
|
<clr-dg-row *clrDgItems="let p of projects" [clrDgItem]="p">
|
||||||
|
@ -67,6 +67,9 @@ export const CookieKeyOfAdmiral = "admiral.endpoint.latest";
|
|||||||
export const enum ConfirmationState {
|
export const enum ConfirmationState {
|
||||||
NA, CONFIRMED, CANCEL
|
NA, CONFIRMED, CANCEL
|
||||||
}
|
}
|
||||||
|
export const enum ConfirmationButtons {
|
||||||
|
CONFIRM_CANCEL, YES_NO, DELETE_CANCEL, CLOSE
|
||||||
|
}
|
||||||
|
|
||||||
export const ProjectTypes = { 0: 'PROJECT.MY_PROJECTS', 1: 'PROJECT.PUBLIC_PROJECTS' };
|
export const ProjectTypes = { 0: 'PROJECT.MY_PROJECTS', 1: 'PROJECT.PUBLIC_PROJECTS' };
|
||||||
export const RoleInfo = { 1: 'MEMBER.PROJECT_ADMIN', 2: 'MEMBER.DEVELOPER', 3: 'MEMBER.GUEST' };
|
export const RoleInfo = { 1: 'MEMBER.PROJECT_ADMIN', 2: 'MEMBER.DEVELOPER', 3: 'MEMBER.GUEST' };
|
||||||
|
@ -54,6 +54,7 @@ import { MessageHandlerService } from './message-handler/message-handler.service
|
|||||||
import { EmailValidatorDirective } from './email.directive';
|
import { EmailValidatorDirective } from './email.directive';
|
||||||
import { GaugeComponent } from './gauge/gauge.component';
|
import { GaugeComponent } from './gauge/gauge.component';
|
||||||
import { StatisticHandler } from './statictics/statistic-handler.service';
|
import { StatisticHandler } from './statictics/statistic-handler.service';
|
||||||
|
import { DateValidatorDirective } from '../shared/date-validator.directive';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -78,7 +79,8 @@ import { StatisticHandler } from './statictics/statistic-handler.service';
|
|||||||
ListProjectROComponent,
|
ListProjectROComponent,
|
||||||
ListRepositoryROComponent,
|
ListRepositoryROComponent,
|
||||||
EmailValidatorDirective,
|
EmailValidatorDirective,
|
||||||
GaugeComponent
|
GaugeComponent,
|
||||||
|
DateValidatorDirective
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
CoreModule,
|
CoreModule,
|
||||||
@ -99,7 +101,8 @@ import { StatisticHandler } from './statictics/statistic-handler.service';
|
|||||||
ListProjectROComponent,
|
ListProjectROComponent,
|
||||||
ListRepositoryROComponent,
|
ListRepositoryROComponent,
|
||||||
EmailValidatorDirective,
|
EmailValidatorDirective,
|
||||||
GaugeComponent
|
GaugeComponent,
|
||||||
|
DateValidatorDirective
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
SessionService,
|
SessionService,
|
||||||
|
@ -21,7 +21,7 @@ import { NewUserModalComponent } from './new-user-modal.component';
|
|||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { ConfirmationDialogService } from '../shared/confirmation-dialog/confirmation-dialog.service';
|
import { ConfirmationDialogService } from '../shared/confirmation-dialog/confirmation-dialog.service';
|
||||||
import { ConfirmationMessage } from '../shared/confirmation-dialog/confirmation-message';
|
import { ConfirmationMessage } from '../shared/confirmation-dialog/confirmation-message';
|
||||||
import { ConfirmationState, ConfirmationTargets } from '../shared/shared.const'
|
import { ConfirmationState, ConfirmationTargets, ConfirmationButtons } from '../shared/shared.const'
|
||||||
import { MessageHandlerService } from '../shared/message-handler/message-handler.service';
|
import { MessageHandlerService } from '../shared/message-handler/message-handler.service';
|
||||||
|
|
||||||
import { SessionService } from '../shared/session.service';
|
import { SessionService } from '../shared/session.service';
|
||||||
@ -188,7 +188,8 @@ export class UserComponent implements OnInit, OnDestroy {
|
|||||||
"USER.DELETION_SUMMARY",
|
"USER.DELETION_SUMMARY",
|
||||||
user.username,
|
user.username,
|
||||||
user,
|
user,
|
||||||
ConfirmationTargets.USER
|
ConfirmationTargets.USER,
|
||||||
|
ConfirmationButtons.DELETE_CANCEL
|
||||||
);
|
);
|
||||||
this.deletionDialogService.openComfirmDialog(msg);
|
this.deletionDialogService.openComfirmDialog(msg);
|
||||||
}
|
}
|
||||||
|
@ -124,6 +124,7 @@
|
|||||||
"NAME": "Project Name",
|
"NAME": "Project Name",
|
||||||
"ROLE": "Role",
|
"ROLE": "Role",
|
||||||
"PUBLIC_OR_PRIVATE": "Public",
|
"PUBLIC_OR_PRIVATE": "Public",
|
||||||
|
"ACCESS_LEVEL": "Access Level",
|
||||||
"REPO_COUNT": "Repositories Count",
|
"REPO_COUNT": "Repositories Count",
|
||||||
"CREATION_TIME": "Creation Time",
|
"CREATION_TIME": "Creation Time",
|
||||||
"PUBLIC": "Public",
|
"PUBLIC": "Public",
|
||||||
@ -197,7 +198,8 @@
|
|||||||
"ADVANCED": "Advanced",
|
"ADVANCED": "Advanced",
|
||||||
"SIMPLE": "Simple",
|
"SIMPLE": "Simple",
|
||||||
"ITEMS": "item(s)",
|
"ITEMS": "item(s)",
|
||||||
"FILTER_PLACEHOLDER": "Filter Logs"
|
"FILTER_PLACEHOLDER": "Filter Logs",
|
||||||
|
"INVALID_DATE": "Invalid date."
|
||||||
},
|
},
|
||||||
"REPLICATION": {
|
"REPLICATION": {
|
||||||
"REPLICATION_RULE": "Replication Rule",
|
"REPLICATION_RULE": "Replication Rule",
|
||||||
@ -265,7 +267,8 @@
|
|||||||
"CANNOT_EDIT": "Replication rule cannot be changed while it is enabled.",
|
"CANNOT_EDIT": "Replication rule cannot be changed while it is enabled.",
|
||||||
"POLICY_ALREADY_EXISTS": "Replication rule already exists.",
|
"POLICY_ALREADY_EXISTS": "Replication rule already exists.",
|
||||||
"FAILED_TO_DELETE_POLICY_ENABLED": "Cannot delete rule: rule has unfinished job(s) or rule is enabled.",
|
"FAILED_TO_DELETE_POLICY_ENABLED": "Cannot delete rule: rule has unfinished job(s) or rule is enabled.",
|
||||||
"FOUND_ERROR_IN_JOBS": "Found errors in the replication job(s), please check."
|
"FOUND_ERROR_IN_JOBS": "Found errors in the replication job(s), please check.",
|
||||||
|
"INVALID_DATE": "Invalid date."
|
||||||
},
|
},
|
||||||
"DESTINATION": {
|
"DESTINATION": {
|
||||||
"NEW_ENDPOINT": "New Endpoint",
|
"NEW_ENDPOINT": "New Endpoint",
|
||||||
|
@ -124,6 +124,7 @@
|
|||||||
"NAME": "Nombre del Proyecto",
|
"NAME": "Nombre del Proyecto",
|
||||||
"ROLE": "Rol",
|
"ROLE": "Rol",
|
||||||
"PUBLIC_OR_PRIVATE": "Público",
|
"PUBLIC_OR_PRIVATE": "Público",
|
||||||
|
"ACCESS_LEVEL": "Nivel de acceso",
|
||||||
"REPO_COUNT": "Contador de repositorios",
|
"REPO_COUNT": "Contador de repositorios",
|
||||||
"CREATION_TIME": "Fecha de creación",
|
"CREATION_TIME": "Fecha de creación",
|
||||||
"PUBLIC": "Público",
|
"PUBLIC": "Público",
|
||||||
@ -197,7 +198,8 @@
|
|||||||
"ADVANCED": "Avanzado",
|
"ADVANCED": "Avanzado",
|
||||||
"SIMPLE": "Simple",
|
"SIMPLE": "Simple",
|
||||||
"ITEMS": "elemento(s)",
|
"ITEMS": "elemento(s)",
|
||||||
"FILTER_PLACEHOLDER": "Filtrar logs"
|
"FILTER_PLACEHOLDER": "Filtrar logs",
|
||||||
|
"INVALID_DATE": "Fecha invalida."
|
||||||
},
|
},
|
||||||
"REPLICATION": {
|
"REPLICATION": {
|
||||||
"REPLICATION_RULE": "Reglas de Replicación",
|
"REPLICATION_RULE": "Reglas de Replicación",
|
||||||
@ -265,7 +267,8 @@
|
|||||||
"CANNOT_EDIT": "La regla de replicación no se puede cambiar mientras esté activa.",
|
"CANNOT_EDIT": "La regla de replicación no se puede cambiar mientras esté activa.",
|
||||||
"POLICY_ALREADY_EXISTS": "La regla de replicación ya existe.",
|
"POLICY_ALREADY_EXISTS": "La regla de replicación ya existe.",
|
||||||
"FAILED_TO_DELETE_POLICY_ENABLED": "No se puede eliminar la regla: tiene trabajo(s) sin finalizar o está activa.",
|
"FAILED_TO_DELETE_POLICY_ENABLED": "No se puede eliminar la regla: tiene trabajo(s) sin finalizar o está activa.",
|
||||||
"FOUND_ERROR_IN_JOBS": "Se han encontrado errores en el trabajo de replicación. Por favor, compruébelos."
|
"FOUND_ERROR_IN_JOBS": "Se han encontrado errores en el trabajo de replicación. Por favor, compruébelos.",
|
||||||
|
"INVALID_DATE": "Fecha invalida."
|
||||||
},
|
},
|
||||||
"DESTINATION": {
|
"DESTINATION": {
|
||||||
"NEW_ENDPOINT": "Nuevo Endpoint",
|
"NEW_ENDPOINT": "Nuevo Endpoint",
|
||||||
|
@ -124,6 +124,7 @@
|
|||||||
"NAME": "项目名称",
|
"NAME": "项目名称",
|
||||||
"ROLE": "角色",
|
"ROLE": "角色",
|
||||||
"PUBLIC_OR_PRIVATE": "公开",
|
"PUBLIC_OR_PRIVATE": "公开",
|
||||||
|
"ACCESS_LEVEL": "访问级别",
|
||||||
"REPO_COUNT": "镜像仓库数",
|
"REPO_COUNT": "镜像仓库数",
|
||||||
"CREATION_TIME": "创建时间",
|
"CREATION_TIME": "创建时间",
|
||||||
"PUBLIC": "公开",
|
"PUBLIC": "公开",
|
||||||
@ -197,7 +198,8 @@
|
|||||||
"ADVANCED": "高级检索",
|
"ADVANCED": "高级检索",
|
||||||
"SIMPLE": "简单检索",
|
"SIMPLE": "简单检索",
|
||||||
"ITEMS": "条记录",
|
"ITEMS": "条记录",
|
||||||
"FILTER_PLACEHOLDER": "过滤日志"
|
"FILTER_PLACEHOLDER": "过滤日志",
|
||||||
|
"INVALID_DATE": "无效日期。"
|
||||||
},
|
},
|
||||||
"REPLICATION": {
|
"REPLICATION": {
|
||||||
"REPLICATION_RULE": "复制规则",
|
"REPLICATION_RULE": "复制规则",
|
||||||
@ -265,7 +267,8 @@
|
|||||||
"CANNOT_EDIT": "当复制规则启用时无法修改。",
|
"CANNOT_EDIT": "当复制规则启用时无法修改。",
|
||||||
"POLICY_ALREADY_EXISTS": "规则已存在。",
|
"POLICY_ALREADY_EXISTS": "规则已存在。",
|
||||||
"FAILED_TO_DELETE_POLICY_ENABLED": "删除复制规则失败: 仍有未完成的任务或规则未停用。",
|
"FAILED_TO_DELETE_POLICY_ENABLED": "删除复制规则失败: 仍有未完成的任务或规则未停用。",
|
||||||
"FOUND_ERROR_IN_JOBS": "复制任务中包含错误,请检查。"
|
"FOUND_ERROR_IN_JOBS": "复制任务中包含错误,请检查。",
|
||||||
|
"INVALID_DATE": "无效日期。"
|
||||||
},
|
},
|
||||||
"DESTINATION": {
|
"DESTINATION": {
|
||||||
"NEW_ENDPOINT": "新建目标",
|
"NEW_ENDPOINT": "新建目标",
|
||||||
|
Loading…
Reference in New Issue
Block a user