From 9a24d2631dd11d9efd98db04e84e3df3ee15d1b8 Mon Sep 17 00:00:00 2001 From: AllForNothing Date: Mon, 6 Feb 2023 13:57:50 +0800 Subject: [PATCH] Support searching artifacts by specified tag name 1.Fixes #18082 2.Update CSS Signed-off-by: AllForNothing --- .../artifact-filter.component.html | 6 ++-- .../artifact-filter.component.scss | 5 +++ .../artifact-filter.component.ts | 32 ++++++++++++++++++- .../artifact-list-tab.component.ts | 7 +++- .../project/repository/artifact/artifact.ts | 1 + 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-filter/artifact-filter.component.html b/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-filter/artifact-filter.component.html index 10fd11d1e370..7e59a8a6d3f0 100644 --- a/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-filter/artifact-filter.component.html +++ b/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-filter/artifact-filter.component.html @@ -36,11 +36,13 @@
+ [(ngModel)]="inputTag" + (keyup)="searchByInputTag()" + class="clr-input no-outline" />
diff --git a/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-filter/artifact-filter.component.scss b/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-filter/artifact-filter.component.scss index 627ecb3e4a7a..3d3a910cb7f8 100644 --- a/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-filter/artifact-filter.component.scss +++ b/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-filter/artifact-filter.component.scss @@ -35,3 +35,8 @@ .search-dropdown-toggle { margin-right: 5px; } + +.no-outline:focus { + border: none; + background: none; +} diff --git a/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-filter/artifact-filter.component.ts b/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-filter/artifact-filter.component.ts index 0ada32cbb44c..5cce58f82234 100644 --- a/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-filter/artifact-filter.component.ts +++ b/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-filter/artifact-filter.component.ts @@ -3,19 +3,23 @@ import { ElementRef, EventEmitter, Input, + OnDestroy, + OnInit, Output, Renderer2, ViewChild, } from '@angular/core'; import { ArtifactFilterEvent, multipleFilter } from '../../../../artifact'; import { Label } from '../../../../../../../../../../ng-swagger-gen/models/label'; +import { debounce, Subject, Subscription } from 'rxjs'; +import { debounceTime } from 'rxjs/operators'; @Component({ selector: 'app-artifact-filter', templateUrl: './artifact-filter.component.html', styleUrls: ['./artifact-filter.component.scss'], }) -export class ArtifactFilterComponent { +export class ArtifactFilterComponent implements OnInit, OnDestroy { @Input() withDivider: boolean = false; @ViewChild('filterArea') @@ -31,6 +35,9 @@ export class ArtifactFilterComponent { filterEvent = new EventEmitter(); readonly searchId: string = 'search-btn'; readonly typeSelectId: string = 'type-select'; + inputTag: string; + private _keyupEventSubject: Subject = new Subject(); + private _keyupEventSubscription: Subscription; constructor(private renderer: Renderer2) { // click outside, then close dropdown this.renderer.listen('window', 'click', (e: Event) => { @@ -45,6 +52,26 @@ export class ArtifactFilterComponent { } }); } + ngOnInit(): void { + if (!this._keyupEventSubscription) { + this._keyupEventSubscription = this._keyupEventSubject + .pipe(debounceTime(500)) + .subscribe(inputTag => { + this.filterEvent.emit({ + type: this.filterByType, + isLabel: false, + isInputTag: true, + stringValue: inputTag, + }); + }); + } + } + ngOnDestroy(): void { + if (this._keyupEventSubscription) { + this._keyupEventSubscription.unsubscribe(); + this._keyupEventSubscription = null; + } + } selectFilterType() { this.selectedValue = null; @@ -87,4 +114,7 @@ export class ArtifactFilterComponent { } return []; } + searchByInputTag() { + this._keyupEventSubject.next(this.inputTag); + } } diff --git a/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.ts b/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.ts index f06d8586b517..9a9608df1a11 100644 --- a/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.ts +++ b/src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/artifact-list-tab.component.ts @@ -816,7 +816,12 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy { } } else { if (e?.stringValue) { - this.filters.push(`${e.type}=${e?.stringValue}`); + if (e?.isInputTag) { + // for input tag, use fuzzy match + this.filters.push(`${e.type}=~${e?.stringValue}`); + } else { + this.filters.push(`${e.type}=${e?.stringValue}`); + } } } this.refresh(); diff --git a/src/portal/src/app/base/project/repository/artifact/artifact.ts b/src/portal/src/app/base/project/repository/artifact/artifact.ts index f5a9704cb7ac..776a625babf4 100644 --- a/src/portal/src/app/base/project/repository/artifact/artifact.ts +++ b/src/portal/src/app/base/project/repository/artifact/artifact.ts @@ -130,5 +130,6 @@ export interface ArtifactFilterEvent { type?: string; stringValue?: string; isLabel?: boolean; + isInputTag?: boolean; label?: Label; }