From fde171bcb34f871f8540381f3855ed0fcf367d41 Mon Sep 17 00:00:00 2001 From: Steven Zou Date: Thu, 22 Jun 2017 16:44:34 +0800 Subject: [PATCH 1/2] Fix UI issues --- .../lib/src/tag/tag-detail.component.html.ts | 8 +++--- .../lib/src/tag/tag-detail.component.spec.ts | 2 +- src/ui_ng/lib/src/tag/tag-detail.component.ts | 6 ++++- src/ui_ng/lib/src/tag/tag.component.css.ts | 5 ++++ src/ui_ng/lib/src/tag/tag.component.html.ts | 7 ++--- src/ui_ng/lib/src/tag/tag.component.ts | 27 +++++++++++++++---- .../vulnerability-scanning/scanning.css.ts | 20 +++++++++++++- .../vulnerability-scanning/scanning.html.ts | 10 +++---- src/ui_ng/package.json | 2 +- .../list-project-ro.component.html | 2 +- .../list-repository-ro.component.html | 2 +- src/ui_ng/src/app/shared/shared.module.ts | 4 +-- src/ui_ng/src/i18n/lang/en-us-lang.json | 10 ++++--- src/ui_ng/src/i18n/lang/es-es-lang.json | 10 ++++--- src/ui_ng/src/i18n/lang/zh-cn-lang.json | 12 ++++++--- 15 files changed, 92 insertions(+), 35 deletions(-) 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 5980ba87a..0f541efbf 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 @@ -48,8 +48,8 @@ export const TAG_DETAIL_HTML: string = `
-
{{highCount}} {{'VULNERABILITY.SEVERITY.HIGH' | translate }} {{suffixForHigh | translate }}
-
{{mediumCount}} {{'VULNERABILITY.SEVERITY.MEDIUM' | translate }} {{suffixForMedium | translate }}
+
{{highCount}} {{getPackageText(highCount) | translate}} {{'VULNERABILITY.SEVERITY.HIGH' | translate }} {{suffixForHigh | translate }}
+
{{mediumCount}} {{getPackageText(mediumCount) | translate}} {{'VULNERABILITY.SEVERITY.MEDIUM' | translate }} {{suffixForMedium | translate }}
@@ -60,8 +60,8 @@ export const TAG_DETAIL_HTML: string = `
-
{{lowCount}} {{'VULNERABILITY.SEVERITY.LOW' | translate }} {{suffixForLow | translate }}
-
{{unknownCount}} {{'VULNERABILITY.SEVERITY.UNKNOWN' | translate }} {{suffixForUnknown | translate }}
+
{{lowCount}} {{getPackageText(lowCount) | translate}} {{'VULNERABILITY.SEVERITY.LOW' | translate }} {{suffixForLow | translate }}
+
{{unknownCount}} {{getPackageText(unknownCount) | translate}} {{'VULNERABILITY.SEVERITY.UNKNOWN' | translate }} {{suffixForUnknown | 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 44bd18979..52654e767 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 @@ -144,7 +144,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 VULNERABILITY.PLURAL"); + expect(el2.textContent.trim()).toEqual("13 VULNERABILITY.PACKAGES VULNERABILITY.SEVERITY.HIGH VULNERABILITY.PLURAL"); }); })); 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 daaf2182f..5572742e5 100644 --- a/src/ui_ng/lib/src/tag/tag-detail.component.ts +++ b/src/ui_ng/lib/src/tag/tag-detail.component.ts @@ -75,8 +75,12 @@ export class TagDetailComponent implements OnInit { this.backEvt.emit(this.tagId); } + getPackageText(count: number): string { + return count > 1 ? "VULNERABILITY.PACKAGES" : "VULNERABILITY.PACKAGE"; + } + public get author(): string { - return this.tagDetails && this.tagDetails.author? this.tagDetails.author: 'TAG.ANONYMITY'; + return this.tagDetails && this.tagDetails.author ? this.tagDetails.author : 'TAG.ANONYMITY'; } public get highCount(): number { 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 6157b6cc6..eb2e512e5 100644 --- a/src/ui_ng/lib/src/tag/tag.component.css.ts +++ b/src/ui_ng/lib/src/tag/tag.component.css.ts @@ -37,4 +37,9 @@ export const TAG_STYLE = ` white-space: nowrap; text-overflow:ellipsis; } + +.copy-failed { + color: red; + margin-right: 6px; +} `; \ 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 9a17036b5..edbd1bfd4 100644 --- a/src/ui_ng/lib/src/tag/tag.component.html.ts +++ b/src/ui_ng/lib/src/tag/tag.component.html.ts @@ -4,11 +4,12 @@ export const TAG_TEMPLATE = ` @@ -54,6 +55,6 @@ export const TAG_TEMPLATE = ` {{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} {{'REPOSITORY.OF' | translate}} {{pagination.totalItems}} {{'REPOSITORY.ITEMS' | translate}}     - + `; \ No newline at end of file diff --git a/src/ui_ng/lib/src/tag/tag.component.ts b/src/ui_ng/lib/src/tag/tag.component.ts index ca009c603..964d4c4b3 100644 --- a/src/ui_ng/lib/src/tag/tag.component.ts +++ b/src/ui_ng/lib/src/tag/tag.component.ts @@ -20,6 +20,7 @@ import { EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef, + ElementRef, OnDestroy } from '@angular/core'; @@ -87,9 +88,13 @@ export class TagComponent implements OnInit, OnDestroy { tagsInScanning: { [key: string]: any } = {}; scanningTagCount: number = 0; + copyFailed: boolean = false; + @ViewChild('confirmationDialog') confirmationDialog: ConfirmationDialogComponent; + @ViewChild('digestTarget') textInput: ElementRef; + constructor( private errorHandler: ErrorHandler, private tagService: TagService, @@ -195,13 +200,10 @@ export class TagComponent implements OnInit, OnDestroy { this.manifestInfoTitle = 'REPOSITORY.COPY_DIGEST_ID'; this.digestId = tag.digest; this.showTagManifestOpened = true; + this.copyFailed = false; } } - - selectAndCopy($event: any) { - $event.target.select(); - } - + onTagClick(tag: Tag): void { if (tag) { let evt: TagClickEvent = { @@ -255,4 +257,19 @@ export class TagComponent implements OnInit, OnDestroy { let hnd = setInterval(() => this.ref.markForCheck(), 100); setTimeout(() => clearInterval(hnd), 1000); } + + onSuccess($event: any): void { + this.copyFailed = false; + //Directly close dialog + this.showTagManifestOpened = false; + } + + onError($event: any): void { + //Show error + this.copyFailed = true; + //Select all text + if(this.textInput){ + this.textInput.nativeElement.select(); + } + } } \ No newline at end of file diff --git a/src/ui_ng/lib/src/vulnerability-scanning/scanning.css.ts b/src/ui_ng/lib/src/vulnerability-scanning/scanning.css.ts index bc6643101..6a8abb7de 100644 --- a/src/ui_ng/lib/src/vulnerability-scanning/scanning.css.ts +++ b/src/ui_ng/lib/src/vulnerability-scanning/scanning.css.ts @@ -1,16 +1,34 @@ export const SCANNING_STYLES: string = ` .bar-wrapper { width: 120px; + height: 12px; } .bar-state { text-align: center !important; } + +.bar-state-chart { + position: relative; + top: 2px; +} + +.bar-state-error { + position: relative; + top: -3px; +} + +.error-text { + position: relative; + top: 1px; + margin-left: -5px; +} + .scanning-button { height: 24px; margin-top: 0px; margin-bottom: 0px; vertical-align: middle; - top: -6px; + top: -12px; position: relative; } .tip-wrapper { diff --git a/src/ui_ng/lib/src/vulnerability-scanning/scanning.html.ts b/src/ui_ng/lib/src/vulnerability-scanning/scanning.html.ts index b39052ba0..06aa794df 100644 --- a/src/ui_ng/lib/src/vulnerability-scanning/scanning.html.ts +++ b/src/ui_ng/lib/src/vulnerability-scanning/scanning.html.ts @@ -56,7 +56,7 @@ export const GRID_COMPONENT_HTML: string = ` {{'VULNERABILITY.GRID.COLUMN_ID' | translate}} {{'VULNERABILITY.GRID.COLUMN_SEVERITY' | translate}} {{'VULNERABILITY.GRID.COLUMN_PACKAGE' | translate}} - {{'VULNERABILITY.GRID.COLUMN_VERSION' | translate}} version + {{'VULNERABILITY.GRID.COLUMN_VERSION' | translate}} {{'VULNERABILITY.GRID.COLUMN_FIXED' | translate}} {{'VULNERABILITY.GRID.PLACEHOLDER' | translate}} @@ -94,15 +94,15 @@ export const BAR_CHART_COMPONENT_HTML: string = `
{{'VULNERABILITY.STATE.QUEUED' | translate}}
-
+
- {{'VULNERABILITY.STATE.ERROR' | translate}} + {{'VULNERABILITY.STATE.ERROR' | translate}}
-
+
{{'VULNERABILITY.STATE.SCANNING' | translate}}
-
+
diff --git a/src/ui_ng/package.json b/src/ui_ng/package.json index 055a18060..72ab7d858 100644 --- a/src/ui_ng/package.json +++ b/src/ui_ng/package.json @@ -31,7 +31,7 @@ "clarity-icons": "^0.9.8", "clarity-ui": "^0.9.8", "core-js": "^2.4.1", - "harbor-ui": "^0.2.13", + "harbor-ui": "^0.2.19", "intl": "^1.2.5", "mutationobserver-shim": "^0.3.2", "ngx-cookie": "^1.0.0", diff --git a/src/ui_ng/src/app/shared/list-project-ro/list-project-ro.component.html b/src/ui_ng/src/app/shared/list-project-ro/list-project-ro.component.html index 2752e67c7..51f59bfea 100644 --- a/src/ui_ng/src/app/shared/list-project-ro/list-project-ro.component.html +++ b/src/ui_ng/src/app/shared/list-project-ro/list-project-ro.component.html @@ -11,6 +11,6 @@ {{(projects ? projects.length : 0)}} {{'PROJECT.ITEMS' | translate}} - + \ No newline at end of file diff --git a/src/ui_ng/src/app/shared/list-repository-ro/list-repository-ro.component.html b/src/ui_ng/src/app/shared/list-repository-ro/list-repository-ro.component.html index f3992075d..e67f32c0b 100644 --- a/src/ui_ng/src/app/shared/list-repository-ro/list-repository-ro.component.html +++ b/src/ui_ng/src/app/shared/list-repository-ro/list-repository-ro.component.html @@ -9,6 +9,6 @@ {{(repositories ? repositories.length : 0)}} {{'REPOSITORY.ITEMS' | translate}} - + \ No newline at end of file diff --git a/src/ui_ng/src/app/shared/shared.module.ts b/src/ui_ng/src/app/shared/shared.module.ts index 5e324da48..20b360fcd 100644 --- a/src/ui_ng/src/app/shared/shared.module.ts +++ b/src/ui_ng/src/app/shared/shared.module.ts @@ -63,8 +63,8 @@ const uiLibConfig: IServiceConfig = { enablei18Support: true, langCookieKey: "harbor-lang", langMessageLoader: "http", - langMessagePathForHttpLoader: "src/i18n/lang/", - langMessageFileSuffixForHttpLoader: "-lang.json", + langMessagePathForHttpLoader: "i18n/lang/", + langMessageFileSuffixForHttpLoader: "-lang.json" }; @NgModule({ 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 f3661f901..a324c4573 100644 --- a/src/ui_ng/src/i18n/lang/en-us-lang.json +++ b/src/ui_ng/src/i18n/lang/en-us-lang.json @@ -31,7 +31,8 @@ "MORE_INFO": "More info...", "YES": "YES", "NO": "NO", - "NEGATIVE": "NEGATIVE" + "NEGATIVE": "NEGATIVE", + "COPY": "COPY" }, "TOOLTIP": { "EMAIL": "Email should be a valid email address like name@example.com.", @@ -477,7 +478,9 @@ }, "SINGULAR": "Vulnerability", "PLURAL": "Vulnerabilities", - "PLACEHOLDER": "Filter Vulnerabilities" + "PLACEHOLDER": "Filter Vulnerabilities", + "PACKAGE": "Package with", + "PACKAGES": "Packages with" }, "PUSH_IMAGE": { "TITLE": "Push Image", @@ -496,7 +499,8 @@ "OS": "OS", "SCAN_COMPLETION_TIME": "Scan Completed", "IMAGE_VULNERABILITIES": "Image Vulnerabilities", - "PLACEHOLDER": "We couldn't find any tags!" + "PLACEHOLDER": "We couldn't find any tags!", + "COPY_ERROR": "Copy failed, please try to manually copy." }, "UNKNOWN_ERROR": "Unknown errors have occurred. Please try again later.", "UNAUTHORIZED_ERROR": "Your session is invalid or has expired. You need to sign in to continue your action.", 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 2c714e4b0..9e4100c04 100644 --- a/src/ui_ng/src/i18n/lang/es-es-lang.json +++ b/src/ui_ng/src/i18n/lang/es-es-lang.json @@ -31,7 +31,8 @@ "MORE_INFO": "Más información...", "YES": "SI", "NO": "NO", - "NEGATIVE": "NEGATIVO" + "NEGATIVE": "NEGATIVO", + "COPY": "COPY" }, "TOOLTIP": { "EMAIL": "El email debe ser una dirección válida como nombre@ejemplo.com.", @@ -476,7 +477,9 @@ }, "SINGULAR": "Vulnerability", "PLURAL": "Vulnerabilities", - "PLACEHOLDER": "Filter Vulnerabilities" + "PLACEHOLDER": "Filter Vulnerabilities", + "PACKAGE": "Package with", + "PACKAGES": "Packages with" }, "PUSH_IMAGE": { "TITLE": "Push Image", @@ -495,7 +498,8 @@ "OS": "OS", "SCAN_COMPLETION_TIME": "Scan Completed", "IMAGE_VULNERABILITIES": "Image Vulnerabilities", - "PLACEHOLDER": "We couldn't find any tags!" + "PLACEHOLDER": "We couldn't find any tags!", + "COPY_ERROR": "Copy failed, please try to manually copy." }, "UNKNOWN_ERROR": "Ha ocurrido un error desconocido. Por favor, inténtelo de nuevo más tarde.", "UNAUTHORIZED_ERROR": "La sesión no es válida o ha caducado. Necesita identificarse de nuevo para llevar a cabo esa acción.", 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 43d22a560..b61495d73 100644 --- a/src/ui_ng/src/i18n/lang/zh-cn-lang.json +++ b/src/ui_ng/src/i18n/lang/zh-cn-lang.json @@ -31,7 +31,8 @@ "MORE_INFO": "更多信息...", "YES": "是", "NO": "否", - "NEGATIVE": "否" + "NEGATIVE": "否", + "COPY": "拷贝" }, "TOOLTIP": { "EMAIL": "请使用正确的邮箱地址,比如name@example.com。", @@ -456,7 +457,7 @@ "PLACEHOLDER": "没有扫描结果!", "COLUMN_ID": "缺陷码", "COLUMN_SEVERITY": "严重度", - "COLUMN_PACKAGE": "组件", + "COLUMN_PACKAGE": "组", "COLUMN_VERSION": "当前版本", "COLUMN_FIXED": "修复版本", "COLUMN_DESCRIPTION": "简介", @@ -477,7 +478,9 @@ }, "SINGULAR": "缺陷", "PLURAL": "缺陷", - "PLACEHOLDER": "过滤缺陷" + "PLACEHOLDER": "过滤缺陷", + "PACKAGE": "个组件有", + "PACKAGES": "个组件有" }, "PUSH_IMAGE": { "TITLE": "推送镜像", @@ -496,7 +499,8 @@ "OS": "操作系统", "SCAN_COMPLETION_TIME": "扫描完成时间", "IMAGE_VULNERABILITIES": "镜像缺陷", - "PLACEHOLDER": "未发现任何标签!" + "PLACEHOLDER": "未发现任何标签!", + "COPY_ERROR": "拷贝失败,请尝试手动拷贝。" }, "UNKNOWN_ERROR": "发生未知错误,请稍后再试。", "UNAUTHORIZED_ERROR": "会话无效或者已经过期, 请重新登录以继续。", From deeb37ac87ab5ee8903ba82f7eb6a6ffef227f45 Mon Sep 17 00:00:00 2001 From: Steven Zou Date: Thu, 22 Jun 2017 17:09:53 +0800 Subject: [PATCH 2/2] Update ui building process --- .travis.yml | 1 + make/dev/nodeclarity/entrypoint.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4a3816b8b..b842e0ba6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -74,6 +74,7 @@ before_script: - sudo chmod 777 /tmp/registry.db script: + - sudo cp ./src/ui_ng/package.json ./src/ui_ng/src - sudo mkdir -p /etc/ui/ca/ - sudo mv ./tests/ca.crt /etc/ui/ca/ - sudo mkdir -p /harbor diff --git a/make/dev/nodeclarity/entrypoint.sh b/make/dev/nodeclarity/entrypoint.sh index 5b2a23240..3ab9c80ad 100644 --- a/make/dev/nodeclarity/entrypoint.sh +++ b/make/dev/nodeclarity/entrypoint.sh @@ -18,6 +18,7 @@ if [ ! -z "$npm_proxy" -a "$npm_proxy" != " " ]; then npm config set proxy $npm_proxy fi +cp ./src/package.json . npm install ./node_modules/.bin/ngc -p tsconfig-aot.json