Merge pull request #6110 from ninjadq/add_chart_2_global_result

Feature: Add helmchart version result in global search result
This commit is contained in:
Qian Deng 2018-10-23 15:46:55 +08:00 committed by GitHub
commit 4b103d115a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 125 additions and 14 deletions

View File

@ -296,7 +296,11 @@ export interface ScrollPosition {
sT: number; sT: number;
cH: number; cH: number;
} }
export interface HelmChartSearchResultItem {
Name: string;
Score: number;
Chart: HelmChartVersion;
}
export interface HelmChartItem { export interface HelmChartItem {
name: string; name: string;
total_versions: number; total_versions: number;

View File

@ -10,5 +10,7 @@
<list-project-ro [projects]="searchResults.project"></list-project-ro> <list-project-ro [projects]="searchResults.project"></list-project-ro>
<h2>{{'PROJECT_DETAIL.REPOSITORIES' | translate}}</h2> <h2>{{'PROJECT_DETAIL.REPOSITORIES' | translate}}</h2>
<list-repository-ro [repositories]="searchResults.repository"></list-repository-ro> <list-repository-ro [repositories]="searchResults.repository"></list-repository-ro>
<h2>{{'HELM_CHART.HELMCHARTS' | translate}}</h2>
<list-chart-version-ro [charts]="searchResults.Chart"></list-chart-version-ro>
</div> </div>
</div> </div>

View File

@ -76,7 +76,7 @@ export class SearchResultComponent implements OnInit, OnDestroy {
if (src) { if (src) {
src.project.forEach(pro => res.project.push(Object.assign({}, pro))); src.project.forEach(pro => res.project.push(Object.assign({}, pro)));
src.repository.forEach(repo => res.repository.push(Object.assign({}, repo))); src.repository.forEach(repo => res.repository.push(Object.assign({}, repo)));
src.Chart.forEach(chart => res.Chart.push(JSON.parse(JSON.stringify(chart))));
return res; return res;
} }
@ -135,7 +135,7 @@ export class SearchResultComponent implements OnInit, OnDestroy {
this.search.doSearch(term) this.search.doSearch(term)
.then(searchResults => { .then(searchResults => {
this.onGoing = false; this.onGoing = false;
this.originalCopy = searchResults; // Keeo the original data this.originalCopy = searchResults; // Keep the original data
this.searchResults = this.clone(searchResults); this.searchResults = this.clone(searchResults);
}) })
.catch(error => { .catch(error => {

View File

@ -12,14 +12,16 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Project } from "../../project/project"; import { Project } from "../../project/project";
import { Repository } from "@harbor/ui"; import { Repository, HelmChartSearchResultItem } from "@harbor/ui";
export class SearchResults { export class SearchResults {
constructor() { constructor() {
this.project = []; this.project = [];
this.repository = []; this.repository = [];
this.Chart = [];
} }
project: Project[]; project: Project[];
repository: Repository[]; repository: Repository[];
Chart: HelmChartSearchResultItem[];
} }

View File

@ -35,7 +35,7 @@ export class ProjectService {
catchError(error => observableThrowError(error)), ); catchError(error => observableThrowError(error)), );
} }
listProjects(name: string, isPublic: number, page?: number, pageSize?: number): Observable<any> { listProjects(name: string, isPublic?: number, page?: number, pageSize?: number): Observable<any> {
let params = new URLSearchParams(); let params = new URLSearchParams();
if (page && pageSize) { if (page && pageSize) {
params.set('page', page + ''); params.set('page', page + '');
@ -47,7 +47,6 @@ export class ProjectService {
if (isPublic !== undefined) { if (isPublic !== undefined) {
params.set('public', '' + isPublic); params.set('public', '' + isPublic);
} }
return this.http return this.http
.get(`/api/projects`, buildHttpRequestOptions(params)).pipe( .get(`/api/projects`, buildHttpRequestOptions(params)).pipe(
map(response => response), map(response => response),

View File

@ -0,0 +1,25 @@
<clr-datagrid>
<clr-dg-column>{{'HELM_CHART.NAME' | translate}}</clr-dg-column>
<clr-dg-column>{{'HELM_CHART.VERSION' | translate}}</clr-dg-column>
<clr-dg-column>{{'HELM_CHART.STATUS' | translate }}</clr-dg-column>
<clr-dg-column>{{'HELM_CHART.MAINTAINERS' | translate }}</clr-dg-column>
<clr-dg-column>{{'HELM_CHART.CREATED' | translate }}</clr-dg-column>
<clr-dg-placeholder>{{'HELM_CHART.NO_VERSION_PLACEHOLDER' | translate }}</clr-dg-placeholder>
<clr-dg-row *clrDgItems="let chart of charts" [clrDgItem]="chart">
<clr-dg-cell>
<a href="javascript:void(0)" (click)="gotoChartVersion(chart.Chart)">{{ chart.Name }}</a>
</clr-dg-cell>
<clr-dg-cell>{{ chart.Chart.version }}</clr-dg-cell>
<clr-dg-cell>{{ getStatusString(chart.Chart) | translate }}</clr-dg-cell>
<clr-dg-cell>{{ getMaintainerString(chart.Chart.maintainers) | translate : getMaintainerTranslateInfo(chart.Chart.maintainers) }}</clr-dg-cell>
<clr-dg-cell>{{ chart.Chart.created | date}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<clr-dg-pagination #pagination [clrDgPageSize]="5" [clrDgTotalItems]="pagination.totalItems">
<span *ngIf="pagination.totalItems">
{{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} {{'HELM_CHART.OF' | translate}}
</span>
{{pagination.totalItems}} {{'HELM_CHART.ITEMS'| translate}}
</clr-dg-pagination>
</clr-dg-footer>
</clr-datagrid>

View File

@ -0,0 +1,69 @@
import { extractJson } from './../shared.utils';
import { Router } from '@angular/router';
import { Component, OnInit, Input } from '@angular/core';
import { HelmChartSearchResultItem, HelmChartVersion, HelmChartMaintainer } from '@harbor/ui';
import { SearchTriggerService } from '../../base/global-search/search-trigger.service';
import { ProjectService } from '../../project/project.service';
@Component({
selector: 'list-chart-version-ro',
templateUrl: './list-chart-version-ro.component.html'
})
export class ListChartVersionRoComponent implements OnInit {
@Input() projectId: number;
@Input() charts: HelmChartSearchResultItem;
constructor(
private searchTrigger: SearchTriggerService,
private projectService: ProjectService,
private router: Router) { }
ngOnInit() {
}
getStatusString(chart: HelmChartVersion) {
if (chart.deprecated) {
return "HELM_CHART.DEPRECATED";
} else {
return "HELM_CHART.ACTIVE";
}
}
getMaintainerString(maintainers: HelmChartMaintainer[]) {
if (!maintainers || maintainers.length < 1) {
return "";
}
let maintainer_string = maintainers[0].name;
if (maintainers.length > 1) {
maintainer_string = "HELM_CHART.OTHER_MAINTAINERS";
}
return maintainer_string;
}
getMaintainerTranslateInfo(maintainers: HelmChartMaintainer[]) {
if (!maintainers || maintainers.length < 1) {
return {};
}
let name = maintainers[0].name;
let number = maintainers.length;
return {name: name, number: number};
}
gotoChartVersion(chartVersion: HelmChartVersion) {
this.searchTrigger.closeSearch(true);
let [projectName, chartName] = chartVersion.name.split('/');
this.projectService.listProjects(projectName).subscribe( res => {
let projects = extractJson(res);
if (projects || projects.length >= 1) {
let linkUrl = ['harbor', 'projects', projects[0].project_id, 'helm-charts', chartName, 'versions', chartVersion.version];
this.router.navigate(linkUrl);
} else {
return;
}
});
}
}

View File

@ -30,11 +30,7 @@ export class ListProjectROComponent {
constructor( constructor(
private searchTrigger: SearchTriggerService, private searchTrigger: SearchTriggerService,
private router: Router, private router: Router) {}
private ref: ChangeDetectorRef) {
let hnd = setInterval(() => ref.markForCheck(), 100);
setTimeout(() => clearInterval(hnd), 1000);
}
goToLink(proId: number): void { goToLink(proId: number): void {
this.searchTrigger.closeSearch(true); this.searchTrigger.closeSearch(true);

View File

@ -52,6 +52,7 @@ import { GaugeComponent } from "./gauge/gauge.component";
import { ConfirmationDialogComponent } from "./confirmation-dialog/confirmation-dialog.component"; import { ConfirmationDialogComponent } from "./confirmation-dialog/confirmation-dialog.component";
import { ConfirmationDialogService } from "./confirmation-dialog/confirmation-dialog.service"; import { ConfirmationDialogService } from "./confirmation-dialog/confirmation-dialog.service";
import { MessageHandlerService } from "./message-handler/message-handler.service"; import { MessageHandlerService } from "./message-handler/message-handler.service";
import { ListChartVersionRoComponent } from './list-chart-version-ro/list-chart-version-ro.component';
const uiLibConfig: IServiceConfig = { const uiLibConfig: IServiceConfig = {
enablei18Support: true, enablei18Support: true,
@ -103,7 +104,8 @@ const uiLibConfig: IServiceConfig = {
ListProjectROComponent, ListProjectROComponent,
ListRepositoryROComponent, ListRepositoryROComponent,
GaugeComponent, GaugeComponent,
DateValidatorDirective DateValidatorDirective,
ListChartVersionRoComponent
], ],
exports: [ exports: [
CoreModule, CoreModule,
@ -124,7 +126,8 @@ const uiLibConfig: IServiceConfig = {
GaugeComponent, GaugeComponent,
DateValidatorDirective, DateValidatorDirective,
FormsModule, FormsModule,
ReactiveFormsModule ReactiveFormsModule,
ListChartVersionRoComponent
], ],
providers: [ providers: [
SessionService, SessionService,

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { NgForm } from '@angular/forms'; import { NgForm } from '@angular/forms';
import {RequestOptions, Headers} from "@angular/http"; import {RequestOptions, Headers, Response} from "@angular/http";
import { Comparator, State } from '@clr/angular'; import { Comparator, State } from '@clr/angular';
import {RequestQueryParams} from "@harbor/ui"; import {RequestQueryParams} from "@harbor/ui";
@ -301,3 +301,10 @@ export function doSorting<T extends { [key: string]: any | any[] }>(items: T[],
return comp; return comp;
}); });
} }
export const extractJson = (res: Response) => {
if (res.text() === '') {
return [];
}
return (res.json() || []);
};

View File

@ -490,6 +490,7 @@
"SRC_REPO": "Source Repository", "SRC_REPO": "Source Repository",
"CREATED": "Created Time", "CREATED": "Created Time",
"MAINTAINERS": "Maintainers", "MAINTAINERS": "Maintainers",
"OTHER_MAINTAINERS": "{{ name }} and {{ number }} others",
"PULLS": "Pull Count", "PULLS": "Pull Count",
"VERSION": "Version", "VERSION": "Version",
"APP_VERSION": "Application Version", "APP_VERSION": "Application Version",

View File

@ -489,6 +489,7 @@
"SRC_REPO": "Source Repository", "SRC_REPO": "Source Repository",
"CREATED": "Created Time", "CREATED": "Created Time",
"MAINTAINERS": "Maintainers", "MAINTAINERS": "Maintainers",
"OTHER_MAINTAINERS": "{{ name }} and {{ number }} others",
"PULLS": "Pull Count", "PULLS": "Pull Count",
"VERSION": "Version", "VERSION": "Version",
"APP_VERSION": "Application Version", "APP_VERSION": "Application Version",

View File

@ -467,6 +467,7 @@
"SRC_REPO": "Source Repository", "SRC_REPO": "Source Repository",
"CREATED": "Created Time", "CREATED": "Created Time",
"MAINTAINERS": "Maintainers", "MAINTAINERS": "Maintainers",
"OTHER_MAINTAINERS": "{{ name }} and {{ number }} others",
"PULLS": "Pull Count", "PULLS": "Pull Count",
"VERSION": "Version", "VERSION": "Version",
"APP_VERSION": "Application Version", "APP_VERSION": "Application Version",

View File

@ -489,6 +489,7 @@
"SRC_REPO": "源仓库", "SRC_REPO": "源仓库",
"CREATED": "创建时间", "CREATED": "创建时间",
"MAINTAINERS": "维护者", "MAINTAINERS": "维护者",
"OTHER_MAINTAINERS": "{{ name }} 与其他 {{ number }} 位",
"PULLS": "拉取数", "PULLS": "拉取数",
"VERSION": "版本", "VERSION": "版本",
"INSTALL": "安装", "INSTALL": "安装",