From b520addf08ec2a8fe835019ce25345e7b62d2594 Mon Sep 17 00:00:00 2001 From: pfh Date: Thu, 26 Apr 2018 10:24:25 +0800 Subject: [PATCH] Add sort fun when filter label in tag page #4617 --- .../create-edit-label.component.ts | 6 + .../lib/src/tag/tag-detail.component.css.ts | 3 +- .../lib/src/tag/tag-detail.component.html.ts | 6 +- src/ui_ng/lib/src/tag/tag.component.html.ts | 6 +- src/ui_ng/lib/src/tag/tag.component.ts | 158 ++++++++++++------ .../result-grid.component.spec.ts | 2 + .../result-grid.component.ts | 6 + .../vulnerability-scanning/scanning.css.ts | 7 +- .../vulnerability-scanning/scanning.html.ts | 11 +- src/ui_ng/package.json | 2 +- 10 files changed, 139 insertions(+), 68 deletions(-) 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 c018a80ba..61cb3603b 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 @@ -37,6 +37,7 @@ import {LabelColor} from "../shared/shared.const"; selector: 'hbr-create-edit-label', template: CREATE_EDIT_LABEL_TEMPLATE, styles: [CREATE_EDIT_LABEL_STYLE], + changeDetection: ChangeDetectionStrategy.Default }) export class CreateEditLabelComponent implements OnInit, OnDestroy { @@ -63,6 +64,7 @@ export class CreateEditLabelComponent implements OnInit, OnDestroy { constructor( private labelService: LabelService, private errorHandler: ErrorHandler, + private ref: ChangeDetectorRef ) { } ngOnInit(): void { @@ -81,6 +83,9 @@ export class CreateEditLabelComponent implements OnInit, OnDestroy { this.checkOnGoing = false; this.errorHandler.error(error) }); + setTimeout(() => { + setInterval(() => this.ref.markForCheck(), 100); + }, 1000); }); } @@ -104,6 +109,7 @@ export class CreateEditLabelComponent implements OnInit, OnDestroy { openModal(): void { this.labelModel = this.initLabel(); this.formShow = true; + this.isLabelNameExist = false; this.labelId = 0; this.copeLabelModel = null; } 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 a64cc44f2..ca6e1e360 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,7 +1,6 @@ export const TAG_DETAIL_STYLES: string = ` .overview-section { padding-bottom: 36px; - border-bottom: 1px solid #cccccc; } .detail-section { @@ -60,7 +59,7 @@ export const TAG_DETAIL_STYLES: string = ` .summary-block { margin-top: 24px; - display: inline-flex; + display: flex; flex-wrap: row wrap; } 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 094f95e6e..450cbb93e 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 @@ -9,8 +9,8 @@ export const TAG_DETAIL_HTML: string = `

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

