Improve Immutable tag UI

Signed-off-by: Yogi_Wang <yawang@vmware.com>
This commit is contained in:
Yogi_Wang 2019-10-24 12:38:09 +08:00
parent e8554b9d66
commit 26381c93be
12 changed files with 197 additions and 45 deletions

View File

@ -1,13 +1,13 @@
<clr-modal [(clrModalOpen)]="addRuleOpened" [clrModalStaticBackdrop]="true" [clrModalClosable]="true" [clrModalSize]="'lg'">
<h3 class="modal-title" *ngIf="isAdd">{{'TAG_RETENTION.ADD_TITLE' | translate}}</h3>
<h3 class="modal-title" *ngIf="!isAdd">{{'TAG_RETENTION.EDIT_TITLE' | translate}}</h3>
<h3 class="modal-title" *ngIf="isAdd">{{'IMMUTABLE_TAG.ADD_TITLE' | translate}}</h3>
<h3 class="modal-title" *ngIf="!isAdd">{{'IMMUTABLE_TAG.EDIT_TITLE' | translate}}</h3>
<div class="modal-body no-scrolling">
<inline-alert class="modal-title"></inline-alert>
<p class="color-97">{{'TAG_RETENTION.ADD_SUBTITLE' | translate}}</p>
<p class="color-97">{{'IMMUTABLE_TAG.ADD_SUBTITLE' | translate}}</p>
<div class="height-72">
<div class="clr-row mt-1">
<div class="clr-col-4">
<span>{{'TAG_RETENTION.IN_REPOSITORIES' | translate}}</span>
<span>{{'IMMUTABLE_TAG.IN_REPOSITORIES' | translate}}</span>
</div>
<div class="clr-col-3">
<div class="clr-select-wrapper w-100">
@ -26,14 +26,14 @@
<div class="clr-row">
<div class="clr-col-4"></div>
<div class="clr-col-8">
<span>{{'TAG_RETENTION.REP_SEPARATOR' | translate}}</span>
<span>{{'IMMUTABLE_TAG.REP_SEPARATOR' | translate}}</span>
</div>
</div>
</div>
<div class="height-72">
<div class="clr-row">
<div class="clr-col-4">
<label>{{'TAG_RETENTION.TAGS' | translate}}</label>
<label>{{'IMMUTABLE_TAG.TAGS' | translate}}</label>
</div>
<div class="clr-col-3">
<div class="clr-select-wrapper w-100">
@ -52,7 +52,7 @@
<div class="clr-row">
<div class="clr-col-4"></div>
<div class="clr-col-8">
<span>{{'TAG_RETENTION.TAG_SEPARATOR' | translate}}</span>
<span>{{'IMMUTABLE_TAG.TAG_SEPARATOR' | translate}}</span>
</div>
</div>
</div>

View File

