From 85f357ec6b8857431025c0b4003be9f5f37b56db Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Sat, 24 Mar 2018 02:22:51 +0800 Subject: [PATCH 01/15] Delete the mapping relationship between resources and labels when the label is deleted --- src/common/dao/resource_label.go | 6 ++++++ src/common/dao/resource_label_test.go | 11 +++++++++++ src/ui/api/label.go | 4 ++++ 3 files changed, 21 insertions(+) diff --git a/src/common/dao/resource_label.go b/src/common/dao/resource_label.go index 56b17916b..b80b3bb03 100644 --- a/src/common/dao/resource_label.go +++ b/src/common/dao/resource_label.go @@ -120,3 +120,9 @@ func ListResourceLabels(query ...*models.ResourceLabelQuery) ([]*models.Resource _, err := qs.All(&rls) return rls, err } + +// DeleteResourceLabelByLabel delete the mapping relationship by label ID +func DeleteResourceLabelByLabel(id int64) error { + _, err := GetOrmer().QueryTable(&models.ResourceLabel{}).Filter("LabelID", id).Delete() + return err +} diff --git a/src/common/dao/resource_label_test.go b/src/common/dao/resource_label_test.go index 572bec8b5..467f019a0 100644 --- a/src/common/dao/resource_label_test.go +++ b/src/common/dao/resource_label_test.go @@ -81,4 +81,15 @@ func TestMethodsOfResourceLabel(t *testing.T) { labels, err = GetLabelsOfResource(resourceType, resourceID) require.Nil(t, err) require.Equal(t, 0, len(labels)) + + // delete by label ID + id, err = AddResourceLabel(rl) + require.Nil(t, err) + err = DeleteResourceLabelByLabel(labelID) + require.Nil(t, err) + rls, err = ListResourceLabels(&models.ResourceLabelQuery{ + LabelID: labelID, + }) + require.Nil(t, err) + require.Equal(t, 0, len(rls)) } diff --git a/src/ui/api/label.go b/src/ui/api/label.go index 3d7dfe978..db6144e57 100644 --- a/src/ui/api/label.go +++ b/src/ui/api/label.go @@ -256,6 +256,10 @@ func (l *LabelAPI) Put() { // Delete the label func (l *LabelAPI) Delete() { id := l.label.ID + if err := dao.DeleteResourceLabelByLabel(id); err != nil { + l.HandleInternalServerError(fmt.Sprintf("failed to delete resource label mappings of label %d: %v", id, err)) + return + } if err := dao.DeleteLabel(id); err != nil { l.HandleInternalServerError(fmt.Sprintf("failed to delete label %d: %v", id, err)) return From 3ea42fd62c260d6fbe6195cded87420344d6c5bd Mon Sep 17 00:00:00 2001 From: wangyan Date: Sun, 25 Mar 2018 18:22:35 -0700 Subject: [PATCH 02/15] add read only case --- tests/resources/Harbor-Pages/Configuration.robot | 14 +++++++++++++- tests/robot-cases/Group11-Nightly/Nightly.robot | 12 ++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/tests/resources/Harbor-Pages/Configuration.robot b/tests/resources/Harbor-Pages/Configuration.robot index 451807ba0..8b99584a1 100644 --- a/tests/resources/Harbor-Pages/Configuration.robot +++ b/tests/resources/Harbor-Pages/Configuration.robot @@ -211,10 +211,22 @@ Set Scan All To None click element //vulnerability-config//select/option[@value='none'] sleep 1 click element ${config_save_button_xpath} + Set Scan All To Daily click element //vulnerability-config//select click element //vulnerability-config//select/option[@value='daily'] sleep 1 click element ${config_save_button_xpath} + Click Scan Now - click element //vulnerability-config//button[contains(.,'SCAN')] \ No newline at end of file + click element //vulnerability-config//button[contains(.,'SCAN')] + +Enable Read Only + ${rc} ${output}= Run And Return Rc And Output curl -u admin:Harbor12345 -s --insecure -H "Content-Type: application/json" -X PUT -d '{"read_only":true}' "https://${ip}/api/configurations" + Log To Console ${output} + Should Be Equal As Integers ${rc} 0 + +Disable Read Only + ${rc} ${output}= Run And Return Rc And Output curl -u admin:Harbor12345 -s --insecure -H "Content-Type: application/json" -X PUT -d '{"read_only":false}' "https://${ip}/api/configurations" + Log To Console ${output} + Should Be Equal As Integers ${rc} 0 \ No newline at end of file diff --git a/tests/robot-cases/Group11-Nightly/Nightly.robot b/tests/robot-cases/Group11-Nightly/Nightly.robot index 24a073894..3c8ccfaad 100644 --- a/tests/robot-cases/Group11-Nightly/Nightly.robot +++ b/tests/robot-cases/Group11-Nightly/Nightly.robot @@ -35,6 +35,18 @@ Test Case - Vulnerability Data Not Ready Go To Vulnerability Config Vulnerability Not Ready Config Hint +Test Case - Read Only Mode + Init Chrome Driver + ${d}= Get Current Date result_format=%m%s + Create An New Project With New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=tester${d} newPassword=Test1@34 comment=harbor projectname=project${d} public=true + + Enable Read Only + Cannot Push image ${ip} tester${d} Test1@34 project${d} busybox:latest + + Disable Read Only + Push image ${ip} tester${d} Test1@34 project${d} busybox:latest + Close Browser + Test Case - Create An New User Init Chrome Driver ${d}= Get Current Date result_format=%m%s From 0c95bd6ffa89d895ee84d350077ea327d327f297 Mon Sep 17 00:00:00 2001 From: sigsbee <23101283+sigsbee@users.noreply.github.com> Date: Mon, 26 Mar 2018 16:27:07 +0800 Subject: [PATCH 03/15] Update project detail xpath (#4482) --- tests/resources/Harbor-Pages/Project.robot | 4 ++-- tests/resources/Harbor-Pages/Project_Elements.robot | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/resources/Harbor-Pages/Project.robot b/tests/resources/Harbor-Pages/Project.robot index 3cc3c6bd8..4563fe988 100644 --- a/tests/resources/Harbor-Pages/Project.robot +++ b/tests/resources/Harbor-Pages/Project.robot @@ -44,11 +44,11 @@ Create An New Project With New User #It's the log of project. Go To Project Log - Click Element xpath=//project-detail//ul/li[3] + Click Element xpath=${project_log_xpath} Sleep 2 Switch To Member - Click Element xpath=//project-detail//li[2] + Click Element xpath=${project_member_xpath} Sleep 1 Switch To Log diff --git a/tests/resources/Harbor-Pages/Project_Elements.robot b/tests/resources/Harbor-Pages/Project_Elements.robot index 57175ee05..34201c9af 100644 --- a/tests/resources/Harbor-Pages/Project_Elements.robot +++ b/tests/resources/Harbor-Pages/Project_Elements.robot @@ -22,4 +22,6 @@ ${project_public_xpath} //input[@name='public']/..//label ${project_save_css} html body.no-scrolling harbor-app harbor-shell clr-main-container.main-container div.content-container div.content-area.content-area-override project div.row div.col-lg-12.col-md-12.col-sm-12.col-xs-12 div.row.flex-items-xs-between div.option-left create-project clr-modal div.modal div.modal-dialog div.modal-content div.modal-footer button.btn.btn-primary ${log_xpath} //clr-main-container/div/clr-vertical-nav/div/a[contains(.,'Logs')] ${projects_xpath} //clr-main-container/div/clr-vertical-nav/div/a[contains(.,'Projects')] -${project_replication_xpath} //project-detail//a[contains(.,'Replication')] \ No newline at end of file +${project_replication_xpath} //project-detail//a[contains(.,'Replication')] +${project_log_xpath} //project-detail//li[contains(.,'Logs')] +${project_member_xpath} //project-detail//li[contains(.,'Members')] From 71eeebec6f40d334325b46b72768e27eedcea27a Mon Sep 17 00:00:00 2001 From: Daniele Franceschi Date: Mon, 26 Mar 2018 14:48:13 +0200 Subject: [PATCH 04/15] fix rendering suffix for >1GB images --- src/ui_ng/lib/src/tag/tag.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui_ng/lib/src/tag/tag.component.ts b/src/ui_ng/lib/src/tag/tag.component.ts index c75438967..2e68f4bce 100644 --- a/src/ui_ng/lib/src/tag/tag.component.ts +++ b/src/ui_ng/lib/src/tag/tag.component.ts @@ -442,7 +442,7 @@ export class TagComponent implements OnInit, AfterViewInit { } else if (Math.pow(1024, 2) <= size && size < Math.pow(1024, 3)) { return (size / Math.pow(1024, 2)).toFixed(2) + "MB"; } else if (Math.pow(1024, 3) <= size && size < Math.pow(1024, 4)) { - return (size / Math.pow(1024, 3)).toFixed(2) + "MB"; + return (size / Math.pow(1024, 3)).toFixed(2) + "GB"; } else { return size + "B"; } From 05b903132725b8a4b6f16076d72132586a3acd56 Mon Sep 17 00:00:00 2001 From: lucaim <15264356+lucaim@users.noreply.github.com> Date: Mon, 26 Mar 2018 17:41:49 +0200 Subject: [PATCH 05/15] Adding LDAP authentication parameters to helm chart --- contrib/helm/harbor/README.md | 10 +++++++++ .../templates/adminserver/adminserver-cm.yaml | 21 +++++++++---------- contrib/helm/harbor/values.yaml | 10 +++++++++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/contrib/helm/harbor/README.md b/contrib/helm/harbor/README.md index 52da97939..23fad1318 100644 --- a/contrib/helm/harbor/README.md +++ b/contrib/helm/harbor/README.md @@ -112,6 +112,16 @@ The following tables lists the configurable parameters of the Harbor chart and t | `adminserver.key` | adminsever key | `not-a-secure-key` | | `adminserver.emailPwd` | password for email | `not-a-secure-password` | | `adminserver.harborAdminPassword` | password for admin user | `Harbor12345` | +| `adminserver.harborAuthenticationMode` | authentication mode for Harbor ( `db_auth` for local database, `ldap_auth` for LDAP, etc...) [Docs](https://github.com/vmware/harbor/blob/master/docs/user_guide.md#user-account) | `db_auth` | +| `adminserver.selfRegistration` | Allows users to register by themselves, otherwise only administrators can add users | `on` | +| `adminserver.authenticationLdapURL` | LDAP server URL for `ldap_auth` authentication | `ldaps://ldapserver` | +| `adminserver.authenticationLdapSearchDN` | LDAP Search DN | `` | +| `adminserver.authenticationLdapBaseDN` | LDAP Base DN | `` | +| `adminserver.authenticationLdapFilter` | LDAP Filter | `(objectClass=person)` | +| `adminserver.authenticationLdapUID` | LDAP UID | `uid` | +| `adminserver.authenticationLdapScope` | LDAP Scope | `2` | +| `adminserver.authenticationLdapTimeout` | LDAP Timeout | `5` | +| `adminserver.authenticationLdapVerifyCert` | LDAP Verify HTTPS Certificate | `True` | | `adminserver.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined | | `adminserver.volumes` | used to create PVCs if persistence is enabled (see instructions in values.yaml) | see values.yaml | | **Jobservice** | diff --git a/contrib/helm/harbor/templates/adminserver/adminserver-cm.yaml b/contrib/helm/harbor/templates/adminserver/adminserver-cm.yaml index 1ff8f8b8b..6f5a3aa79 100644 --- a/contrib/helm/harbor/templates/adminserver/adminserver-cm.yaml +++ b/contrib/helm/harbor/templates/adminserver/adminserver-cm.yaml @@ -29,17 +29,16 @@ data: WITH_NOTARY: "{{ .Values.notary.enabled }}" LOG_LEVEL: "info" IMAGE_STORE_PATH: "/" # This is a temporary hack. - AUTH_MODE: "db_auth" - SELF_REGISTRATION: "on" - LDAP_URL: "ldaps://ldapserver" - LDAP_SEARCH_DN: "" - LDAP_BASE_DN: "" - LDAP_FILTER: "(objectClass=person)" - LDAP_UID: "uid" - LDAP_SCOPE: "2" - LDAP_TIMEOUT: "5" - LDAP_TIMEOUT: "5" - LDAP_VERIFY_CERT: "True" + AUTH_MODE: "{{ .Values.adminserver.harborAuthenticationMode }}" + SELF_REGISTRATION: "{{ .Values.adminserver.selfRegistration }}" + LDAP_URL: "{{ .Values.adminserver.authenticationLdapURL }}" + LDAP_SEARCH_DN: "{{ .Values.adminserver.authenticationLdapSearchDN }}" + LDAP_BASE_DN: "{{ .Values.adminserver.authenticationLdapBaseDN }}" + LDAP_FILTER: "{{ .Values.adminserver.authenticationLdapFilter }}" + LDAP_UID: "{{ .Values.adminserver.authenticationLdapUID }}" + LDAP_SCOPE: "{{ .Values.adminserver.authenticationLdapScope }}" + LDAP_TIMEOUT: "{{ .Values.adminserver.authenticationLdapTimeout }}" + LDAP_VERIFY_CERT: "{{ .Values.adminserver.authenticationLdapVerifyCert }}" DATABASE_TYPE: "mysql" PROJECT_CREATION_RESTRICTION: "everyone" VERIFY_REMOTE_CERT: "off" diff --git a/contrib/helm/harbor/values.yaml b/contrib/helm/harbor/values.yaml index 737bf2b74..39efff4ef 100644 --- a/contrib/helm/harbor/values.yaml +++ b/contrib/helm/harbor/values.yaml @@ -66,6 +66,16 @@ adminserver: emailInsecure: "False" emailPwd: not-a-secure-password harborAdminPassword: Harbor12345 + harborAuthenticationMode: "db_auth" + selfRegistration: "on" + authenticationLdapURL: "ldaps://ldapserver" + authenticationLdapSearchDN: "" + authenticationLdapBaseDN: "" + authenticationLdapFilter: "(objectClass=person)" + authenticationLdapUID: "uid" + authenticationLdapScope: "2" + authenticationLdapTimeout: "5" + authenticationLdapVerifyCert: "True" ## Persist data to a persistent volume volumes: config: From 42fa690f902dd08365455694fc86f74786a17c05 Mon Sep 17 00:00:00 2001 From: pfh Date: Tue, 27 Mar 2018 10:12:37 +0800 Subject: [PATCH 06/15] Modify tag detail page and fix label bugs --- src/ui_ng/lib/src/config/config.ts | 2 ++ .../create-edit-label.component.css.ts | 4 +-- .../create-edit-label.component.ts | 20 +++++------ .../lib/src/service/repository.service.ts | 2 +- .../lib/src/tag/tag-detail.component.css.ts | 21 +++++++---- .../lib/src/tag/tag-detail.component.html.ts | 35 +++++++++---------- .../lib/src/tag/tag-detail.component.spec.ts | 17 +++++++-- src/ui_ng/lib/src/tag/tag-detail.component.ts | 4 ++- src/ui_ng/lib/src/tag/tag.component.css.ts | 7 ++++ src/ui_ng/lib/src/tag/tag.component.html.ts | 6 ++-- src/ui_ng/lib/src/tag/tag.component.spec.ts | 7 ---- src/ui_ng/lib/src/tag/tag.component.ts | 8 ++--- src/ui_ng/package.json | 2 +- src/ui_ng/src/app/harbor-routing.module.ts | 12 ++++--- .../tag-detail/tag-detail-page.component.html | 2 +- .../tag-detail/tag-detail-page.component.ts | 4 +-- src/ui_ng/src/i18n/lang/en-us-lang.json | 3 ++ src/ui_ng/src/i18n/lang/es-es-lang.json | 9 +++-- src/ui_ng/src/i18n/lang/zh-cn-lang.json | 7 +++- 19 files changed, 104 insertions(+), 68 deletions(-) diff --git a/src/ui_ng/lib/src/config/config.ts b/src/ui_ng/lib/src/config/config.ts index f3b80b8d7..624967756 100644 --- a/src/ui_ng/lib/src/config/config.ts +++ b/src/ui_ng/lib/src/config/config.ts @@ -81,6 +81,7 @@ export class Configuration { token_expiration: NumberValueItem; cfg_expiration: NumberValueItem; scan_all_policy: ComplexValueItem; + read_only: BoolValueItem; public constructor() { this.auth_mode = new StringValueItem("db_auth", true); @@ -116,5 +117,6 @@ export class Configuration { daily_time: 0 } }, true); + this.read_only = new BoolValueItem(false, true); } } \ No newline at end of file diff --git a/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.css.ts b/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.css.ts index 4653a70d1..8bf46d759 100644 --- a/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.css.ts +++ b/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.css.ts @@ -10,8 +10,8 @@ export const CREATE_EDIT_LABEL_STYLE: string = ` section{padding:.5rem 0;} section> label{margin-left: 20px;} - .dropdown-menu{display:inline-block;width:166px; padding:6px;} - .dropdown-item{ display:inline-flex; margin:2px 4px; + .dropdown-menu {display:inline-block;width:166px; padding:6px;} + .dropdown-menu .dropdown-item{ display:inline-flex; margin:2px 4px; display: inline-block;padding: 0px; width:30px;height:24px; text-align: center;line-height: 24px;} .btnColor{ margin: 0 !important; diff --git a/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.ts b/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.ts index c1e838231..1c35656a4 100644 --- a/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.ts +++ b/src/ui_ng/lib/src/create-edit-label/create-edit-label.component.ts @@ -16,7 +16,7 @@ import { Output, EventEmitter, OnDestroy, - Input, OnInit, ViewChild + Input, OnInit, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; @@ -27,16 +27,15 @@ import { CREATE_EDIT_LABEL_TEMPLATE } from './create-edit-label.component.html'; import {toPromise, clone, compareValue} from '../utils'; -import {Subject} from "rxjs/Subject"; - import {LabelService} from "../service/label.service"; import {ErrorHandler} from "../error-handler/error-handler"; import {NgForm} from "@angular/forms"; +import {Subject} from "rxjs/Subject"; @Component({ selector: 'hbr-create-edit-label', template: CREATE_EDIT_LABEL_TEMPLATE, - styles: [CREATE_EDIT_LABEL_STYLE] + styles: [CREATE_EDIT_LABEL_STYLE], }) export class CreateEditLabelComponent implements OnInit, OnDestroy { @@ -46,12 +45,13 @@ export class CreateEditLabelComponent implements OnInit, OnDestroy { labelModel: Label = this.initLabel(); labelId = 0; - nameChecker: Subject = new Subject(); checkOnGoing: boolean; isLabelNameExist = false; labelColor = ['#00ab9a', '#9da3db', '#be90d6', '#9b0d54', '#f52f22', '#747474', '#0095d3', '#f38b00', ' #62a420', '#89cbdf', '#004a70', '#9460b8']; + nameChecker = new Subject(); + labelForm: NgForm; @ViewChild('labelForm') currentForm: NgForm; @@ -66,16 +66,12 @@ export class CreateEditLabelComponent implements OnInit, OnDestroy { ) { } ngOnInit(): void { - this.nameChecker.debounceTime(500).distinctUntilChanged().subscribe((name: string) => { + this.nameChecker.debounceTime(500).subscribe((name: string) => { this.checkOnGoing = true; - toPromise(this.labelService.getLabels(this.scope, this.projectId)) + toPromise(this.labelService.getLabels(this.scope, this.projectId, name)) .then(targets => { if (targets && targets.length) { - if (targets.find(m => m.name === name)) { - this.isLabelNameExist = true; - } else { - this.isLabelNameExist = false; - }; + this.isLabelNameExist = true; }else { this.isLabelNameExist = false; } diff --git a/src/ui_ng/lib/src/service/repository.service.ts b/src/ui_ng/lib/src/service/repository.service.ts index 546955271..4e1db7fa0 100644 --- a/src/ui_ng/lib/src/service/repository.service.ts +++ b/src/ui_ng/lib/src/service/repository.service.ts @@ -140,6 +140,6 @@ export class RepositoryDefaultService extends RepositoryService { return this.http.delete(url, HTTP_JSON_OPTIONS).toPromise() .then(response => response) - .catch(error => { Promise.reject(error); }); + .catch(error => {return Promise.reject(error); }); } } diff --git a/src/ui_ng/lib/src/tag/tag-detail.component.css.ts b/src/ui_ng/lib/src/tag/tag-detail.component.css.ts index 2bfb781d8..f17860614 100644 --- a/src/ui_ng/lib/src/tag/tag-detail.component.css.ts +++ b/src/ui_ng/lib/src/tag/tag-detail.component.css.ts @@ -1,6 +1,5 @@ export const TAG_DETAIL_STYLES: string = ` .overview-section { - background-color: white; padding-bottom: 36px; border-bottom: 1px solid #cccccc; } @@ -78,27 +77,37 @@ export const TAG_DETAIL_STYLES: string = ` padding-left: 24px; } -.vulnerabilities-info .third-column { + .third-column { margin-left: 36px; } +.vulnerability{ +margin-left: 50px; + margin-top: -12px; + margin-bottom: 20px;} -.vulnerabilities-info .second-column, -.vulnerabilities-info .fourth-column { +.vulnerabilities-info .second-column { text-align: left; margin-left: 6px; } +.fourth-column{ +float: left; +margin-left:20px;} + .vulnerabilities-info .second-row { margin-top: 6px; } .detail-title { - font-weight: 500; + float:left; + font-weight: 600; font-size: 14px; } .image-detail-label { - text-align: right; + margin-right: 10px; + text-align: left; + font-weight: 600; } .image-detail-value { diff --git a/src/ui_ng/lib/src/tag/tag-detail.component.html.ts b/src/ui_ng/lib/src/tag/tag-detail.component.html.ts index 0b92947bd..ab6dde6ae 100644 --- a/src/ui_ng/lib/src/tag/tag-detail.component.html.ts +++ b/src/ui_ng/lib/src/tag/tag-detail.component.html.ts @@ -7,26 +7,22 @@ export const TAG_DETAIL_HTML: string = `
-

