From 716485623967fa535311a0a344c32d27396d9f54 Mon Sep 17 00:00:00 2001 From: Qian Deng Date: Wed, 24 Oct 2018 15:59:29 +0800 Subject: [PATCH] Enhancement: Harbor Helmchart UI Label 1. Add Filter to helmchart datagrid 2. Fix UI misc issues Signed-off-by: Qian Deng --- .../helm-chart-version.component.html | 20 ++++-- .../helm-chart-version.component.scss | 4 +- .../versions/helm-chart-version.component.ts | 4 +- src/portal/lib/src/label/index.ts | 4 +- .../label-filter/label-filter.component.html | 18 +++++ .../label-filter/label-filter.component.scss | 31 +++++++++ .../label-filter/label-filter.component.ts | 69 +++++++++++++++++++ .../label-marker/label-marker.component.scss | 2 + .../label-signpost.component.html | 4 +- .../label-signpost.component.scss | 1 + src/portal/lib/src/shared/shared.const.ts | 1 + src/portal/lib/src/tag/tag.component.html | 42 ++++++----- .../base/global-search/search.component.scss | 5 ++ .../list-chart-version-ro.component.ts | 3 +- src/portal/src/i18n/lang/es-es-lang.json | 2 +- src/portal/src/i18n/lang/fr-fr-lang.json | 2 +- src/portal/src/i18n/lang/zh-cn-lang.json | 2 +- 17 files changed, 179 insertions(+), 35 deletions(-) create mode 100644 src/portal/lib/src/label/label-filter/label-filter.component.html create mode 100644 src/portal/lib/src/label/label-filter/label-filter.component.scss create mode 100644 src/portal/lib/src/label/label-filter/label-filter.component.ts diff --git a/src/portal/lib/src/helm-chart/versions/helm-chart-version.component.html b/src/portal/lib/src/helm-chart/versions/helm-chart-version.component.html index 57b3fa14a..2b0d1e776 100644 --- a/src/portal/lib/src/helm-chart/versions/helm-chart-version.component.html +++ b/src/portal/lib/src/helm-chart/versions/helm-chart-version.component.html @@ -49,7 +49,7 @@ @@ -69,9 +69,17 @@ {{'HELM_CHART.MAINTAINERS' | translate }} {{'HELM_CHART.CREATED' | translate }} - {{'REPOSITORY.LABELS' | translate}} + + {{'REPOSITORY.LABELS' | translate}} + + + + + {{'HELM_CHART.NO_VERSION_PLACEHOLDER' | translate }} - + @@ -83,8 +91,10 @@ {{ getMaintainerString(v.maintainers) }} {{ v.created | date}} - - +
+ + +
diff --git a/src/portal/lib/src/helm-chart/versions/helm-chart-version.component.scss b/src/portal/lib/src/helm-chart/versions/helm-chart-version.component.scss index dee8505f3..cfb766fdd 100644 --- a/src/portal/lib/src/helm-chart/versions/helm-chart-version.component.scss +++ b/src/portal/lib/src/helm-chart/versions/helm-chart-version.component.scss @@ -34,13 +34,15 @@ } clr-dg-action-bar { - clr-dropdown{ + clr-dropdown { @include dropdown-as-action-button; } } hbr-resource-label-signpost { display: inline-block; + max-height: 24px; + margin-left: 3px; } .card-container { diff --git a/src/portal/lib/src/helm-chart/versions/helm-chart-version.component.ts b/src/portal/lib/src/helm-chart/versions/helm-chart-version.component.ts index ca12efa8f..6202b877b 100644 --- a/src/portal/lib/src/helm-chart/versions/helm-chart-version.component.ts +++ b/src/portal/lib/src/helm-chart/versions/helm-chart-version.component.ts @@ -317,8 +317,8 @@ export class ChartVersionComponent implements OnInit { .subscribe(labels => { let versionIdx = this.chartVersions.findIndex(v => v.name === version.name); this.chartVersions[versionIdx].labels = labels; - let hnd = setInterval(() => this.cdr.markForCheck(), 100); - setTimeout(() => clearInterval(hnd), 2000); + let hnd = setInterval(() => this.cdr.markForCheck(), 200); + setTimeout(() => clearInterval(hnd), 5000); }); } } diff --git a/src/portal/lib/src/label/index.ts b/src/portal/lib/src/label/index.ts index 55e5cced6..a046d63b0 100644 --- a/src/portal/lib/src/label/index.ts +++ b/src/portal/lib/src/label/index.ts @@ -2,9 +2,11 @@ import { Type } from '@angular/core'; import { LabelComponent} from "./label.component"; import { LabelMarkerComponent } from './label-marker/label-marker.component'; import { LabelSignPostComponent } from './label-signpost/label-signpost.component'; +import { LabelFilterComponent } from './label-filter/label-filter.component'; export const LABEL_DIRECTIVES: Type[] = [ LabelComponent, LabelMarkerComponent, - LabelSignPostComponent + LabelSignPostComponent, + LabelFilterComponent ]; diff --git a/src/portal/lib/src/label/label-filter/label-filter.component.html b/src/portal/lib/src/label/label-filter/label-filter.component.html new file mode 100644 index 000000000..baffcfb09 --- /dev/null +++ b/src/portal/lib/src/label/label-filter/label-filter.component.html @@ -0,0 +1,18 @@ +
+
+ +
+
+ +
+
\ No newline at end of file diff --git a/src/portal/lib/src/label/label-filter/label-filter.component.scss b/src/portal/lib/src/label/label-filter/label-filter.component.scss new file mode 100644 index 000000000..3df80b882 --- /dev/null +++ b/src/portal/lib/src/label/label-filter/label-filter.component.scss @@ -0,0 +1,31 @@ +@mixin icon-span { + width: 12px; + min-height: 12px; +} + +.filter-div { + margin-left: 9px; + margin-bottom: 12px; +} + +.label-items-container { + max-height: 300px; + overflow-y: auto; + + .dropdown-item { + padding-left: 12px; + padding-right: 12px; + + .x-label-span { + @include icon-span(); + float: right; + } + + .check-label-span { + @include icon-span(); + float: left; + margin-right: 9px; + } + } + +} \ No newline at end of file diff --git a/src/portal/lib/src/label/label-filter/label-filter.component.ts b/src/portal/lib/src/label/label-filter/label-filter.component.ts new file mode 100644 index 000000000..4fb3848a6 --- /dev/null +++ b/src/portal/lib/src/label/label-filter/label-filter.component.ts @@ -0,0 +1,69 @@ +import { OnInit, Input, EventEmitter, Component, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core'; +import {ClrDatagridFilterInterface} from "@clr/angular"; +import { fromEvent } from 'rxjs'; +import { debounceTime } from 'rxjs/operators'; + +import { Label, Tag } from './../../service/interface'; +import { HelmChartVersion } from '../../service/interface'; +import { ResourceType } from '../../shared/shared.const'; + +@Component({ + selector: "hbr-chart-version-label-filter", + templateUrl: './label-filter.component.html', + styleUrls: ['./label-filter.component.scss'] +}) +export class LabelFilterComponent implements ClrDatagridFilterInterface, OnInit { + + @Input() labels: Label[] = []; + @Input() resourceType: ResourceType; + + @ViewChild('filterInput') filterInputRef: ElementRef; + + selectedLabels: Map = new Map(); + + changes: EventEmitter = new EventEmitter(false); + + labelFilter = ''; + + ngOnInit(): void { + fromEvent(this.filterInputRef.nativeElement, 'keyup') + .pipe(debounceTime(500)) + .subscribe(() => { + let hnd = setInterval(() => this.cdr.markForCheck(), 100); + setTimeout(() => clearInterval(hnd), 2000); + }); + } + constructor(private cdr: ChangeDetectorRef) {} + + get filteredLabels() { + return this.labels.filter(label => label.name.includes(this.labelFilter)); + } + + isActive(): boolean { + return this.selectedLabels.size > 0; + } + + accepts(cv: any): boolean { + if (this.resourceType === ResourceType.CHART_VERSION) { + return (cv as HelmChartVersion).labels.some(label => this.selectedLabels.get(label.id)); + } else if (this.resourceType === ResourceType.REPOSITORY_TAG) { + return (cv as Tag).labels.some(label => this.selectedLabels.get(label.id)); + } else { + return true; + } + } + + selectLabel(label: Label) { + this.selectedLabels.set(label.id, true); + this.changes.emit(); + } + + unselectLabel(label: Label) { + this.selectedLabels.delete(label.id); + this.changes.emit(true); + } + + isSelected(label: Label) { + return this.selectedLabels.has(label.id); + } +} diff --git a/src/portal/lib/src/label/label-marker/label-marker.component.scss b/src/portal/lib/src/label/label-marker/label-marker.component.scss index 2bd1089a3..90b23ae43 100644 --- a/src/portal/lib/src/label/label-marker/label-marker.component.scss +++ b/src/portal/lib/src/label/label-marker/label-marker.component.scss @@ -9,6 +9,8 @@ .filter-div { margin-left: 9px; + margin-right: 9px; + margin-bottom: 9px; } .label-items-container { diff --git a/src/portal/lib/src/label/label-signpost/label-signpost.component.html b/src/portal/lib/src/label/label-signpost/label-signpost.component.html index 7bc201033..c824fd527 100644 --- a/src/portal/lib/src/label/label-signpost/label-signpost.component.html +++ b/src/portal/lib/src/label/label-signpost/label-signpost.component.html @@ -1,8 +1,6 @@
- +
diff --git a/src/portal/lib/src/label/label-signpost/label-signpost.component.scss b/src/portal/lib/src/label/label-signpost/label-signpost.component.scss index 56e8a50b7..57424a5c2 100644 --- a/src/portal/lib/src/label/label-signpost/label-signpost.component.scss +++ b/src/portal/lib/src/label/label-signpost/label-signpost.component.scss @@ -4,6 +4,7 @@ clr-signpost { margin: 0; height: 24px; vertical-align: super; + line-height: 6px; } clr-signpost-content { diff --git a/src/portal/lib/src/shared/shared.const.ts b/src/portal/lib/src/shared/shared.const.ts index 24358fe9d..50cc84781 100644 --- a/src/portal/lib/src/shared/shared.const.ts +++ b/src/portal/lib/src/shared/shared.const.ts @@ -104,4 +104,5 @@ export enum Roles { export enum ResourceType { REPOSITORY = 1, CHART_VERSION = 2, + REPOSITORY_TAG = 3, } diff --git a/src/portal/lib/src/tag/tag.component.html b/src/portal/lib/src/tag/tag.component.html index 7a1f0e597..8cc0266c6 100644 --- a/src/portal/lib/src/tag/tag.component.html +++ b/src/portal/lib/src/tag/tag.component.html @@ -14,28 +14,34 @@
-
-
-
- -
- × - -
-
{{'LABEL.NO_LABELS' | translate }}
-
- +
+ +
+ +
+
+ + +
-
- - - -
diff --git a/src/portal/src/app/base/global-search/search.component.scss b/src/portal/src/app/base/global-search/search.component.scss index 215951bb0..fdcc82818 100644 --- a/src/portal/src/app/base/global-search/search.component.scss +++ b/src/portal/src/app/base/global-search/search.component.scss @@ -64,4 +64,9 @@ height: 40px; width: 1px; top: 10px; +} + +#results { + overflow-y: auto; + max-height: 99%; } \ No newline at end of file diff --git a/src/portal/src/app/shared/list-chart-version-ro/list-chart-version-ro.component.ts b/src/portal/src/app/shared/list-chart-version-ro/list-chart-version-ro.component.ts index 27c9fd0c5..f8e545640 100644 --- a/src/portal/src/app/shared/list-chart-version-ro/list-chart-version-ro.component.ts +++ b/src/portal/src/app/shared/list-chart-version-ro/list-chart-version-ro.component.ts @@ -21,8 +21,7 @@ export class ListChartVersionRoComponent implements OnInit { private projectService: ProjectService, private router: Router) { } - ngOnInit() { - } + ngOnInit() {} getStatusString(chart: HelmChartVersion) { if (chart.deprecated) { diff --git a/src/portal/src/i18n/lang/es-es-lang.json b/src/portal/src/i18n/lang/es-es-lang.json index 9325dcf00..00ca44c1f 100644 --- a/src/portal/src/i18n/lang/es-es-lang.json +++ b/src/portal/src/i18n/lang/es-es-lang.json @@ -763,7 +763,7 @@ "DELETE": "Delete", "LABEL_NAME": "Label Name", "COLOR": "Color", - "FILTER_Label_PLACEHOLDER": "Filter Labels", + "FILTER_LABEL_PLACEHOLDER": "Filter Labels", "NO_LABELS": "No labels", "DELETION_TITLE_TARGET": "Confirm Label Deletion", "DELETION_SUMMARY_TARGET": "Do you want to delete {{param}}?", diff --git a/src/portal/src/i18n/lang/fr-fr-lang.json b/src/portal/src/i18n/lang/fr-fr-lang.json index a537b73ce..7caf17222 100644 --- a/src/portal/src/i18n/lang/fr-fr-lang.json +++ b/src/portal/src/i18n/lang/fr-fr-lang.json @@ -726,7 +726,7 @@ "DELETE": "Delete", "LABEL_NAME": "Label Name", "COLOR": "Color", - "FILTER_Label_PLACEHOLDER": "Filter Labels", + "FILTER_LABEL_PLACEHOLDER": "Filter Labels", "NO_LABELS": "No labels", "DELETION_TITLE_TARGET": "Confirm Label Deletion", "DELETION_SUMMARY_TARGET": "Do you want to delete {{param}}?", diff --git a/src/portal/src/i18n/lang/zh-cn-lang.json b/src/portal/src/i18n/lang/zh-cn-lang.json index 38c86be67..04923dcab 100644 --- a/src/portal/src/i18n/lang/zh-cn-lang.json +++ b/src/portal/src/i18n/lang/zh-cn-lang.json @@ -762,7 +762,7 @@ "DELETE": "删除", "LABEL_NAME": "标签名字", "COLOR": "颜色", - "FILTER_Label_PLACEHOLDER": "过滤标签", + "FILTER_LABEL_PLACEHOLDER": "过滤标签", "NO_LABELS": "无标签", "DELETION_TITLE_TARGET":"删除标签确认", "DELETION_SUMMARY_TARGET": "确认删除标签 {{param}}?",