@ -54,7 +54,7 @@ export class AddRuleComponent implements OnInit, OnDestroy {
set repositories(repositories) {
if (this.rule && this.rule.scope_selectors && this.rule.scope_selectors.repository
&& this.rule.scope_selectors.repository[0] && this.rule.scope_selectors.repository[0].pattern) {
&& this.rule.scope_selectors.repository[0]) {
if (repositories.indexOf(",") !== -1) {
this.rule.scope_selectors.repository[0].pattern = "{" + repositories + "}";
} else {
@ -85,7 +85,7 @@ export class AddRuleComponent implements OnInit, OnDestroy {
}
set tagsInput(tagsInput) {
if (this.rule && this.rule.tag_selectors && this.rule.tag_selectors[0] && this.rule.tag_selectors[0].pattern) {
if (this.rule && this.rule.tag_selectors && this.rule.tag_selectors[0]) {
if (tagsInput.indexOf(",") !== -1) {
this.rule.tag_selectors[0].pattern = "{" + tagsInput + "}";
} else {

View File

@ -1,6 +1,6 @@
<div class="clr-row pt-1 fw8">
<div class="clr-col">
<label class="label-left font-size-54">{{'TAG_RETENTION.RETENTION_RULES' | translate}}</label><span class="badge badge-3 ml-5">{{rules?.length ? rules?.length : 0}}/15</span>
<label class="label-left font-size-54">{{'IMMUTABLE_TAG.IMMUTABLE_RULES' | translate}}</label><span class="badge badge-3 ml-5">{{rules?.length ? rules?.length : 0}}/15</span>
<span *ngIf="loadingRule" class="spinner spinner-inline ml-2">Loading...</span>
</div>
</div>
@ -12,14 +12,14 @@
<div class="clr-col-2 flex-150">
<div class="dropdown" [ngClass]="{open:ruleIndex===i}">
<button (click)="openEditor(i)" id="{{'action'+i}}" class="dropdown-toggle btn btn-link btn-sm">
{{'TAG_RETENTION.ACTION' | translate}}
{{'IMMUTABLE_TAG.ACTION' | translate}}
<clr-icon shape="caret down"></clr-icon>
</button>
<div class="dropdown-menu">
<button *ngIf="!rule?.disabled" type="button" id="{{'disable-btn'+i}}" class="dropdown-item" (click)="toggleDisable(rule,true)">{{'TAG_RETENTION.DISABLE' | translate}}</button>
<button *ngIf="rule?.disabled" type="button" class="dropdown-item" (click)="toggleDisable(rule,false)">{{'TAG_RETENTION.ENABLE' | translate}}</button>
<button type="button" id="{{'edit-btn'+i}}" class="dropdown-item" (click)="editRuleByIndex(i)">{{'TAG_RETENTION.EDIT' | translate}}</button>
<button type="button" class="dropdown-item" id="{{'delete-btn'+i}}" (click)="deleteRule(rule.id)">{{'TAG_RETENTION.DELETE' | translate}}</button>
<button *ngIf="!rule?.disabled" type="button" id="{{'disable-btn'+i}}" class="dropdown-item" (click)="toggleDisable(rule,true)">{{'IMMUTABLE_TAG.DISABLE' | translate}}</button>
<button *ngIf="rule?.disabled" type="button" class="dropdown-item" (click)="toggleDisable(rule,false)">{{'IMMUTABLE_TAG.ENABLE' | translate}}</button>
<button type="button" id="{{'edit-btn'+i}}" class="dropdown-item" (click)="editRuleByIndex(i)">{{'IMMUTABLE_TAG.EDIT' | translate}}</button>
<button type="button" class="dropdown-item" id="{{'delete-btn'+i}}" (click)="deleteRule(rule.id)">{{'IMMUTABLE_TAG.DELETE' | translate}}</button>
</div>
</div>
</div>
@ -29,16 +29,16 @@
<clr-icon id="{{'disable-icon'+i}}" *ngIf="rule?.disabled" class="color-red" shape="error-standard"></clr-icon>
</span>
<span class="rule-name ml-5">
<span>{{'TAG_RETENTION.IN_REPOSITORIES' | translate}}</span>
<span>{{'IMMUTABLE_TAG.IN_REPOSITORIES' | translate}}</span>
<span>{{getI18nKey(rule?.scope_selectors?.repository[0]?.decoration)|translate}}</span>
<span>{{formatPattern(rule?.scope_selectors?.repository[0]?.pattern)}}</span>
<span>,</span>
<span>{{'TAG_RETENTION.LOWER_TAGS' | translate}}</span>
<span>{{'IMMUTABLE_TAG.LOWER_TAGS' | translate}}</span>
<span>{{getI18nKey(rule?.tag_selectors[0]?.decoration)|translate}}</span>
<span id="{{'tag-selectors-patten'+i}}">{{formatPattern(rule?.tag_selectors[0]?.pattern)}}</span>
<ng-container *ngIf="rule?.tag_selectors[1]?.pattern && rule?.tag_selectors[1]?.pattern">
<span class="color-97">{{'TAG_RETENTION.AND' | translate}}</span>
<span>{{'TAG_RETENTION.LOWER_LABELS' | translate}}</span>
<span class="color-97">{{'IMMUTABLE_TAG.AND' | translate}}</span>
<span>{{'IMMUTABLE_TAG.LOWER_LABELS' | translate}}</span>
<span>{{getI18nKey(rule?.tag_selectors[1]?.decoration)|translate}}</span>
<span>{{rule?.tag_selectors[1]?.pattern}}</span>
</ng-container>
@ -50,10 +50,10 @@
<div class="v-center clr-row" [ngClass]="{'pt-1':rules?.length > 0}">
<div class="clr-col-2 flex-150"></div>
<div class="clr-col-2">
<button [disabled]="rules?.length >= 15" id="add-rule" class="btn btn-primary btn-sm" (click)="openAddRule()">{{'TAG_RETENTION.ADD_RULE' | translate}}</button>
<button [disabled]="rules?.length >= 15" id="add-rule" class="btn btn-primary btn-sm" (click)="openAddRule()">{{'IMMUTABLE_TAG.ADD_RULE' | translate}}</button>
</div>
<div class="clr-col-8 color-97 font-size-54">
{{'TAG_RETENTION.ADD_RULE_HELP_1' | translate}}
{{'IMMUTABLE_TAG.ADD_RULE_HELP_1' | translate}}
</div>
</div>
</div>

View File

@ -0,0 +1,15 @@
.ml-5 {
margin-left: 5px;
}
.dropdown-toggle {
outline: none;
}
.backdrop-transparent {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
opacity: 0;
z-index: 999;
}

View File

@ -63,10 +63,11 @@ export class ImmutableTagComponent implements OnInit {
this.ruleIndex = -1;
}
toggleDisable(rule, isActionDisable) {
rule.disabled = isActionDisable;
let cloneRule = clone(rule);
cloneRule.disabled = isActionDisable;
this.ruleIndex = -1;
this.loadingRule = true;
this.immutableTagService.updateRule(this.projectId, rule).subscribe(
this.immutableTagService.updateRule(this.projectId, cloneRule).subscribe(
response => {
this.getRules();
}, error => {

View File

@ -8,34 +8,14 @@ import { HTTP_JSON_OPTIONS } from "@harbor/ui";
@Injectable()
export class ImmutableTagService {
private I18nMap: object = {
"retain": "ACTION_RETAIN",
"lastXDays": "RULE_NAME_1",
"latestActiveK": "RULE_NAME_2",
"latestPushedK": "RULE_NAME_3",
"latestPulledN": "RULE_NAME_4",
"always": "RULE_NAME_5",
"nDaysSinceLastPull": "RULE_NAME_6",
"nDaysSinceLastPush": "RULE_NAME_7",
"the images from the last # days": "RULE_TEMPLATE_1",
"the most recent active # images": "RULE_TEMPLATE_2",
"the most recently pushed # images": "RULE_TEMPLATE_3",
"the most recently pulled # images": "RULE_TEMPLATE_4",
"pulled within the last # days": "RULE_TEMPLATE_6",
"pushed within the last # days": "RULE_TEMPLATE_7",
"repoMatches": "MAT",
"repoExcludes": "EXC",
"matches": "MAT",
"excludes": "EXC",
"withLabels": "WITH",
"withoutLabels": "WITHOUT",
"COUNT": "UNIT_COUNT",
"DAYS": "UNIT_DAY",
"none": "NONE",
"nothing": "NONE",
"Parameters nDaysSinceLastPull is too large": "DAYS_LARGE",
"Parameters nDaysSinceLastPush is too large": "DAYS_LARGE",
"Parameters latestPushedK is too large": "COUNT_LARGE",
"Parameters latestPulledN is too large": "COUNT_LARGE"
"nothing": "NONE"
};
constructor(
@ -45,7 +25,7 @@ export class ImmutableTagService {
getI18nKey(str: string): string {
if (this.I18nMap[str.trim()]) {
return "TAG_RETENTION." + this.I18nMap[str.trim()];
return "IMMUTABLE_TAG." + this.I18nMap[str.trim()];
}
return str;
}

View File

@ -1233,6 +1233,32 @@
"EXECUTION_TYPE": "Execution Type",
"ACTION": "ACTION"
},
"IMMUTABLE_TAG": {
"IMMUTABLE_RULES": "Immutable rules",
"ADD_RULE": "ADD RULE",
"ADD_RULE_HELP_1": "Click the ADD RULE button to add a rule.",
"EDIT": "Edit",
"DISABLE": "Disable",
"ENABLE": "Enable",
"DELETE": "Delete",
"ADD_TITLE": "Add Immutable Rule",
"ADD_SUBTITLE": "Specify a immutable rule for this project. All immutable rules are independently calculated and each rule can be applied to a selected list of repositories.",
"IN_REPOSITORIES": "For the repositories",
"REP_SEPARATOR": "Enter multiple comma separated repos,repo*,or **",
"TAGS": "Tags",
"TAG_SEPARATOR": "Enter multiple comma separated tags,tag*,or **",
"EDIT_TITLE": "Edit Immutable Rule",
"EXC": " excluding ",
"MAT": " matching ",
"AND": " and",
"WITH": " with ",
"WITHOUT": " without ",
"LOWER_LABELS": " labels",
"LOWER_TAGS": " tags",
"NONE": " none",
"EXISTING_RULE": "Existing rule",
"ACTION": "ACTION"
},
"SCANNER": {
"DELETION_SUMMARY": "Do you want to delete scanner {{param}}?",
"SKIP_CERT_VERIFY": "Check this box to skip certificate verification when the remote registry uses a self-signed or untrusted certificate.",

View File

@ -1230,6 +1230,32 @@
"EXECUTION_TYPE": "Execution Type",
"ACTION": "ACTION"
},
"IMMUTABLE_TAG": {
"IMMUTABLE_RULES": "Immutable rules",
"ADD_RULE": "ADD RULE",
"ADD_RULE_HELP_1": "Click the ADD RULE button to add a rule.",
"EDIT": "Edit",
"DISABLE": "Disable",
"ENABLE": "Enable",
"DELETE": "Delete",
"ADD_TITLE": "Add Immutable Rule",
"ADD_SUBTITLE": "Specify a immutable rule for this project. All immutable rules are independently calculated and each rule can be applied to a selected list of repositories.",
"IN_REPOSITORIES": "For the repositories",
"REP_SEPARATOR": "Enter multiple comma separated repos,repo*,or **",
"TAGS": "Tags",
"TAG_SEPARATOR": "Enter multiple comma separated tags,tag*,or **",
"EDIT_TITLE": "Edit Immutable Rule",
"EXC": " excluding ",
"MAT": " matching ",
"AND": " and",
"WITH": " with ",
"WITHOUT": " without ",
"LOWER_LABELS": " labels",
"LOWER_TAGS": " tags",
"NONE": " none",
"EXISTING_RULE": "Existing rule",
"ACTION": "ACTION"
},
"SCANNER": {
"DELETION_SUMMARY": "Do you want to delete scanner {{param}}?",
"SKIP_CERT_VERIFY": "Check this box to skip certificate verification when the remote registry uses a self-signed or untrusted certificate.",

View File

@ -1202,6 +1202,32 @@
"EXECUTION_TYPE": "Execution Type",
"ACTION": "ACTION"
},
"IMMUTABLE_TAG": {
"IMMUTABLE_RULES": "Immutable rules",
"ADD_RULE": "ADD RULE",
"ADD_RULE_HELP_1": "Click the ADD RULE button to add a rule.",
"EDIT": "Edit",
"DISABLE": "Disable",
"ENABLE": "Enable",
"DELETE": "Delete",
"ADD_TITLE": "Add Immutable Rule",
"ADD_SUBTITLE": "Specify a immutable rule for this project. All immutable rules are independently calculated and each rule can be applied to a selected list of repositories.",
"IN_REPOSITORIES": "For the repositories",
"REP_SEPARATOR": "Enter multiple comma separated repos,repo*,or **",
"TAGS": "Tags",
"TAG_SEPARATOR": "Enter multiple comma separated tags,tag*,or **",
"EDIT_TITLE": "Edit Immutable Rule",
"EXC": " excluding ",
"MAT": " matching ",
"AND": " and",
"WITH": " with ",
"WITHOUT": " without ",
"LOWER_LABELS": " labels",
"LOWER_TAGS": " tags",
"NONE": " none",
"EXISTING_RULE": "Existing rule",
"ACTION": "ACTION"
},
"SCANNER": {
"DELETION_SUMMARY": "Do you want to delete scanner {{param}}?",
"SKIP_CERT_VERIFY": "Check this box to skip certificate verification when the remote registry uses a self-signed or untrusted certificate.",

View File

@ -1227,6 +1227,32 @@
"EXECUTION_TYPE": "Execution Type",
"ACTION": "ACTION"
},
"IMMUTABLE_TAG": {
"IMMUTABLE_RULES": "Immutable rules",
"ADD_RULE": "ADD RULE",
"ADD_RULE_HELP_1": "Click the ADD RULE button to add a rule.",
"EDIT": "Edit",
"DISABLE": "Disable",
"ENABLE": "Enable",
"DELETE": "Delete",
"ADD_TITLE": "Add Immutable Rule",
"ADD_SUBTITLE": "Specify a immutable rule for this project. All immutable rules are independently calculated and each rule can be applied to a selected list of repositories.",
"IN_REPOSITORIES": "For the repositories",
"REP_SEPARATOR": "Enter multiple comma separated repos,repo*,or **",
"TAGS": "Tags",
"TAG_SEPARATOR": "Enter multiple comma separated tags,tag*,or **",
"EDIT_TITLE": "Edit Immutable Rule",
"EXC": " excluding ",
"MAT": " matching ",
"AND": " and",
"WITH": " with ",
"WITHOUT": " without ",
"LOWER_LABELS": " labels",
"LOWER_TAGS": " tags",
"NONE": " none",
"EXISTING_RULE": "Existing rule",
"ACTION": "ACTION"
},
"SCANNER": {
"DELETION_SUMMARY": "Do you want to delete scanner {{param}}?",
"SKIP_CERT_VERIFY": "Check this box to skip certificate verification when the remote registry uses a self-signed or untrusted certificate.",

View File

@ -1232,6 +1232,32 @@
"EXECUTION_TYPE": "Execution Type",
"ACTION": "ACTION"
},
"IMMUTABLE_TAG": {
"IMMUTABLE_RULES": "Immutable rules",
"ADD_RULE": "ADD RULE",
"ADD_RULE_HELP_1": "Click the ADD RULE button to add a rule.",
"EDIT": "Edit",
"DISABLE": "Disable",
"ENABLE": "Enable",
"DELETE": "Delete",
"ADD_TITLE": "Add Immutable Rule",
"ADD_SUBTITLE": "Specify a immutable rule for this project. All immutable rules are independently calculated and each rule can be applied to a selected list of repositories.",
"IN_REPOSITORIES": "For the repositories",
"REP_SEPARATOR": "Enter multiple comma separated repos,repo*,or **",
"TAGS": "Tags",
"TAG_SEPARATOR": "Enter multiple comma separated tags,tag*,or **",
"EDIT_TITLE": "Edit Immutable Rule",
"EXC": " excluding ",
"MAT": " matching ",
"AND": " and",
"WITH": " with ",
"WITHOUT": " without ",
"LOWER_LABELS": " labels",
"LOWER_TAGS": " tags",
"NONE": " none",
"EXISTING_RULE": "Existing rule",
"ACTION": "ACTION"
},
"SCANNER": {
"DELETION_SUMMARY": "Do you want to delete scanner {{param}}?",
"SKIP_CERT_VERIFY": "Check this box to skip certificate verification when the remote registry uses a self-signed or untrusted certificate.",

View File

@ -1229,6 +1229,32 @@
"EXECUTION_TYPE": "执行类型",
"ACTION": "操作"
},
"IMMUTABLE_TAG": {
"IMMUTABLE_RULES": "不变的规则",
"ADD_RULE": "添加新规则",
"ADD_RULE_HELP_1": "点击添加按钮可添加规则。",
"EDIT": "修改",
"DISABLE": "禁用",
"ENABLE": "启用",
"DELETE": "删除",
"ADD_TITLE": "添加不变的规则",
"ADD_SUBTITLE": "为当前项目指定不改变规则。所有不改变的规则独立计算并且适用于所有符合条件的仓库。",
"IN_REPOSITORIES": "应用到仓库",
"REP_SEPARATOR": "使用逗号分隔repos,repo*和**。",
"TAGS": "Tags",
"TAG_SEPARATOR": "使用逗号分割tags,tag*和**。",
"EDIT_TITLE": "编辑不改变的规则",
"EXC": "排除",
"MAT": "匹配",
"AND": "且",
"WITH": "有",
"WITHOUT": "没有",
"LOWER_LABELS": "标签",
"LOWER_TAGS": " tags",
"NONE": " 无",
"EXISTING_RULE": "规则已存在。",
"ACTION": "操作"
},
"SCANNER": {
"DELETION_SUMMARY": "确定删除扫描器{{param}}",
"SKIP_CERT_VERIFY": "当远程注册使用自签或不可信证书时可勾选此项以跳过证书认证。",