add placeholders to the datagird

This commit is contained in:
Steven Zou 2017-06-14 00:00:22 +08:00
parent f981415b5b
commit 23635b6966
8 changed files with 79 additions and 15 deletions

View File

@ -52,10 +52,9 @@ If no parameters are passed to **'forRoot'**, the module will be initialized wit
* **Registry log view** * **Registry log view**
Use **withTitle** to set whether self-contained a header with title or not. Default is **false**, that means no header is existing.
``` ```
//No @Input properties <hbr-log [withTitle]="..."></hbr-log>
<hbr-log></hbr-log>
``` ```
* **Replication Management View** * **Replication Management View**
@ -85,8 +84,18 @@ If **projectId** is set to the id of specified project, then only show the repli
**hasProjectAdminRole** is a user session related property to determined whether the current user has project administrator role. Some action menus might be disabled based on this property. **hasProjectAdminRole** is a user session related property to determined whether the current user has project administrator role. Some action menus might be disabled based on this property.
**tagClickEvent** is an @output event emitter for you to catch the tag click events.
``` ```
<hbr-repository-stackview [projectId]="..." [hasSignedIn]="..." [hasProjectAdminRole]="..."></hbr-repository-stackview> <hbr-repository-stackview [projectId]="..." [hasSignedIn]="..." [hasProjectAdminRole]="..." (tagClickEvent)="watchTagClickEvent($event)"></hbr-repository-stackview>
...
watchTagClickEvent(tag: Tag): void {
//Process tag
...
}
``` ```
## Configurations ## Configurations
@ -96,7 +105,7 @@ All the related configurations are defined in the **HarborModuleConfig** interfa
The base configuration for the module. Mainly used to define the relevant endpoints of services which are in charge of retrieving data from backend APIs. It's a 'OpaqueToken' and defined by 'IServiceConfig' interface. If **config** is not set, the default value will be used. The base configuration for the module. Mainly used to define the relevant endpoints of services which are in charge of retrieving data from backend APIs. It's a 'OpaqueToken' and defined by 'IServiceConfig' interface. If **config** is not set, the default value will be used.
``` ```
export const DefaultServiceConfig: IServiceConfig = { export const DefaultServiceConfig: IServiceConfig = {
systemInfoEndpoint: "/api/system", systemInfoEndpoint: "/api/systeminfo",
repositoryBaseEndpoint: "/api/repositories", repositoryBaseEndpoint: "/api/repositories",
logBaseEndpoint: "/api/logs", logBaseEndpoint: "/api/logs",
targetBaseEndpoint: "/api/targets", targetBaseEndpoint: "/api/targets",
@ -126,6 +135,8 @@ HarborLibraryModule.forRoot({
``` ```
It supports partially overriding. For the items not overridden, default values will be adopted. The items contained in **config** are: It supports partially overriding. For the items not overridden, default values will be adopted. The items contained in **config** are:
* **systemInfoEndpoint:** The base endpoint of the service used to get the related system configurations. Default value is "/api/systeminfo".
* **repositoryBaseEndpoint:** The base endpoint of the service used to handle the repositories of registry and/or tags of repository. Default value is "/api/repositories". * **repositoryBaseEndpoint:** The base endpoint of the service used to handle the repositories of registry and/or tags of repository. Default value is "/api/repositories".
* **logBaseEndpoint:** The base endpoint of the service used to handle the recent access logs. Default is "/api/logs". * **logBaseEndpoint:** The base endpoint of the service used to handle the recent access logs. Default is "/api/logs".
@ -578,32 +589,39 @@ HarborLibraryModule.forRoot({
* **ScanningResultService:** Get the vulnerabilities scanning results for the specified tag. * **ScanningResultService:** Get the vulnerabilities scanning results for the specified tag.
``` ```
@Injectable() @Injectable()
/**
* Get the vulnerabilities scanning results for the specified tag.
*
* @export
* @abstract
* @class ScanningResultService
*/
export class MyScanningResultService extends ScanningResultService { export class MyScanningResultService extends ScanningResultService {
/** /**
* Get the summary of vulnerability scanning result. * Get the summary of vulnerability scanning result.
* *
* @abstract * @abstract
* @param {string} tagId * @param {string} tagId
* @returns {(Observable<ScanningResultSummary> | Promise<ScanningResultSummary> | ScanningResultSummary)} * @returns {(Observable<VulnerabilitySummary> | Promise<VulnerabilitySummary> | VulnerabilitySummary)}
* *
* @memberOf ScanningResultService * @memberOf ScanningResultService
*/ */
getScanningResultSummary(tagId: string): Observable<ScanningResultSummary> | Promise<ScanningResultSummary> | ScanningResultSummary { getVulnerabilityScanningSummary(tagId: string): Observable<VulnerabilitySummary> | Promise<VulnerabilitySummary> | VulnerabilitySummary{
... ...
} }
/** /**
* Get the detailed vulnerabilities scanning results. * Get the detailed vulnerabilities scanning results.
* *
* @abstract * @abstract
* @param {string} tagId * @param {string} tagId
* @returns {(Observable<ScanningDetailResult[]> | Promise<ScanningDetailResult[]> | ScanningDetailResult[])} * @returns {(Observable<VulnerabilityItem[]> | Promise<VulnerabilityItem[]> | VulnerabilityItem[])}
* *
* @memberOf ScanningResultService * @memberOf ScanningResultService
*/ */
getScanningResults(tagId: string): Observable<ScanningDetailResult[]> | Promise<ScanningDetailResult[]> | ScanningDetailResult[] { getVulnerabilityScanningResults(tagId: string): Observable<VulnerabilityItem[]> | Promise<VulnerabilityItem[]> | VulnerabilityItem[]{
... ...
} }
} }
... ...
@ -612,4 +630,30 @@ HarborLibraryModule.forRoot({
}) })
... ...
```
* **SystemInfoService:** Get related system configurations.
```
/**
* Get System information about current backend server.
* @abstract
* @class
*/
export class MySystemInfoService extends SystemInfoService {
/**
* Get global system information.
* @abstract
* @returns
*/
getSystemInfo(): Observable<SystemInfo> | Promise<SystemInfo> | SystemInfo {
...
}
}
...
HarborLibraryModule.forRoot({
systemInfoService: { provide: SystemInfoService, useClass: MySystemInfoService }
})
...
``` ```

View File

@ -20,6 +20,7 @@ export const ENDPOINT_TEMPLATE: string = `
<clr-dg-column [clrDgField]="'name'">{{'DESTINATION.NAME' | translate}}</clr-dg-column> <clr-dg-column [clrDgField]="'name'">{{'DESTINATION.NAME' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'endpoint'">{{'DESTINATION.URL' | translate}}</clr-dg-column> <clr-dg-column [clrDgField]="'endpoint'">{{'DESTINATION.URL' | translate}}</clr-dg-column>
<clr-dg-column [clrDgSortBy]="creationTimeComparator">{{'DESTINATION.CREATION_TIME' | translate}}</clr-dg-column> <clr-dg-column [clrDgSortBy]="creationTimeComparator">{{'DESTINATION.CREATION_TIME' | translate}}</clr-dg-column>
<clr-dg-placeholder>{{'DESTINATION.PLACEHOLDER' | translate }}</clr-dg-placeholder>
<clr-dg-row *clrDgItems="let t of targets" [clrDgItem]='t'> <clr-dg-row *clrDgItems="let t of targets" [clrDgItem]='t'>
<clr-dg-action-overflow> <clr-dg-action-overflow>
<button class="action-item" (click)="editTarget(t)">{{'DESTINATION.TITLE_EDIT' | translate}}</button> <button class="action-item" (click)="editTarget(t)">{{'DESTINATION.TITLE_EDIT' | translate}}</button>

View File

@ -7,6 +7,7 @@ export const LIST_REPLICATION_RULE_TEMPLATE: string = `
<clr-dg-column [clrDgField]="'target_name'">{{'REPLICATION.DESTINATION_NAME' | translate}}</clr-dg-column> <clr-dg-column [clrDgField]="'target_name'">{{'REPLICATION.DESTINATION_NAME' | translate}}</clr-dg-column>
<clr-dg-column [clrDgSortBy]="startTimeComparator">{{'REPLICATION.LAST_START_TIME' | translate}}</clr-dg-column> <clr-dg-column [clrDgSortBy]="startTimeComparator">{{'REPLICATION.LAST_START_TIME' | translate}}</clr-dg-column>
<clr-dg-column [clrDgSortBy]="enabledComparator">{{'REPLICATION.ACTIVATION' | translate}}</clr-dg-column> <clr-dg-column [clrDgSortBy]="enabledComparator">{{'REPLICATION.ACTIVATION' | translate}}</clr-dg-column>
<clr-dg-placeholder>{{'REPLICATION.PLACEHOLDER' | translate }}</clr-dg-placeholder>
<clr-dg-row *clrDgItems="let p of changedRules" [clrDgItem]="p" (click)="selectRule(p)" [style.backgroundColor]="(!projectScope && withReplicationJob && selectedId === p.id) ? '#eee' : ''"> <clr-dg-row *clrDgItems="let p of changedRules" [clrDgItem]="p" (click)="selectRule(p)" [style.backgroundColor]="(!projectScope && withReplicationJob && selectedId === p.id) ? '#eee' : ''">
<clr-dg-action-overflow> <clr-dg-action-overflow>
<button class="action-item" (click)="editRule(p)">{{'REPLICATION.EDIT_POLICY' | translate}}</button> <button class="action-item" (click)="editRule(p)">{{'REPLICATION.EDIT_POLICY' | translate}}</button>

View File

@ -3,6 +3,7 @@ export const LIST_REPOSITORY_TEMPLATE = `
<clr-dg-column [clrDgField]="'name'">{{'REPOSITORY.NAME' | translate}}</clr-dg-column> <clr-dg-column [clrDgField]="'name'">{{'REPOSITORY.NAME' | translate}}</clr-dg-column>
<clr-dg-column [clrDgSortBy]="tagsCountComparator">{{'REPOSITORY.TAGS_COUNT' | translate}}</clr-dg-column> <clr-dg-column [clrDgSortBy]="tagsCountComparator">{{'REPOSITORY.TAGS_COUNT' | translate}}</clr-dg-column>
<clr-dg-column [clrDgSortBy]="pullCountComparator">{{'REPOSITORY.PULL_COUNT' | translate}}</clr-dg-column> <clr-dg-column [clrDgSortBy]="pullCountComparator">{{'REPOSITORY.PULL_COUNT' | translate}}</clr-dg-column>
<clr-dg-placeholder>{{'REPOSITORY.PLACEHOLDER' | translate }}</clr-dg-placeholder>
<clr-dg-row *clrDgItems="let r of repositories" [clrDgItem]='r'> <clr-dg-row *clrDgItems="let r of repositories" [clrDgItem]='r'>
<clr-dg-action-overflow [hidden]="!hasProjectAdminRole"> <clr-dg-action-overflow [hidden]="!hasProjectAdminRole">
<button class="action-item" (click)="deleteRepo(r.name)">{{'REPOSITORY.DELETE' | translate}}</button> <button class="action-item" (click)="deleteRepo(r.name)">{{'REPOSITORY.DELETE' | translate}}</button>

View File

@ -53,6 +53,7 @@ export const REPLICATION_TEMPLATE: string = `
<clr-dg-column [clrDgSortBy]="creationTimeComparator">{{'REPLICATION.CREATION_TIME' | translate}}</clr-dg-column> <clr-dg-column [clrDgSortBy]="creationTimeComparator">{{'REPLICATION.CREATION_TIME' | translate}}</clr-dg-column>
<clr-dg-column [clrDgSortBy]="updateTimeComparator">{{'REPLICATION.END_TIME' | translate}}</clr-dg-column> <clr-dg-column [clrDgSortBy]="updateTimeComparator">{{'REPLICATION.END_TIME' | translate}}</clr-dg-column>
<clr-dg-column>{{'REPLICATION.LOGS' | translate}}</clr-dg-column> <clr-dg-column>{{'REPLICATION.LOGS' | translate}}</clr-dg-column>
<clr-dg-placeholder>{{'REPLICATION.JOB_PLACEHOLDER' | translate }}</clr-dg-placeholder>
<clr-dg-row *clrDgItems="let j of jobs" [clrDgItem]='j'> <clr-dg-row *clrDgItems="let j of jobs" [clrDgItem]='j'>
<clr-dg-cell>{{j.repository}}</clr-dg-cell> <clr-dg-cell>{{j.repository}}</clr-dg-cell>
<clr-dg-cell>{{j.status}}</clr-dg-cell> <clr-dg-cell>{{j.status}}</clr-dg-cell>

View File

@ -21,7 +21,7 @@ export const REPOSITORY_STACKVIEW_TEMPLATE: string = `
<clr-dg-cell>{{r.name}}</clr-dg-cell> <clr-dg-cell>{{r.name}}</clr-dg-cell>
<clr-dg-cell>{{r.tags_count}}</clr-dg-cell> <clr-dg-cell>{{r.tags_count}}</clr-dg-cell>
<clr-dg-cell>{{r.pull_count}}</clr-dg-cell> <clr-dg-cell>{{r.pull_count}}</clr-dg-cell>
<hbr-tag *clrIfExpanded ngProjectAs="clr-dg-row-detail" class="sub-grid-custom" [repoName]="r.name" [registryUrl]="registryUrl" [withNotary]="withNotary" [hasSignedIn]="hasSignedIn" [hasProjectAdminRole]="hasProjectAdminRole" [projectId]="projectId" [isEmbedded]="true" (refreshRepo)="refresh($event)"></hbr-tag> <hbr-tag *clrIfExpanded ngProjectAs="clr-dg-row-detail" (tagClickEvent)="watchTagClickEvt($event)" class="sub-grid-custom" [repoName]="r.name" [registryUrl]="registryUrl" [withNotary]="withNotary" [hasSignedIn]="hasSignedIn" [hasProjectAdminRole]="hasProjectAdminRole" [projectId]="projectId" [isEmbedded]="true" (refreshRepo)="refresh($event)"></hbr-tag>
</clr-dg-row> </clr-dg-row>
<clr-dg-footer> <clr-dg-footer>
{{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} {{'REPOSITORY.OF' | translate}} {{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} {{'REPOSITORY.OF' | translate}}

View File

@ -1,4 +1,13 @@
import { Component, Input, OnInit, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; import {
Component,
Input,
Output,
OnInit,
ViewChild,
ChangeDetectionStrategy,
ChangeDetectorRef,
EventEmitter
} from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { Comparator } from 'clarity-angular'; import { Comparator } from 'clarity-angular';
@ -21,6 +30,7 @@ import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation
import { ConfirmationMessage } from '../confirmation-dialog/confirmation-message'; import { ConfirmationMessage } from '../confirmation-dialog/confirmation-message';
import { ConfirmationAcknowledgement } from '../confirmation-dialog/confirmation-state-message'; import { ConfirmationAcknowledgement } from '../confirmation-dialog/confirmation-state-message';
import { Subscription } from 'rxjs/Subscription'; import { Subscription } from 'rxjs/Subscription';
import { Tag } from '../service/interface';
@Component({ @Component({
selector: 'hbr-repository-stackview', selector: 'hbr-repository-stackview',
@ -34,6 +44,7 @@ export class RepositoryStackviewComponent implements OnInit {
@Input() hasSignedIn: boolean; @Input() hasSignedIn: boolean;
@Input() hasProjectAdminRole: boolean; @Input() hasProjectAdminRole: boolean;
@Output() tagClickEvent = new EventEmitter<Tag>();
lastFilteredRepoName: string; lastFilteredRepoName: string;
repositories: Repository[]; repositories: Repository[];
@ -120,4 +131,8 @@ export class RepositoryStackviewComponent implements OnInit {
refresh() { refresh() {
this.retrieve(); this.retrieve();
} }
watchTagClickEvt(tag: Tag): void {
this.tagClickEvent.emit(tag);
}
} }

View File

@ -22,6 +22,7 @@ export const TAG_TEMPLATE = `
<clr-dg-column [clrDgField]="'docker_version'">{{'REPOSITORY.DOCKER_VERSION' | translate}}</clr-dg-column> <clr-dg-column [clrDgField]="'docker_version'">{{'REPOSITORY.DOCKER_VERSION' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'architecture'">{{'REPOSITORY.ARCHITECTURE' | translate}}</clr-dg-column> <clr-dg-column [clrDgField]="'architecture'">{{'REPOSITORY.ARCHITECTURE' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'os'">{{'REPOSITORY.OS' | translate}}</clr-dg-column> <clr-dg-column [clrDgField]="'os'">{{'REPOSITORY.OS' | translate}}</clr-dg-column>
<clr-dg-placeholder>{{'TGA.PLACEHOLDER' | translate }}</clr-dg-placeholder>
<clr-dg-row *clrDgItems="let t of tags" [clrDgItem]='t'> <clr-dg-row *clrDgItems="let t of tags" [clrDgItem]='t'>
<clr-dg-action-overflow> <clr-dg-action-overflow>
<button class="action-item" (click)="showDigestId(t)">{{'REPOSITORY.COPY_DIGEST_ID' | translate}}</button> <button class="action-item" (click)="showDigestId(t)">{{'REPOSITORY.COPY_DIGEST_ID' | translate}}</button>