mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-04 01:30:15 +01:00
[Cherry-pick]Support searching artifacts by specified tag name (#18176)
Support searching artifacts by specified tag name 1.Fixes #18082 2.Update CSS Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
dc931cfd2c
commit
7f0bd60a8b
@ -36,11 +36,13 @@
|
||||
<div class="clr-control-container" *ngIf="!selectedValue">
|
||||
<div class="clr-input-wrapper">
|
||||
<input
|
||||
readonly
|
||||
[readonly]="filterByType !== 'tags'"
|
||||
placeholder="{{
|
||||
'ARTIFACT.FILTER_FOR_ARTIFACTS' | translate
|
||||
}}"
|
||||
class="clr-input" />
|
||||
[(ngModel)]="inputTag"
|
||||
(keyup)="searchByInputTag()"
|
||||
class="clr-input no-outline" />
|
||||
</div>
|
||||
</div>
|
||||
<span *ngIf="selectedValue">
|
||||
|
@ -35,3 +35,8 @@
|
||||
.search-dropdown-toggle {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.no-outline:focus {
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
|
@ -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 { 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<ArtifactFilterEvent>();
|
||||
readonly searchId: string = 'search-btn';
|
||||
readonly typeSelectId: string = 'type-select';
|
||||
inputTag: string;
|
||||
private _keyupEventSubject: Subject<string> = 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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -130,5 +130,6 @@ export interface ArtifactFilterEvent {
|
||||
type?: string;
|
||||
stringValue?: string;
|
||||
isLabel?: boolean;
|
||||
isInputTag?: boolean;
|
||||
label?: Label;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user