-
-
+
+
{{'TAG.AUTHOR' | translate }}
@@ -28,7 +28,7 @@ export const TAG_DETAIL_HTML: string = `
-
+
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 dea5b3223..4e18a27f8 100644 --- a/src/ui_ng/lib/src/tag/tag.component.html.ts +++ b/src/ui_ng/lib/src/tag/tag.component.html.ts @@ -26,7 +26,7 @@ export const TAG_TEMPLATE = `
{{'LABEL.NO_LABELS' | translate }}
- @@ -51,7 +51,7 @@ export const TAG_TEMPLATE = `
{{'LABEL.NO_LABELS' | translate }}
- @@ -69,7 +69,7 @@ export const TAG_TEMPLATE = ` {{'REPOSITORY.AUTHOR' | translate}} {{'REPOSITORY.CREATED' | translate}} {{'REPOSITORY.DOCKER_VERSION' | translate}} - {{'REPOSITORY.LABELS' | translate}} + {{'REPOSITORY.LABELS' | translate}} {{'TAG.PLACEHOLDER' | translate }} diff --git a/src/ui_ng/lib/src/tag/tag.component.ts b/src/ui_ng/lib/src/tag/tag.component.ts index bfa4d351b..7bc9480a5 100644 --- a/src/ui_ng/lib/src/tag/tag.component.ts +++ b/src/ui_ng/lib/src/tag/tag.component.ts @@ -60,12 +60,17 @@ import {BatchInfo, BathInfoChanges} from "../confirmation-dialog/confirmation-ba import {Observable} from "rxjs/Observable"; import {LabelService} from "../service/label.service"; import {Subject} from "rxjs/Subject"; +export interface LabelOpe { + iconsShow: boolean; + label: Label; + show: boolean; +} @Component({ selector: "hbr-tag", template: TAG_TEMPLATE, styles: [TAG_STYLE], - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.Default }) export class TagComponent implements OnInit, AfterViewInit { @@ -103,16 +108,16 @@ export class TagComponent implements OnInit, AfterViewInit { copyFailed = false; selectedRow: Tag[] = []; - imageLabels: {[key: string]: boolean | Label | any}[] = []; - imageStickLabels: {[key: string]: boolean | Label | any}[] = []; - imageFilterLabels: {[key: string]: boolean | Label | any}[] = []; + imageLabels: LabelOpe[] = []; + imageStickLabels: LabelOpe[] = []; + imageFilterLabels: LabelOpe[] = []; labelListOpen = false; selectedTag: Tag[]; labelNameFilter: Subject = new Subject (); stickLabelNameFilter: Subject = new Subject (); filterOnGoing: boolean; - stickName = '' + stickName = ''; filterName = ''; initFilter = { name: '', @@ -120,7 +125,7 @@ export class TagComponent implements OnInit, AfterViewInit { color: '', scope: '', project_id: 0, - } + }; filterOneLabel: Label = this.initFilter; @@ -163,13 +168,14 @@ export class TagComponent implements OnInit, AfterViewInit { .subscribe((name: string) => { if (this.filterName.length) { this.filterOnGoing = true; - this.imageFilterLabels = []; - this.imageLabels.forEach(data => { + this.imageFilterLabels.forEach(data => { if (data.label.name.indexOf(this.filterName) !== -1) { - this.imageFilterLabels.push(data); + data.show = true; + } else { + data.show = false; } - }) + }); setTimeout(() => { setInterval(() => this.ref.markForCheck(), 200); }, 1000); @@ -182,11 +188,12 @@ export class TagComponent implements OnInit, AfterViewInit { .subscribe((name: string) => { if (this.stickName.length) { this.filterOnGoing = true; - this.imageStickLabels = []; - this.imageLabels.forEach(data => { + this.imageStickLabels.forEach(data => { if (data.label.name.indexOf(this.stickName) !== -1) { - this.imageStickLabels.push(data); + data.show = true; + }else { + data.show = false; } }) setTimeout(() => { @@ -273,14 +280,14 @@ export class TagComponent implements OnInit, AfterViewInit { toPromise(this.labelService.getGLabels()).then((res: Label[]) => { if (res.length) { res.forEach(data => { - this.imageLabels.push({'iconsShow': false, 'label': data}); + this.imageLabels.push({'iconsShow': false, 'label': data, 'show': true}); }); } toPromise(this.labelService.getPLabels(this.projectId)).then((res1: Label[]) => { if (res1.length) { res1.forEach(data => { - this.imageLabels.push({'iconsShow': false, 'label': data}); + this.imageLabels.push({'iconsShow': false, 'label': data, 'show': true}); }); } this.imageFilterLabels = clone(this.imageLabels); @@ -294,24 +301,31 @@ export class TagComponent implements OnInit, AfterViewInit { } labelSelectedChange(tag?: Tag[]): void { - if (tag && tag[0].labels && tag[0].labels.length) { + if (tag && tag[0].labels) { this.imageStickLabels.forEach(data => { data.iconsShow = false; + data.show = true; }) - tag[0].labels.forEach((labelInfo: Label) => { - this.imageStickLabels.find(data => labelInfo.id === data['label'].id).iconsShow = true; - }); + if (tag[0].labels.length) { + tag[0].labels.forEach((labelInfo: Label) => { + let findedLabel = this.imageStickLabels.find(data => labelInfo.id === data['label'].id); + this.imageStickLabels.splice(this.imageStickLabels.indexOf(findedLabel), 1); + this.imageStickLabels.unshift(findedLabel); + + findedLabel.iconsShow = true; + }); + } } } addLabels(tag: Tag[]): void { this.labelListOpen = true; this.selectedTag = tag; - + this.stickName = ''; this.labelSelectedChange(tag); } - stickLabel(labelInfo: {[key: string]: any | string[]}): void { + stickLabel(labelInfo: LabelOpe): void { if (labelInfo && !labelInfo.iconsShow) { this.selectLabel(labelInfo); } @@ -320,13 +334,18 @@ export class TagComponent implements OnInit, AfterViewInit { } } - selectLabel(labelInfo: {[key: string]: any | string[]}): void { + selectLabel(labelInfo: LabelOpe): void { if (!this.inprogress) { this.inprogress = true; let labelId = labelInfo.label.id; this.selectedRow = this.selectedTag; toPromise(this.tagService.addLabelToImages(this.repoName, this.selectedRow[0].name, labelId)).then(res => { this.refresh(); + + // set the selected label in front + this.imageStickLabels.splice(this.imageStickLabels.indexOf(labelInfo), 1); + this.imageStickLabels.unshift(labelInfo); + labelInfo.iconsShow = true; this.inprogress = false; }).catch(err => { @@ -336,13 +355,15 @@ export class TagComponent implements OnInit, AfterViewInit { } } - unSelectLabel(labelInfo: {[key: string]: any | string[]}): void { + unSelectLabel(labelInfo: LabelOpe): void { if (!this.inprogress) { this.inprogress = true; let labelId = labelInfo.label.id; this.selectedRow = this.selectedTag; toPromise(this.tagService.deleteLabelToImages(this.repoName, this.selectedRow[0].name, labelId)).then(res => { this.refresh(); + // insert the unselected label to groups with the same icons + this.sortOperation(this.imageStickLabels, labelInfo); labelInfo.iconsShow = false; this.inprogress = false; }).catch(err => { @@ -352,7 +373,7 @@ export class TagComponent implements OnInit, AfterViewInit { } } - rightFilterLabel(labelInfo: {[key: string]: any | string[]}): void { + rightFilterLabel(labelInfo: LabelOpe): void { if (labelInfo) { if (!labelInfo.iconsShow) { this.filterLabel(labelInfo); @@ -362,19 +383,26 @@ export class TagComponent implements OnInit, AfterViewInit { } } - filterLabel(labelInfo: {[key: string]: any | string[]}): void { - let labelName = labelInfo.label.name; - this.imageFilterLabels.filter(data => { - if (data.label.name !== labelName) { - data.iconsShow = false; - }else { - data.iconsShow = true; - } - }); + filterLabel(labelInfo: LabelOpe): void { + let labelName = labelInfo.label.name; + // insert the unselected label to groups with the same icons + let preLabelInfo = this.imageFilterLabels.find(data => data.label.id === this.filterOneLabel.id); + if (preLabelInfo) { + this.sortOperation(this.imageFilterLabels, preLabelInfo); + } + this.imageFilterLabels.filter(data => { + if (data.label.name !== labelName) { + data.iconsShow = false; + }else { + data.iconsShow = true; + } + }); + this.imageFilterLabels.splice(this.imageFilterLabels.indexOf(labelInfo), 1); + this.imageFilterLabels.unshift(labelInfo); this.filterOneLabel = labelInfo.label; - // reload datagu + // reload data this.currentPage = 1; let st: State = this.currentState; if (!st) { @@ -392,31 +420,35 @@ export class TagComponent implements OnInit, AfterViewInit { this.clrLoad(st); } - unFilterLabel(labelInfo: {[key: string]: any | string[]}): void { - this.filterOneLabel = this.initFilter; - labelInfo.iconsShow = false; - // reload datagu - this.currentPage = 1; - let st: State = this.currentState; - if (!st) { - st = { page: {} }; - } - st.page.size = this.pageSize; - st.page.from = 0; - st.page.to = this.pageSize - 1; - if (this.lastFilteredTagName) { - st.filters = [{property: 'name', value: this.lastFilteredTagName}]; - }else { - st.filters = []; - } - this.clrLoad(st); + unFilterLabel(labelInfo: LabelOpe): void { + // insert the unselected label to groups with the same icons + this.sortOperation(this.imageFilterLabels, labelInfo); + + this.filterOneLabel = this.initFilter; + labelInfo.iconsShow = false; + + // reload data + this.currentPage = 1; + let st: State = this.currentState; + if (!st) { + st = { page: {} }; + } + st.page.size = this.pageSize; + st.page.from = 0; + st.page.to = this.pageSize - 1; + if (this.lastFilteredTagName) { + st.filters = [{property: 'name', value: this.lastFilteredTagName}]; + }else { + st.filters = []; + } + this.clrLoad(st); } handleInputFilter() { if (this.filterName.length) { this.labelNameFilter.next(this.filterName); }else { - this.imageFilterLabels = clone(this.imageLabels); + this.imageFilterLabels.every(data => data.show = true); } } @@ -424,10 +456,28 @@ export class TagComponent implements OnInit, AfterViewInit { if (this.stickName.length) { this.stickLabelNameFilter.next(this.stickName); }else { - this.imageStickLabels = clone(this.imageLabels); + this.imageStickLabels.every(data => data.show = true); } } + // insert the unselected label to groups with the same icons + sortOperation(labelList: LabelOpe[], labelInfo: LabelOpe): void { + labelList.some((data, i) => { + if (!data.iconsShow) { + if (data.label.scope === labelInfo.label.scope) { + labelList.splice(i, 0, labelInfo); + labelList.splice(labelList.indexOf(labelInfo, 0), 1); + return true; + } + if (data.label.scope !== labelInfo.label.scope && i === labelList.length - 1) { + labelList.push(labelInfo); + labelList.splice(labelList.indexOf(labelInfo), 1); + return true; + } + } + }); + } + retrieve() { this.tags = []; let signatures: string[] = [] ; diff --git a/src/ui_ng/lib/src/vulnerability-scanning/result-grid.component.spec.ts b/src/ui_ng/lib/src/vulnerability-scanning/result-grid.component.spec.ts index 9fa9e0245..812933a4b 100644 --- a/src/ui_ng/lib/src/vulnerability-scanning/result-grid.component.spec.ts +++ b/src/ui_ng/lib/src/vulnerability-scanning/result-grid.component.spec.ts @@ -11,6 +11,7 @@ import { SERVICE_CONFIG, IServiceConfig } from '../service.config'; import { ErrorHandler } from '../error-handler/index'; import { SharedModule } from '../shared/shared.module'; import { FilterComponent } from '../filter/index'; +import {ChannelService} from "../channel/channel.service"; describe('ResultGridComponent (inline template)', () => { let component: ResultGridComponent; @@ -30,6 +31,7 @@ describe('ResultGridComponent (inline template)', () => { declarations: [ResultGridComponent, FilterComponent], providers: [ ErrorHandler, + ChannelService, { provide: SERVICE_CONFIG, useValue: testConfig }, { provide: ScanningResultService, useClass: ScanningResultDefaultService } ] diff --git a/src/ui_ng/lib/src/vulnerability-scanning/result-grid.component.ts b/src/ui_ng/lib/src/vulnerability-scanning/result-grid.component.ts index f75045841..afd48c8a5 100644 --- a/src/ui_ng/lib/src/vulnerability-scanning/result-grid.component.ts +++ b/src/ui_ng/lib/src/vulnerability-scanning/result-grid.component.ts @@ -9,6 +9,7 @@ import { ErrorHandler } from '../error-handler/index'; import { toPromise } from '../utils'; import { GRID_COMPONENT_HTML } from './scanning.html'; import { SCANNING_STYLES } from './scanning.css'; +import {ChannelService} from "../channel/channel.service"; @Component({ selector: 'hbr-vulnerabilities-grid', @@ -24,6 +25,7 @@ export class ResultGridComponent implements OnInit { constructor( private scanningService: ScanningResultService, + private channel: ChannelService, private errorHandler: ErrorHandler ) { } @@ -74,4 +76,8 @@ export class ResultGridComponent implements OnInit { let reg = new RegExp('.*' + terms + '.*', 'i'); return reg.test(testedValue); } + + scanNow(): void { + this.channel.publishScanEvent(this.repositoryId + "/" + this.tagId); + } } 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 0ffd92d13..3fbf38d80 100644 --- a/src/ui_ng/lib/src/vulnerability-scanning/scanning.css.ts +++ b/src/ui_ng/lib/src/vulnerability-scanning/scanning.css.ts @@ -126,5 +126,10 @@ hr{ .font-weight-600{ font-weight:600; } - +.rightPos{ + position: absolute; + z-index: 100; + right: 35px; + margin-top: 4px; +} `; \ No newline at end of file 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 dcdc4eb3c..c77f391e4 100644 --- a/src/ui_ng/lib/src/vulnerability-scanning/scanning.html.ts +++ b/src/ui_ng/lib/src/vulnerability-scanning/scanning.html.ts @@ -67,10 +67,10 @@ export const TIP_COMPONENT_HTML: string = ` `; export const GRID_COMPONENT_HTML: string = ` -
-
-
-
+
+
+
+
@@ -78,6 +78,9 @@ export const GRID_COMPONENT_HTML: string = `
+ + + {{'VULNERABILITY.GRID.COLUMN_ID' | translate}} {{'VULNERABILITY.GRID.COLUMN_SEVERITY' | translate}} {{'VULNERABILITY.GRID.COLUMN_PACKAGE' | translate}} diff --git a/src/ui_ng/package.json b/src/ui_ng/package.json index 4aea664e0..bc91bd121 100644 --- a/src/ui_ng/package.json +++ b/src/ui_ng/package.json @@ -30,7 +30,7 @@ "clarity-icons": "^0.10.27", "clarity-ui": "^0.10.27", "core-js": "^2.4.1", - "harbor-ui": "0.7.6", + "harbor-ui": "0.7.7", "intl": "^1.2.5", "mutationobserver-shim": "^0.3.2", "ngx-cookie": "^1.0.0",