{{tagDetails.name}}

-
-
- {{'TAG.CREATION_TIME_PREFIX' | translate }} {{tagDetails.created | date }} {{'TAG.CREATOR_PREFIX' | translate }} {{author | translate}} +

{{repositoryId}}:{{tagDetails.name}}

-
- {{'TAG.IMAGE_DETAILS' | translate }} -
+
{{'TAG.AUTHOR' | translate }}
{{'TAG.ARCHITECTURE' | translate }}
{{'TAG.OS' | translate }}
{{'TAG.DOCKER_VERSION' | translate }}
{{'TAG.SCAN_COMPLETION_TIME' | translate }}
+
{{author | translate}}
{{tagDetails.architecture}}
{{tagDetails.os}}
{{tagDetails.docker_version}}
@@ -35,8 +31,8 @@ export const TAG_DETAIL_HTML: string = `
-
- {{'TAG.IMAGE_VULNERABILITIES' | translate }} +
+
@@ -46,12 +42,6 @@ export const TAG_DETAIL_HTML: string = `
-
-
-
{{highCount}} {{'VULNERABILITY.SEVERITY.HIGH' | translate }}
-
{{mediumCount}} {{'VULNERABILITY.SEVERITY.MEDIUM' | translate }}
-
-
@@ -59,11 +49,20 @@ export const TAG_DETAIL_HTML: string = `
-
-
{{lowCount}} {{'VULNERABILITY.SEVERITY.LOW' | translate }}
-
{{unknownCount}} {{'VULNERABILITY.SEVERITY.UNKNOWN' | translate }}
+
+
{{highCount}} {{'VULNERABILITY.SEVERITY.HIGH' | translate }}{{'TAG.LEVEL_VULNERABILITIES' | translate }}
+
{{mediumCount}} {{'VULNERABILITY.SEVERITY.MEDIUM' | translate }}{{'TAG.LEVEL_VULNERABILITIES' | translate }}
+
{{lowCount}} {{'VULNERABILITY.SEVERITY.LOW' | translate }}{{'TAG.LEVEL_VULNERABILITIES' | translate }}
+
{{unknownCount}} {{'VULNERABILITY.SEVERITY.UNKNOWN' | translate }}{{'TAG.LEVEL_VULNERABILITIES' | translate }}
+ +
+
+
{{'TAG.LABELS' | translate }}
+
+
+
diff --git a/src/ui_ng/lib/src/tag/tag-detail.component.spec.ts b/src/ui_ng/lib/src/tag/tag-detail.component.spec.ts index 876297038..20da427dd 100644 --- a/src/ui_ng/lib/src/tag/tag-detail.component.spec.ts +++ b/src/ui_ng/lib/src/tag/tag-detail.component.spec.ts @@ -10,6 +10,11 @@ import { SERVICE_CONFIG, IServiceConfig } from '../service.config'; import { TagService, TagDefaultService, ScanningResultService, ScanningResultDefaultService } from '../service/index'; import { FilterComponent } from '../filter/index'; import { VULNERABILITY_SCAN_STATUS } from '../utils'; +import {VULNERABILITY_DIRECTIVES} from "../vulnerability-scanning/index"; +import {LabelPieceComponent} from "../label-piece/label-piece.component"; +import {JobLogViewerComponent} from "../job-log-viewer/job-log-viewer.component"; +import {ChannelService} from "../channel/channel.service"; +import {JobLogService, JobLogDefaultService} from "../service/job-log.service"; describe('TagDetailComponent (inline template)', () => { @@ -66,10 +71,16 @@ describe('TagDetailComponent (inline template)', () => { declarations: [ TagDetailComponent, ResultGridComponent, + VULNERABILITY_DIRECTIVES, + LabelPieceComponent, + JobLogViewerComponent, FilterComponent ], providers: [ ErrorHandler, + ChannelService, + JobLogDefaultService, + {provide: JobLogService, useClass: JobLogDefaultService}, { provide: SERVICE_CONFIG, useValue: config }, { provide: TagService, useClass: TagDefaultService }, { provide: ScanningResultService, useClass: ScanningResultDefaultService } @@ -119,7 +130,7 @@ describe('TagDetailComponent (inline template)', () => { let el: HTMLElement = fixture.nativeElement.querySelector('.tag-name'); expect(el).toBeTruthy(); - expect(el.textContent.trim()).toEqual('nginx'); + expect(el.textContent.trim()).toEqual('mock_repo:nginx'); }); })); @@ -133,7 +144,7 @@ describe('TagDetailComponent (inline template)', () => { expect(el).toBeTruthy(); let el2: HTMLElement = el.querySelector('div'); expect(el2).toBeTruthy(); - expect(el2.textContent).toEqual("amd64"); + expect(el2.textContent).toEqual("steven"); }); })); @@ -147,7 +158,7 @@ describe('TagDetailComponent (inline template)', () => { expect(el).toBeTruthy(); let el2: HTMLElement = el.querySelector('div'); expect(el2).toBeTruthy(); - expect(el2.textContent.trim()).toEqual("13 VULNERABILITY.SEVERITY.HIGH"); + expect(el2.textContent.trim()).toEqual("13 VULNERABILITY.SEVERITY.HIGHTAG.LEVEL_VULNERABILITIES"); }); })); diff --git a/src/ui_ng/lib/src/tag/tag-detail.component.ts b/src/ui_ng/lib/src/tag/tag-detail.component.ts index 617b04f48..5a98ef8b3 100644 --- a/src/ui_ng/lib/src/tag/tag-detail.component.ts +++ b/src/ui_ng/lib/src/tag/tag-detail.component.ts @@ -6,6 +6,7 @@ import { TAG_DETAIL_HTML } from './tag-detail.component.html'; import { TagService, Tag, VulnerabilitySeverity } from '../service/index'; import { toPromise } from '../utils'; import { ErrorHandler } from '../error-handler/index'; +import {Label} from "../service/interface"; @Component({ selector: 'hbr-tag-detail', @@ -19,6 +20,7 @@ export class TagDetailComponent implements OnInit { _mediumCount: number = 0; _lowCount: number = 0; _unknownCount: number = 0; + labels: Label; @Input() tagId: string; @Input() repositoryId: string; @@ -74,7 +76,7 @@ export class TagDetailComponent implements OnInit { } onBack(): void { - this.backEvt.emit(this.tagId); + this.backEvt.emit(this.repositoryId); } getPackageText(count: number): string { diff --git a/src/ui_ng/lib/src/tag/tag.component.css.ts b/src/ui_ng/lib/src/tag/tag.component.css.ts index 34442217e..36f5e96e6 100644 --- a/src/ui_ng/lib/src/tag/tag.component.css.ts +++ b/src/ui_ng/lib/src/tag/tag.component.css.ts @@ -66,4 +66,11 @@ export const TAG_STYLE = ` :host >>> .signpost-content-body{padding:0 .4rem;} :host >>> .signpost-content-header{display:none;} .filterLabelPiece{position: absolute; bottom :0px;z-index:1;} +.dropdown .dropdown-toggle.btn { + padding-right: 1rem; + border-left-width: 0; + border-right-width: 0; + border-radius: 0; + margin-top: -2px; +} `; \ No newline at end of file diff --git a/src/ui_ng/lib/src/tag/tag.component.html.ts b/src/ui_ng/lib/src/tag/tag.component.html.ts index b578b6de7..96be13e60 100644 --- a/src/ui_ng/lib/src/tag/tag.component.html.ts +++ b/src/ui_ng/lib/src/tag/tag.component.html.ts @@ -21,7 +21,7 @@ export const TAG_TEMPLATE = `
- +
{{'LABEL.NO_LABELS' | translate }}
@@ -52,10 +52,10 @@ export const TAG_TEMPLATE = `
{{'LABEL.NO_LABELS' | translate }}
-
diff --git a/src/ui_ng/lib/src/tag/tag.component.spec.ts b/src/ui_ng/lib/src/tag/tag.component.spec.ts index ec8291ab6..983498796 100644 --- a/src/ui_ng/lib/src/tag/tag.component.spec.ts +++ b/src/ui_ng/lib/src/tag/tag.component.spec.ts @@ -140,13 +140,6 @@ describe('TagComponent (inline template)', () => { labelService = fixture.debugElement.injector.get(LabelService); - /*spyLabels = spyOn(labelService, 'getLabels').and.callFake(function (param) { - if (param === 'g') { - return Promise.resolve(mockLabels); - }else { - Promise.resolve(mockLabels1) - } - })*/ spyLabels = spyOn(labelService, 'getGLabels').and.returnValues(Promise.resolve(mockLabels)); spyLabels1 = spyOn(labelService, 'getPLabels').and.returnValues(Promise.resolve(mockLabels1)); diff --git a/src/ui_ng/lib/src/tag/tag.component.ts b/src/ui_ng/lib/src/tag/tag.component.ts index c75438967..4999baf5a 100644 --- a/src/ui_ng/lib/src/tag/tag.component.ts +++ b/src/ui_ng/lib/src/tag/tag.component.ts @@ -180,11 +180,11 @@ export class TagComponent implements OnInit, AfterViewInit { .subscribe((name: string) => { if (name && name.length) { this.filterOnGoing = true; - this.imageFilterLabels = []; + this.imageStickLabels = []; this.imageLabels.forEach(data => { if (data.label.name.indexOf(name) !== -1) { - this.imageFilterLabels.push(data); + this.imageStickLabels.push(data); } }) setTimeout(() => { @@ -302,7 +302,7 @@ export class TagComponent implements OnInit, AfterViewInit { this.selectedChange(tag); } selectLabel(labelInfo: {[key: string]: any | string[]}): void { - if (labelInfo && labelInfo.iconsShow) { + if (labelInfo && !labelInfo.iconsShow) { let labelId = labelInfo.label.id; this.selectedRow = this.selectedTag; toPromise(this.tagService.addLabelToImages(this.repoName, this.selectedRow[0].name, labelId)).then(res => { @@ -314,7 +314,7 @@ export class TagComponent implements OnInit, AfterViewInit { } unSelectLabel(labelInfo: {[key: string]: any | string[]}): void { - if (labelInfo && !labelInfo.iconsShow) { + if (labelInfo && labelInfo.iconsShow) { let labelId = labelInfo.label.id; this.selectedRow = this.selectedTag; toPromise(this.tagService.deleteLabelToImages(this.repoName, this.selectedRow[0].name, labelId)).then(res => { diff --git a/src/ui_ng/package.json b/src/ui_ng/package.json index 5f5b8cf95..ebc5040c4 100644 --- a/src/ui_ng/package.json +++ b/src/ui_ng/package.json @@ -31,7 +31,7 @@ "clarity-icons": "^0.10.17", "clarity-ui": "^0.10.27", "core-js": "^2.4.1", - "harbor-ui": "0.6.53", + "harbor-ui": "0.6.57", "intl": "^1.2.5", "mutationobserver-shim": "^0.3.2", "ngx-cookie": "^1.0.0", diff --git a/src/ui_ng/src/app/harbor-routing.module.ts b/src/ui_ng/src/app/harbor-routing.module.ts index cdd547be5..6f42705dd 100644 --- a/src/ui_ng/src/app/harbor-routing.module.ts +++ b/src/ui_ng/src/app/harbor-routing.module.ts @@ -108,6 +108,14 @@ const harborRoutes: Routes = [ projectResolver: ProjectRoutingResolver } }, + { + path: 'projects/:id/repositories/:repo/tags/:tag', + component: TagDetailPageComponent, + canActivate: [MemberGuard], + resolve: { + projectResolver: ProjectRoutingResolver + }, + }, { path: 'projects/:id', component: ProjectDetailComponent, @@ -124,10 +132,6 @@ const harborRoutes: Routes = [ path: 'repositories/:repo/tags', component: TagRepositoryComponent, }, - { - path: 'repositories/:repo/tags/:tag', - component: TagDetailPageComponent - }, { path: 'replications', component: ReplicationPageComponent, diff --git a/src/ui_ng/src/app/repository/tag-detail/tag-detail-page.component.html b/src/ui_ng/src/app/repository/tag-detail/tag-detail-page.component.html index 3c047ba42..f95fc141b 100644 --- a/src/ui_ng/src/app/repository/tag-detail/tag-detail-page.component.html +++ b/src/ui_ng/src/app/repository/tag-detail/tag-detail-page.component.html @@ -1,3 +1,3 @@ -
+
\ No newline at end of file diff --git a/src/ui_ng/src/app/repository/tag-detail/tag-detail-page.component.ts b/src/ui_ng/src/app/repository/tag-detail/tag-detail-page.component.ts index 27b3dd2d5..7dc45c42b 100644 --- a/src/ui_ng/src/app/repository/tag-detail/tag-detail-page.component.ts +++ b/src/ui_ng/src/app/repository/tag-detail/tag-detail-page.component.ts @@ -32,10 +32,10 @@ export class TagDetailPageComponent implements OnInit { ngOnInit(): void { this.repositoryId = this.route.snapshot.params["repo"]; this.tagId = this.route.snapshot.params["tag"]; - this.projectId = this.route.snapshot.parent.params["id"]; + this.projectId = this.route.snapshot.params["id"]; } goBack(tag: string): void { - this.router.navigate(["harbor", "projects", this.projectId, "repositories"]); + this.router.navigate(["harbor", "projects", this.projectId, "repositories", tag]); } } \ No newline at end of file diff --git a/src/ui_ng/src/i18n/lang/en-us-lang.json b/src/ui_ng/src/i18n/lang/en-us-lang.json index 7a6d5c4f7..f776b61e3 100644 --- a/src/ui_ng/src/i18n/lang/en-us-lang.json +++ b/src/ui_ng/src/i18n/lang/en-us-lang.json @@ -415,6 +415,7 @@ "IMAGE": "Images", "LABELS": ":labels", "ADD_TO_IMAGE": "Add labels to this image", + "FILTER_BY_LABEL": "Filter projects by label", "ADD_LABELS": "Add labels" }, "ALERT": { @@ -438,6 +439,8 @@ "REPLICATION": "Replication", "EMAIL": "Email", "LABEL": "Label", + "REPOSITORY": "Repository", + "REPO_READ_ONLY": "Repository Read Only", "SYSTEM": "System Settings", "VULNERABILITY": "Vulnerability", "CONFIRM_TITLE": "Confirm to cancel", diff --git a/src/ui_ng/src/i18n/lang/es-es-lang.json b/src/ui_ng/src/i18n/lang/es-es-lang.json index 9e1ad70ed..70a19d087 100644 --- a/src/ui_ng/src/i18n/lang/es-es-lang.json +++ b/src/ui_ng/src/i18n/lang/es-es-lang.json @@ -413,7 +413,7 @@ "INFO": "Información", "NO_INFO": "Sin información de descripción para este repositorio", "IMAGE": "Imágenes", - "LABELS": ":labels", + "LABELS": "Labels", "ADD_TO_IMAGE": "Add labels to this image", "ADD_LABELS": "Add labels" }, @@ -438,6 +438,8 @@ "REPLICATION": "Replicación", "EMAIL": "Email", "LABEL": "Label", + "REPOSITORY": "Repository", + "REPO_READ_ONLY": "Repository Read Only", "SYSTEM": "Opciones del Sistema", "VULNERABILITY": "Vulnerability", "CONFIRM_TITLE": "Confirma cancelación", @@ -613,9 +615,12 @@ "OS": "OS", "SCAN_COMPLETION_TIME": "Scan Completed", "IMAGE_VULNERABILITIES": "Image Vulnerabilities", + "LEVEL_VULNERABILITIES": "Level Vulnerabilities", "PLACEHOLDER": "We couldn't find any tags!", "COPY_ERROR": "Copy failed, please try to manually copy.", - "FILTER_FOR_TAGS": "Etiquetas de filtro" + "FILTER_FOR_TAGS": "Etiquetas de filtro", + "AUTHOR": "Author", + "LABELS": "LABELS" }, "LABEL": { "LABEL": "Label", diff --git a/src/ui_ng/src/i18n/lang/zh-cn-lang.json b/src/ui_ng/src/i18n/lang/zh-cn-lang.json index 0fe5c6aa9..ce2ff9b34 100644 --- a/src/ui_ng/src/i18n/lang/zh-cn-lang.json +++ b/src/ui_ng/src/i18n/lang/zh-cn-lang.json @@ -438,6 +438,8 @@ "REPLICATION": "复制", "EMAIL": "邮箱", "LABEL": "标签", + "REPOSITORY": "仓库", + "REPO_READ_ONLY": "仓库只读", "SYSTEM": "系统设置", "VULNERABILITY": "漏洞", "CONFIRM_TITLE": "确认取消", @@ -613,9 +615,12 @@ "OS": "操作系统", "SCAN_COMPLETION_TIME": "扫描完成时间", "IMAGE_VULNERABILITIES": "镜像缺陷", + "LEVEL_VULNERABILITIES": "缺陷等级", "PLACEHOLDER": "未发现任何标签!", "COPY_ERROR": "拷贝失败,请尝试手动拷贝。", - "FILTER_FOR_TAGS": "过滤项目" + "FILTER_FOR_TAGS": "过滤项目", + "AUTHOR": "作者", + "LABELS": "标签" }, "LABEL": { "LABEL": "标签", From 22fa1ba189f953e57d0cd4ee979483139870d482 Mon Sep 17 00:00:00 2001 From: pfh Date: Tue, 27 Mar 2018 14:31:18 +0800 Subject: [PATCH 07/15] Add control about label for admiral and standalone --- src/ui_ng/lib/src/repository/repository.component.html.ts | 2 +- src/ui_ng/lib/src/repository/repository.component.ts | 1 + src/ui_ng/lib/src/tag/tag-detail.component.html.ts | 2 +- src/ui_ng/lib/src/tag/tag-detail.component.ts | 1 + src/ui_ng/lib/src/tag/tag.component.html.ts | 5 +++-- src/ui_ng/lib/src/tag/tag.component.ts | 2 +- src/ui_ng/package.json | 2 +- src/ui_ng/src/app/config/config.component.html | 7 +++---- src/ui_ng/src/app/config/config.component.ts | 4 ++++ .../project/project-detail/project-detail.component.html | 2 +- .../app/project/project-detail/project-detail.component.ts | 6 ++++++ .../repository/tag-detail/tag-detail-page.component.html | 2 +- .../app/repository/tag-detail/tag-detail-page.component.ts | 6 ++++++ .../tag-repository/tag-repository.component.html | 2 +- .../repository/tag-repository/tag-repository.component.ts | 4 ++++ 15 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/ui_ng/lib/src/repository/repository.component.html.ts b/src/ui_ng/lib/src/repository/repository.component.html.ts index 50c5dec87..e22ad9ae0 100644 --- a/src/ui_ng/lib/src/repository/repository.component.html.ts +++ b/src/ui_ng/lib/src/repository/repository.component.html.ts @@ -46,7 +46,7 @@ export const REPOSITORY_TEMPLATE = `
- +
diff --git a/src/ui_ng/lib/src/repository/repository.component.ts b/src/ui_ng/lib/src/repository/repository.component.ts index cfe1c24dd..82c9e7096 100644 --- a/src/ui_ng/lib/src/repository/repository.component.ts +++ b/src/ui_ng/lib/src/repository/repository.component.ts @@ -54,6 +54,7 @@ export class RepositoryComponent implements OnInit { @Input() isGuest: boolean; @Input() withNotary: boolean; @Input() withClair: boolean; + @Input() withAdmiral: boolean; @Output() tagClickEvent = new EventEmitter(); @Output() backEvt: EventEmitter = new EventEmitter(); diff --git a/src/ui_ng/lib/src/tag/tag-detail.component.html.ts b/src/ui_ng/lib/src/tag/tag-detail.component.html.ts index ab6dde6ae..127e5b52e 100644 --- a/src/ui_ng/lib/src/tag/tag-detail.component.html.ts +++ b/src/ui_ng/lib/src/tag/tag-detail.component.html.ts @@ -58,7 +58,7 @@ export const TAG_DETAIL_HTML: string = `
-
+
{{'TAG.LABELS' | translate }}
diff --git a/src/ui_ng/lib/src/tag/tag-detail.component.ts b/src/ui_ng/lib/src/tag/tag-detail.component.ts index 5a98ef8b3..9a1be6b3a 100644 --- a/src/ui_ng/lib/src/tag/tag-detail.component.ts +++ b/src/ui_ng/lib/src/tag/tag-detail.component.ts @@ -24,6 +24,7 @@ export class TagDetailComponent implements OnInit { @Input() tagId: string; @Input() repositoryId: string; + @Input() withAdmiral: boolean; tagDetails: Tag = { name: "--", size: "--", diff --git a/src/ui_ng/lib/src/tag/tag.component.html.ts b/src/ui_ng/lib/src/tag/tag.component.html.ts index 96be13e60..381660994 100644 --- a/src/ui_ng/lib/src/tag/tag.component.html.ts +++ b/src/ui_ng/lib/src/tag/tag.component.html.ts @@ -17,7 +17,8 @@ export const TAG_TEMPLATE = `
- + +
@@ -44,7 +45,7 @@ export const TAG_TEMPLATE = `
- +
diff --git a/src/ui_ng/lib/src/tag/tag.component.ts b/src/ui_ng/lib/src/tag/tag.component.ts index 4999baf5a..8f44593f2 100644 --- a/src/ui_ng/lib/src/tag/tag.component.ts +++ b/src/ui_ng/lib/src/tag/tag.component.ts @@ -80,7 +80,7 @@ export class TagComponent implements OnInit, AfterViewInit { @Input() registryUrl: string; @Input() withNotary: boolean; @Input() withClair: boolean; - + @Input() withAdmiral: boolean; @Output() refreshRepo = new EventEmitter(); @Output() tagClickEvent = new EventEmitter(); @Output() signatureOutput = new EventEmitter(); diff --git a/src/ui_ng/package.json b/src/ui_ng/package.json index ebc5040c4..52ae9f4cb 100644 --- a/src/ui_ng/package.json +++ b/src/ui_ng/package.json @@ -31,7 +31,7 @@ "clarity-icons": "^0.10.17", "clarity-ui": "^0.10.27", "core-js": "^2.4.1", - "harbor-ui": "0.6.57", + "harbor-ui": "0.6.58", "intl": "^1.2.5", "mutationobserver-shim": "^0.3.2", "ngx-cookie": "^1.0.0", diff --git a/src/ui_ng/src/app/config/config.component.html b/src/ui_ng/src/app/config/config.component.html index fee0a3a17..6f00dce28 100644 --- a/src/ui_ng/src/app/config/config.component.html +++ b/src/ui_ng/src/app/config/config.component.html @@ -12,7 +12,7 @@ - -
-
+
{{'TAG.LABELS' | translate }}
diff --git a/src/ui_ng/lib/src/tag/tag.component.html.ts b/src/ui_ng/lib/src/tag/tag.component.html.ts index 381660994..36d3e5fac 100644 --- a/src/ui_ng/lib/src/tag/tag.component.html.ts +++ b/src/ui_ng/lib/src/tag/tag.component.html.ts @@ -17,8 +17,8 @@ export const TAG_TEMPLATE = `
- - + +
@@ -39,31 +39,29 @@ export const TAG_TEMPLATE = `
-
+
-
- - - -
- -
-
{{'LABEL.NO_LABELS' | translate }}
-
- -
-
-
-
+ + + +
+ +
+
{{'LABEL.NO_LABELS' | translate }}
+
+ +
+
+
+
-
{{'REPOSITORY.TAG' | translate}} {{'REPOSITORY.SIZE' | translate}} @@ -73,7 +71,7 @@ export const TAG_TEMPLATE = ` {{'REPOSITORY.AUTHOR' | translate}} {{'REPOSITORY.CREATED' | translate}} {{'REPOSITORY.DOCKER_VERSION' | translate}} - {{'REPOSITORY.LABELS' | translate}} + {{'REPOSITORY.LABELS' | translate}} {{'TAG.PLACEHOLDER' | translate }} @@ -98,7 +96,7 @@ export const TAG_TEMPLATE = ` {{t.author}} {{t.created | date: 'short'}} {{t.docker_version}} - +
@@ -114,7 +112,7 @@ export const TAG_TEMPLATE = `
- + {{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} {{'REPOSITORY.OF' | translate}} {{pagination.totalItems}} {{'REPOSITORY.ITEMS' | translate}}     diff --git a/src/ui_ng/lib/src/tag/tag.component.ts b/src/ui_ng/lib/src/tag/tag.component.ts index d0e2dda27..ee0137069 100644 --- a/src/ui_ng/lib/src/tag/tag.component.ts +++ b/src/ui_ng/lib/src/tag/tag.component.ts @@ -196,7 +196,9 @@ export class TagComponent implements OnInit, AfterViewInit { } ngAfterViewInit() { - this.getAllLabels(); + if (!this.withAdmiral) { + this.getAllLabels(); + } } public get filterLabelPieceWidth() { diff --git a/src/ui_ng/package.json b/src/ui_ng/package.json index 52ae9f4cb..7940d6aa6 100644 --- a/src/ui_ng/package.json +++ b/src/ui_ng/package.json @@ -31,7 +31,7 @@ "clarity-icons": "^0.10.17", "clarity-ui": "^0.10.27", "core-js": "^2.4.1", - "harbor-ui": "0.6.58", + "harbor-ui": "0.6.61", "intl": "^1.2.5", "mutationobserver-shim": "^0.3.2", "ngx-cookie": "^1.0.0", diff --git a/src/ui_ng/src/app/repository/repository-page.component.html b/src/ui_ng/src/app/repository/repository-page.component.html index 13cc9c0c1..06f72277d 100644 --- a/src/ui_ng/src/app/repository/repository-page.component.html +++ b/src/ui_ng/src/app/repository/repository-page.component.html @@ -1,4 +1,5 @@
- +
\ No newline at end of file diff --git a/src/ui_ng/src/app/repository/tag-repository/tag-repository.component.ts b/src/ui_ng/src/app/repository/tag-repository/tag-repository.component.ts index 9a10273d7..96708a18e 100644 --- a/src/ui_ng/src/app/repository/tag-repository/tag-repository.component.ts +++ b/src/ui_ng/src/app/repository/tag-repository/tag-repository.component.ts @@ -79,6 +79,7 @@ export class TagRepositoryComponent implements OnInit { hasChanges(): boolean { return this.repositoryComponent.hasChanges(); } + watchTagClickEvt(tagEvt: TagClickEvent): void { let linkUrl = ['harbor', 'projects', tagEvt.project_id, 'repositories', tagEvt.repository_name, 'tags', tagEvt.tag_name]; this.router.navigate(linkUrl); diff --git a/src/ui_ng/src/i18n/lang/en-us-lang.json b/src/ui_ng/src/i18n/lang/en-us-lang.json index f776b61e3..525ed7bd8 100644 --- a/src/ui_ng/src/i18n/lang/en-us-lang.json +++ b/src/ui_ng/src/i18n/lang/en-us-lang.json @@ -404,6 +404,7 @@ "REPOSITORIES": "Repositories", "OF": "of", "ITEMS": "items", + "NO_ITEMS": "NO ITEMS", "POP_REPOS": "Popular Repositories", "DELETED_REPO_SUCCESS": "Deleted repositories successfully.", "DELETED_TAG_SUCCESS": "Deleted tags successfully.", @@ -416,7 +417,10 @@ "LABELS": ":labels", "ADD_TO_IMAGE": "Add labels to this image", "FILTER_BY_LABEL": "Filter projects by label", - "ADD_LABELS": "Add labels" + "ADD_LABELS": "Add labels", + "ACTION": "ACTION", + "DEPLOY": "DEPLOY", + "ADDITIONAL_INFO": "Add Additional Info" }, "ALERT": { "FORM_CHANGE_CONFIRMATION": "Some changes are not saved yet. Do you want to cancel?" diff --git a/src/ui_ng/src/i18n/lang/es-es-lang.json b/src/ui_ng/src/i18n/lang/es-es-lang.json index 70a19d087..9f3f9d00c 100644 --- a/src/ui_ng/src/i18n/lang/es-es-lang.json +++ b/src/ui_ng/src/i18n/lang/es-es-lang.json @@ -404,6 +404,7 @@ "REPOSITORIES": "Repositorios", "OF": "of", "ITEMS": "elementos", + "NO_ITEMS": "NO ITEMS", "POP_REPOS": "Repositorios Populares", "DELETED_REPO_SUCCESS": "Repositorio eliminado satisfactoriamente.", "DELETED_TAG_SUCCESS": "Etiqueta eliminada satisfactoriamente.", @@ -415,7 +416,11 @@ "IMAGE": "Imágenes", "LABELS": "Labels", "ADD_TO_IMAGE": "Add labels to this image", - "ADD_LABELS": "Add labels" + "ADD_LABELS": "Add labels", + "FILTER_BY_LABEL": "Filter projects by label", + "ACTION": "ACTION", + "DEPLOY": "DEPLOY", + "ADDITIONAL_INFO": "Add Additional Info" }, "ALERT": { "FORM_CHANGE_CONFIRMATION": "Algunos cambios no se han guardado aún. ¿Quiere cancelar?" diff --git a/src/ui_ng/src/i18n/lang/fr-fr-lang.json b/src/ui_ng/src/i18n/lang/fr-fr-lang.json index 28784f9fe..0c965db34 100644 --- a/src/ui_ng/src/i18n/lang/fr-fr-lang.json +++ b/src/ui_ng/src/i18n/lang/fr-fr-lang.json @@ -364,7 +364,11 @@ "DELETED_TAG_SUCCESS": "Tag supprimé avec succés.", "COPY": "Copier", "NOTARY_IS_UNDETERMINED": "Ne peut pas déterminer la signature de ce tag.", - "PLACEHOLDER": "Nous ne trouvons aucun dépôt !" + "PLACEHOLDER": "Nous ne trouvons aucun dépôt !", + "IMAGE": "Images", + "ACTION": "ACTION", + "DEPLOY": "DEPLOY", + "ADDITIONAL_INFO": "Add Additional Info" }, "ALERT": { "FORM_CHANGE_CONFIRMATION": "Certaines modifications ne sont pas encore enregistrées. Voulez-vous annuler ?" diff --git a/src/ui_ng/src/i18n/lang/zh-cn-lang.json b/src/ui_ng/src/i18n/lang/zh-cn-lang.json index ce2ff9b34..e61f2b90f 100644 --- a/src/ui_ng/src/i18n/lang/zh-cn-lang.json +++ b/src/ui_ng/src/i18n/lang/zh-cn-lang.json @@ -404,6 +404,7 @@ "REPOSITORIES": "镜像仓库", "OF": "共计", "ITEMS": "条记录", + "NO_ITEMS": "没有记录", "POP_REPOS": "受欢迎的镜像仓库", "DELETED_REPO_SUCCESS": "成功删除镜像仓库。", "DELETED_TAG_SUCCESS": "成功删除镜像标签。", @@ -415,7 +416,11 @@ "IMAGE": "镜像", "LABELS": "标签", "ADD_TO_IMAGE": "添加标签到此镜像", - "ADD_LABELS": "添加标签" + "ADD_LABELS": "添加标签", + "FILTER_BY_LABEL": "过滤标签", + "ACTION": "操作", + "DEPLOY": "部署", + "ADDITIONAL_INFO": "添加信息" }, "ALERT": { "FORM_CHANGE_CONFIRMATION": "表单内容改变,确认是否取消?"