Add harbor datetime pipe (#14331)

Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
Will Sun 2021-03-01 15:45:21 +08:00 committed by GitHub
parent 9161a3fbdf
commit 3ecd60b84b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 119 additions and 123 deletions

View File

@ -74,8 +74,7 @@ Start
"/i18n/lang/*.json": {
"target": "https://hostname",
"secure": false,
"logLevel": "debug",
"pathRewrite": { "^/src$": "" }
"logLevel": "debug"
},
"/swagger.json": {
"target": "https://hostname",

View File

@ -51,9 +51,6 @@ class MyMissingTranslationHandler implements MissingTranslationHandler {
}
}
@NgModule({
declarations: [
AppComponent,

View File

@ -105,7 +105,7 @@
</div>
</clr-dg-cell>
<clr-dg-cell>{{ instance.auth_mode }}</clr-dg-cell>
<clr-dg-cell>{{fmtTime(instance.setup_timestamp) | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{fmtTime(instance.setup_timestamp) | harborDatetime: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{ instance.description }}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>

View File

@ -15,8 +15,8 @@
<clr-dg-cell>{{(job.type ? 'SCHEDULE.'+ job.type.toUpperCase() : '') | translate }}</clr-dg-cell>
<clr-dg-cell>{{isDryRun(job?.parameters) | translate}}</clr-dg-cell>
<clr-dg-cell>{{job.status.toUpperCase() | translate}}</clr-dg-cell>
<clr-dg-cell>{{job.createTime | date:'medium'}}</clr-dg-cell>
<clr-dg-cell>{{job.updateTime | date:'medium'}}</clr-dg-cell>
<clr-dg-cell>{{job.createTime | harborDatetime:'medium'}}</clr-dg-cell>
<clr-dg-cell>{{job.updateTime | harborDatetime:'medium'}}</clr-dg-cell>
<clr-dg-cell>
<a *ngIf="job.status.toLowerCase() === 'success' || job.status.toLowerCase() === 'error'" target="_blank" [href]="getLogLink(job.id)"><clr-icon shape="list"></clr-icon></a>
</clr-dg-cell>

View File

@ -32,7 +32,7 @@
<clr-dg-cell>{{l.resource}}</clr-dg-cell>
<clr-dg-cell>{{l.resource_type}}</clr-dg-cell>
<clr-dg-cell>{{l.operation}}</clr-dg-cell>
<clr-dg-cell>{{l.op_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{l.op_time | harborDatetime: 'short'}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<clr-dg-pagination #pagination [(clrDgPage)]="currentPage" [clrDgPageSize]="pageSize" [clrDgTotalItems]="totalCount">

View File

@ -22,7 +22,7 @@
<clr-dg-cell>{{projectTypeMap[p.registry_id ? 1 : 0] | translate}}</clr-dg-cell>
<clr-dg-cell>{{p.repo_count}}</clr-dg-cell>
<clr-dg-cell *ngIf="withChartMuseum">{{p.chart_count}}</clr-dg-cell>
<clr-dg-cell>{{p.creation_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{p.creation_time | harborDatetime: 'short'}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<clr-dg-pagination #pagination [clrDgPageSize]="pageSize" [(clrDgPage)]="currentPage" [clrDgTotalItems]="totalCount">

View File

@ -50,7 +50,7 @@
{{!t.insecure}}
</clr-dg-cell>
<clr-dg-cell>{{t.credential.type}}</clr-dg-cell>
<clr-dg-cell>{{t.creation_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{t.creation_time | harborDatetime: 'short'}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<clr-dg-pagination #pagination [clrDgPageSize]="15">

View File

@ -44,7 +44,7 @@
</div>
<div>
<label>{{'REPLICATION.CREATION_TIME' | translate}} :</label>
<span>{{startTime | date: 'short'}}</span>
<span>{{startTime | harborDatetime: 'short'}}</span>
</div>
</div>
<div class="flex-block">
@ -110,8 +110,8 @@
<clr-dg-cell>{{t.dst_resource}}</clr-dg-cell>
<clr-dg-cell>{{t.operation}}</clr-dg-cell>
<clr-dg-cell>{{getStatusStr(t.status)}}</clr-dg-cell>
<clr-dg-cell>{{t.start_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{t.end_time && t.end_time != '0001-01-01T00:00:00Z' ? (t.end_time | date: 'short') : "-"}}</clr-dg-cell>
<clr-dg-cell>{{t.start_time | harborDatetime: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{t.end_time && t.end_time != '0001-01-01T00:00:00Z' ? (t.end_time | harborDatetime: 'short') : "-"}}</clr-dg-cell>
<clr-dg-cell>
<a target="_blank" [href]="viewLog(t.id)" *ngIf="t.status !== 'Initialized'">
<clr-icon shape="list"></clr-icon>

View File

@ -13,6 +13,7 @@ import { delay } from "rxjs/operators";
import { HttpHeaders, HttpResponse } from "@angular/common/http";
import { ClarityModule } from "@clr/angular";
import { ReplicationTask } from "../../../../../../../ng-swagger-gen/models/replication-task";
import { SharedTestingModule } from "../../../../../shared/shared.module";
describe('ReplicationTasksComponent', () => {
@ -74,10 +75,7 @@ describe('ReplicationTasksComponent', () => {
schemas: [CUSTOM_ELEMENTS_SCHEMA,
NO_ERRORS_SCHEMA],
imports: [
NoopAnimationsModule,
RouterTestingModule,
ClarityModule,
TranslateModule.forRoot()
SharedTestingModule
],
declarations: [
ReplicationTasksComponent,

View File

@ -73,7 +73,7 @@
</clr-tooltip>
</clr-dg-cell>
<clr-dg-cell>{{j.trigger}}</clr-dg-cell>
<clr-dg-cell>{{j.start_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{j.start_time | harborDatetime: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{getDuration(j)}}</clr-dg-cell>
<clr-dg-cell>
{{((j.status === 'InProgress' || j.status === 'Failed')? (j.total > 0 ? j.succeed / j.total : 0): j.total > 0 ? j.succeed / j.total : 1)| percent }}

View File

@ -24,7 +24,7 @@
<clr-dg-cell>
<a href="javascript:void(0)" (click)="goToLink(p.project_id)">{{p.name}}</a>
</clr-dg-cell>
<clr-dg-cell>{{p.creation_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{p.creation_time | harborDatetime: 'short'}}</clr-dg-cell>
<clr-dg-cell>
<div class="permissions">
<clr-dropdown [clrCloseMenuOnItemClick]="false">

View File

@ -1,12 +1,9 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ListAllProjectsComponent } from './list-all-projects.component';
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { ClarityModule } from "@clr/angular";
import { RouterTestingModule } from "@angular/router/testing";
import { TranslateModule } from "@ngx-translate/core";
import { clone } from "../../../../shared/units/utils";
import { INITIAL_ACCESSES } from "../system-robot-util";
import { Project } from "../../../../../../ng-swagger-gen/models/project";
import { SharedTestingModule } from "../../../../shared/shared.module";
describe('ListAllProjectsComponent', () => {
let component: ListAllProjectsComponent;
@ -26,10 +23,7 @@ describe('ListAllProjectsComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
BrowserAnimationsModule,
ClarityModule,
RouterTestingModule,
TranslateModule.forRoot(),
SharedTestingModule
],
declarations: [ ListAllProjectsComponent ]
})

View File

@ -73,7 +73,7 @@
<clr-control-helper *ngIf="isEditMode && systemRobot?.duration > 0 && !((expiration.dirty || expiration.touched) && expiration.invalid)|| isExpirationInvalid()">
<span [ngClass]="{showWarning: shouldShowWarning()}">
<clr-icon *ngIf="shouldShowWarning()" class="alert-icon" shape="exclamation-triangle"></clr-icon><span>{{'SYSTEM_ROBOT.EXPIRES_AT' | translate}}</span>:
<span>{{calculateExpiresAt() | date:'short'}}</span>
<span>{{calculateExpiresAt() | harborDatetime:'short'}}</span>
</span>
</clr-control-helper>
</div>

View File

@ -30,7 +30,7 @@
</clr-dropdown>
</div>
</clr-dg-cell>
<clr-dg-cell>{{getProject(p)?.creation_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{getProject(p)?.creation_time | harborDatetime: 'short'}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<clr-dg-pagination #pagination [clrDgPageSize]="10">

View File

@ -1,12 +1,9 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ProjectsModalComponent } from './projects-modal.component';
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { ClarityModule } from "@clr/angular";
import { TranslateModule } from "@ngx-translate/core";
import { RouterTestingModule } from "@angular/router/testing";
import { Project } from "../../../../../../ng-swagger-gen/models/project";
import { Action, PermissionsKinds, Resource } from "../system-robot-util";
import { RobotPermission } from "../../../../../../ng-swagger-gen/models/robot-permission";
import { SharedTestingModule } from "../../../../shared/shared.module";
describe('ProjectsModalComponent', () => {
let component: ProjectsModalComponent;
@ -44,10 +41,7 @@ describe('ProjectsModalComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
BrowserAnimationsModule,
ClarityModule,
RouterTestingModule,
TranslateModule.forRoot(),
SharedTestingModule
],
declarations: [ ProjectsModalComponent ]
})

View File

@ -95,8 +95,8 @@
</span>
</span>
</clr-dg-cell>
<clr-dg-cell>{{r.creation_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{r.expires_at === -1?("ROBOT_ACCOUNT.NEVER_EXPIRED" | translate):(r.expires_at * 1000 | date: 'short')}}</clr-dg-cell>
<clr-dg-cell>{{r.creation_time | harborDatetime: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{r.expires_at === -1?("ROBOT_ACCOUNT.NEVER_EXPIRED" | translate):(r.expires_at * 1000 | harborDatetime: 'short')}}</clr-dg-cell>
<clr-dg-cell>{{r.description}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>

View File

@ -1,7 +1,4 @@
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { ClarityModule } from "@clr/angular";
import { TranslateModule } from "@ngx-translate/core";
import { NO_ERRORS_SCHEMA } from "@angular/core";
import { SystemRobotAccountsComponent } from './system-robot-accounts.component';
import { RobotService } from "../../../../../ng-swagger-gen/services/robot.service";
@ -14,8 +11,8 @@ import { Project } from "../../../../../ng-swagger-gen/models/project";
import { ProjectService } from "../../../../../ng-swagger-gen/services/project.service";
import { MessageHandlerService } from "../../../shared/services/message-handler.service";
import { OperationService } from "../../../shared/components/operation/operation.service";
import { HttpClientTestingModule } from "@angular/common/http/testing";
import { ConfirmationDialogService } from "../../global-confirmation-dialog/confirmation-dialog.service";
import { SharedTestingModule } from "../../../shared/shared.module";
describe('SystemRobotAccountsComponent', () => {
let component: SystemRobotAccountsComponent;
@ -122,10 +119,7 @@ describe('SystemRobotAccountsComponent', () => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
BrowserAnimationsModule,
ClarityModule,
TranslateModule.forRoot(),
HttpClientTestingModule
SharedTestingModule
],
declarations: [ SystemRobotAccountsComponent ],
providers: [

View File

@ -44,7 +44,7 @@
<clr-dg-cell>{{user.username}}</clr-dg-cell>
<clr-dg-cell>{{isSystemAdmin(user)}}</clr-dg-cell>
<clr-dg-cell>{{user.email}}</clr-dg-cell>
<clr-dg-cell>{{user.creation_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{user.creation_time | harborDatetime: 'short'}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<clr-dg-pagination #pagination [clrDgPageSize]="pageSize" [(clrDgPage)]="currentPage" [clrDgTotalItems]="totalCount">

View File

@ -30,7 +30,7 @@
</tr>
<tr>
<td class="left">{{'HELM_CHART.CREATED' | translate }}</td>
<td class="left">{{summary.created | date}}</td>
<td class="left">{{summary.created | harborDatetime}}</td>
</tr>
<tr *ngFor="let maintainer of summary.maintainers; let i = index">
<td class="left" *ngIf="i === 0">{{'HELM_CHART.MAINTAINERS' | translate }}</td>

View File

@ -1,13 +1,12 @@
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { TranslateService } from '@ngx-translate/core';
import { ChartDetailSummaryComponent } from './chart-detail-summary.component';
import { ClarityModule } from '@clr/angular';
import { CUSTOM_ELEMENTS_SCHEMA, SecurityContext } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MarkedOptions, MarkdownModule } from 'ngx-markdown';
import { HelmChartService } from '../helm-chart.service';
import { ErrorHandler } from "../../../../../shared/units/error-handler";
import { MessageHandlerService } from "../../../../../shared/services/message-handler.service";
import { SharedTestingModule } from "../../../../../shared/shared.module";
describe('ChartDetailSummaryComponent', () => {
let component: ChartDetailSummaryComponent;
let fixture: ComponentFixture<ChartDetailSummaryComponent>;
@ -19,9 +18,7 @@ describe('ChartDetailSummaryComponent', () => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ClarityModule,
FormsModule,
SharedTestingModule,
MarkdownModule.forRoot({ sanitize: SecurityContext.HTML }),
],
schemas: [

View File

@ -90,7 +90,7 @@
<clr-dg-cell>{{ getStatusString(v) | translate }}</clr-dg-cell>
<clr-dg-cell>{{ v.engine }}</clr-dg-cell>
<clr-dg-cell>{{ getMaintainerString(v.maintainers) }}</clr-dg-cell>
<clr-dg-cell>{{ v.created | date}}</clr-dg-cell>
<clr-dg-cell>{{ v.created | harborDatetime}}</clr-dg-cell>
<clr-dg-cell>
<div>
<hbr-label-piece *ngIf="v.labels?.length" [label]="v.labels[0]" [labelWidth]="130"> </hbr-label-piece>

View File

@ -50,7 +50,7 @@
</clr-dg-cell>
<clr-dg-cell class="table-center">{{ getStatusString(chart) | translate }}</clr-dg-cell>
<clr-dg-cell class="table-center">{{ chart.total_versions }}</clr-dg-cell>
<clr-dg-cell class="table-center">{{ chart.created | date }}</clr-dg-cell>
<clr-dg-cell class="table-center">{{ chart.created | harborDatetime }}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<clr-dg-pagination #pagination [clrDgPageSize]="pageSize" [clrDgTotalItems]="totalCount">

View File

@ -140,7 +140,7 @@
</clr-signpost-content>
</clr-signpost>
</clr-dg-cell>
<clr-dg-cell>{{p.creation_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{p.creation_time | harborDatetime: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{p.description}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
@ -198,7 +198,7 @@
</clr-tooltip>
</clr-dg-cell>
<clr-dg-cell>{{getTriggerTypeI18nForExecution(execution.trigger) | translate}}</clr-dg-cell>
<clr-dg-cell>{{execution.start_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{execution.start_time | harborDatetime: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{getDuration(execution)}}</clr-dg-cell>
<clr-dg-cell>{{getSuccessRate(execution.metrics) | percent}}</clr-dg-cell>
<clr-dg-cell>{{execution.vendor_type}}</clr-dg-cell>

View File

@ -1,14 +1,8 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { ActivatedRoute } from '@angular/router';
import { MessageHandlerService } from "../../../../shared/services/message-handler.service";
import { of } from 'rxjs';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ClarityModule } from '@clr/angular';
import { FormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { delay } from "rxjs/operators";
import { ConfirmationDialogComponent } from "../../../../shared/components/confirmation-dialog";
import { ProjectService, UserPermissionService } from '../../../../shared/services';
@ -23,6 +17,7 @@ import { SessionService } from '../../../../shared/services/session.service';
import { AppConfigService } from '../../../../services/app-config.service';
import { ErrorHandler } from '../../../../shared/units/error-handler';
import { InlineAlertComponent } from "../../../../shared/components/inline-alert/inline-alert.component";
import { SharedTestingModule } from "../../../../shared/shared.module";
describe('PolicyComponent', () => {
let component: PolicyComponent;
@ -131,13 +126,7 @@ describe('PolicyComponent', () => {
CUSTOM_ELEMENTS_SCHEMA
],
imports: [
BrowserAnimationsModule,
ClarityModule,
TranslateModule.forRoot(),
FormsModule,
RouterTestingModule,
NoopAnimationsModule,
HttpClientTestingModule
SharedTestingModule
],
declarations: [PolicyComponent,
AddP2pPolicyComponent,

View File

@ -44,7 +44,7 @@
</div>
<div>
<label>{{'REPLICATION.CREATION_TIME' | translate}} :</label>
<span>{{startTime() | date: 'short'}}</span>
<span>{{startTime() | harborDatetime: 'short'}}</span>
</div>
</div>
<div class="flex-block">
@ -124,7 +124,7 @@
<span>{{t.extra_attrs?.kind}}</span>
</clr-dg-cell>
<clr-dg-cell>{{t.start_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{t.start_time | harborDatetime: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{getDuration(t)}}</clr-dg-cell>
<clr-dg-cell>
<a target="_blank" [href]="viewLog(t.id)" *ngIf="t.status !== 'Initialized'">

View File

@ -1,11 +1,6 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { TranslateService } from '@ngx-translate/core';
import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ClarityModule } from '@clr/angular';
import { FormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { P2pProviderService } from '../p2p-provider.service';
import { PreheatService } from '../../../../../../ng-swagger-gen/services/preheat.service';
import { ActivatedRoute } from '@angular/router';
@ -18,6 +13,7 @@ import { MessageHandlerService } from '../../../../shared/services/message-handl
import { UserPermissionService } from '../../../../shared/services';
import { Task } from '../../../../../../ng-swagger-gen/models/task';
import { HttpHeaders, HttpResponse } from '@angular/common/http';
import { SharedTestingModule } from "../../../../shared/shared.module";
describe('TaskListComponent', () => {
let component: TaskListComponent;
let fixture: ComponentFixture<TaskListComponent>;
@ -93,13 +89,7 @@ describe('TaskListComponent', () => {
NO_ERRORS_SCHEMA
],
imports: [
BrowserAnimationsModule,
ClarityModule,
TranslateModule.forRoot(),
FormsModule,
RouterTestingModule,
NoopAnimationsModule,
HttpClientTestingModule
SharedTestingModule
],
declarations: [TaskListComponent],
providers: [

View File

@ -41,7 +41,7 @@
<clr-dg-cell>{{l.resource}}</clr-dg-cell>
<clr-dg-cell>{{l.resource_type}}</clr-dg-cell>
<clr-dg-cell>{{l.operation}}</clr-dg-cell>
<clr-dg-cell>{{l.op_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{l.op_time | harborDatetime: 'short'}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>

View File

@ -2,7 +2,7 @@
<clr-dg-column class="history-time">{{ 'TAG.CREATION' | translate }}</clr-dg-column>
<clr-dg-column>{{ 'TAG.COMMAND' | translate }}</clr-dg-column>
<clr-dg-row *clrDgItems="let h of historyList" [clrDgItem]='h' class="history-item">
<clr-dg-cell>{{ h.created | date: 'short' }}</clr-dg-cell>
<clr-dg-cell>{{ h.created | harborDatetime: 'short' }}</clr-dg-cell>
<clr-dg-cell>{{ h.created_by }}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>{{ historyList.length }} commands</clr-dg-footer>

View File

@ -1,14 +1,12 @@
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from "@angular/core";
import { ClarityModule } from "@clr/angular";
import { AdditionsService } from "../additions.service";
import { of } from "rxjs";
import { TranslateFakeLoader, TranslateLoader, TranslateModule } from "@ngx-translate/core";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { BuildHistoryComponent } from "./build-history.component";
import { ArtifactBuildHistory } from "../models";
import { AdditionLink } from "../../../../../../../../ng-swagger-gen/models/addition-link";
import { ErrorHandler } from "../../../../../../shared/units/error-handler";
import { SharedTestingModule } from "../../../../../../shared/shared.module";
describe('BuildHistoryComponent', () => {
let component: BuildHistoryComponent;
@ -36,14 +34,7 @@ describe('BuildHistoryComponent', () => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
BrowserAnimationsModule,
ClarityModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateFakeLoader,
}
})
SharedTestingModule
],
declarations: [BuildHistoryComponent],
providers: [

View File

@ -235,8 +235,8 @@
</a>
</div>
</td>
<td class="left tag-body-color">{{tag.pull_time === availableTime ? '':(tag.pull_time | date: 'short')}}</td>
<td class="left tag-body-color">{{tag.push_time | date: 'short'}}</td>
<td class="left tag-body-color">{{tag.pull_time === availableTime ? '':(tag.pull_time | harborDatetime: 'short')}}</td>
<td class="left tag-body-color">{{tag.push_time | harborDatetime: 'short'}}</td>
</tr>
<tr *ngIf="artifact?.tagNumber > 8">...</tr>
</tbody>
@ -304,11 +304,11 @@
</div>
</clr-dg-cell>
<clr-dg-cell>
<div class="cell">{{artifact.push_time | date: 'short'}}</div>
<div class="cell">{{artifact.push_time | harborDatetime: 'short'}}</div>
</clr-dg-cell>
<clr-dg-cell>
<div class="cell">
{{artifact.pull_time === availableTime ? "" : (artifact.pull_time| date: 'short')}}</div>
{{artifact.pull_time === availableTime ? "" : (artifact.pull_time| harborDatetime: 'short')}}</div>
</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>

View File

@ -66,8 +66,8 @@
</a>
</div>
</clr-dg-cell>
<clr-dg-cell>{{tag.pull_time !== availableTime? (tag.pull_time | date: 'short') : ""}}</clr-dg-cell>
<clr-dg-cell>{{tag.push_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{tag.pull_time !== availableTime? (tag.pull_time | harborDatetime: 'short') : ""}}</clr-dg-cell>
<clr-dg-cell>{{tag.push_time | harborDatetime: 'short'}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>

View File

@ -70,7 +70,7 @@
</div>
<div>
<span class="bar-scanning-time">{{'VULNERABILITY.CHART.SCANNING_TIME' | translate}} </span>
<span>{{completeTimestamp | date:'short'}}</span>
<span>{{completeTimestamp | harborDatetime:'short'}}</span>
</div>
</clr-tooltip-content>
</clr-tooltip>

View File

@ -58,7 +58,7 @@
</div>
<div>
<span class="bar-scanning-time">{{'VULNERABILITY.CHART.SCANNING_TIME' | translate}} </span>
<span>{{completeTimestamp | date:'MM/dd/y HH:mm:ss'}}</span>
<span>{{completeTimestamp | harborDatetime:'MM/dd/y HH:mm:ss'}}</span>
</div>
</clr-tooltip-content>
</clr-tooltip>

View File

@ -37,7 +37,7 @@
<!-- to do -->
<clr-dg-cell>{{r.artifact_count}}</clr-dg-cell>
<clr-dg-cell>{{r.pull_count}}</clr-dg-cell>
<clr-dg-cell>{{r.update_time | date:'short'}}</clr-dg-cell>
<clr-dg-cell>{{r.update_time | harborDatetime:'short'}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<clr-dg-pagination #pagination [(clrDgPage)]="currentPage" [clrDgPageSize]="pageSize" [clrDgTotalItems]="totalCount">
@ -84,7 +84,7 @@
</div>
<div class="form-group">
<label>{{'REPOSITORY.LAST_MODIFIED' | translate}}</label>
<div>{{item.update_time | date: 'short'}}</div>
<div>{{item.update_time | harborDatetime: 'short'}}</div>
</div>
</div>
<div class="card-footer">

View File

@ -68,7 +68,7 @@
<clr-control-helper *ngIf="isEditMode && systemRobot?.duration > 0 && !((expiration.dirty || expiration.touched) && expiration.invalid)|| isExpirationInvalid()">
<span [ngClass]="{showWarning: shouldShowWarning()}">
<clr-icon *ngIf="shouldShowWarning()" class="alert-icon" shape="exclamation-triangle"></clr-icon><span>{{'SYSTEM_ROBOT.EXPIRES_AT' | translate}}</span>:
<span>{{calculateExpiresAt() | date:'short'}}</span>
<span>{{calculateExpiresAt() | harborDatetime:'short'}}</span>
</span>
</clr-control-helper>
<clr-control-error *ngIf="((expiration.dirty || expiration.touched) && expiration.invalid)|| isExpirationInvalid()">

View File

@ -88,8 +88,8 @@
</clr-dropdown>
</div>
</clr-dg-cell>
<clr-dg-cell>{{r.creation_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{r.expires_at === -1?("ROBOT_ACCOUNT.NEVER_EXPIRED" | translate):(r.expires_at * 1000 | date: 'short')}}</clr-dg-cell>
<clr-dg-cell>{{r.creation_time | harborDatetime: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{r.expires_at === -1?("ROBOT_ACCOUNT.NEVER_EXPIRED" | translate):(r.expires_at * 1000 | harborDatetime: 'short')}}</clr-dg-cell>
<clr-dg-cell>{{r.description}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>

View File

@ -121,7 +121,7 @@
<clr-dg-cell class="hand"
(click)="openDetail(i,execution.id)">{{execution.trigger}}</clr-dg-cell>
<clr-dg-cell class="hand"
(click)="openDetail(i,execution.id)">{{execution.start_time|date:'medium'}}</clr-dg-cell>
(click)="openDetail(i,execution.id)">{{execution.start_time| harborDatetime:'medium'}}</clr-dg-cell>
<clr-dg-cell class="hand" (click)="openDetail(i,execution.id)">{{execution.duration}}</clr-dg-cell>
<clr-dg-row-detail *ngIf="index===i">
<clr-datagrid (clrDgRefresh)="loadLog()" [clrDgLoading]="loadingHistories" class="w-100">
@ -138,7 +138,7 @@
<clr-dg-cell>{{task.repository}}</clr-dg-cell>
<clr-dg-cell>{{task.status}}</clr-dg-cell>
<clr-dg-cell>{{task?.retained?task?.retained:0}}/{{task?.total?task?.total:0}}</clr-dg-cell>
<clr-dg-cell>{{task.start_time|date:'medium'}}</clr-dg-cell>
<clr-dg-cell>{{task.start_time| harborDatetime:'medium'}}</clr-dg-cell>
<clr-dg-cell>{{task.duration}}</clr-dg-cell>
<clr-dg-cell><span (click)="seeLog(task.execution_id,task.id)"
class="hand color-79b">{{'TAG_RETENTION.LOG' | translate}}</span>

View File

@ -15,7 +15,7 @@
<span>{{'WEBHOOK.DISABLED' | translate}}</span>
</div>
</clr-dg-cell>
<clr-dg-cell>{{item.last_trigger_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{item.last_trigger_time | harborDatetime: 'short'}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-placeholder>
{{'WEBHOOK.NO_TRIGGER' | translate}}

View File

@ -94,7 +94,7 @@
</div>
</div>
</clr-dg-cell>
<clr-dg-cell>{{w.creation_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{w.creation_time | harborDatetime: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{w.description}}</clr-dg-cell>
<clr-dg-row-detail *clrIfExpanded>
<last-trigger class="w-100" [webhookName]="w.name" *clrIfExpanded [inputLastTriggers]="lastTriggers"></last-trigger>

View File

@ -27,7 +27,7 @@
<hbr-label-piece [label]="label"></hbr-label-piece>
</clr-dg-cell>
<clr-dg-cell>{{label.description}}</clr-dg-cell>
<clr-dg-cell>{{label.creation_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{label.creation_time | harborDatetime: 'short'}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<clr-dg-pagination #pagination [clrDgPageSize]="15">

View File

@ -12,7 +12,7 @@
<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-cell>{{ chart.Chart.created | harborDatetime}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<clr-dg-pagination #pagination [clrDgPageSize]="5" [clrDgTotalItems]="charts?.length">

View File

@ -7,7 +7,7 @@
<clr-dg-cell><a href="javascript:void(0)" (click)="goToLink(p.project_id)">{{p.name}}</a></clr-dg-cell>
<clr-dg-cell>{{ (p.metadata.public === 'true' ? 'PROJECT.PUBLIC' : 'PROJECT.PRIVATE') | translate}}</clr-dg-cell>
<clr-dg-cell>{{p.repo_count}}</clr-dg-cell>
<clr-dg-cell>{{p.creation_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{p.creation_time | harborDatetime: 'short'}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<span *ngIf="projects?.length">{{pagination.firstItem + 1}} - {{pagination.lastItem +1 }} {{'PROJECT.OF' | translate}} </span> {{projects?.length}} {{'PROJECT.ITEMS' | translate}}

View File

@ -0,0 +1,8 @@
import { HarborDatetimePipe } from './harbor-datetime.pipe';
describe('HarborDatetimePipe', () => {
it('create an instance', () => {
const pipe = new HarborDatetimePipe();
expect(pipe).toBeTruthy();
});
});

View File

@ -0,0 +1,19 @@
import { Pipe, PipeTransform } from '@angular/core';
import { DatePipe } from "@angular/common";
import { DEFAULT_LANG_LOCALSTORAGE_KEY, DeFaultLang } from "../entities/shared.const";
@Pipe({
name: 'harborDatetime',
pure: false
})
export class HarborDatetimePipe implements PipeTransform {
transform(value: any, format?: string): string {
let lang: string = DeFaultLang;
if (localStorage && localStorage.getItem(DEFAULT_LANG_LOCALSTORAGE_KEY)) {
lang = localStorage.getItem(DEFAULT_LANG_LOCALSTORAGE_KEY);
}
// default format medium
return new DatePipe(lang).transform(value, format ? format : 'medium');
}
}

View File

@ -70,6 +70,26 @@ import { MessageHandlerService } from "./services/message-handler.service";
import { HttpClientTestingModule } from "@angular/common/http/testing";
import { RouterTestingModule } from "@angular/router/testing";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { HarborDatetimePipe } from './pipes/harbor-datetime.pipe';
import { registerLocaleData } from "@angular/common";
import zh_cn from '@angular/common/locales/zh-Hans';
import zh_tw from '@angular/common/locales/zh-Hans-HK';
import es from '@angular/common/locales/es';
import localeFr from '@angular/common/locales/fr';
import localePt from '@angular/common/locales/pt-PT';
import localeTr from '@angular/common/locales/tr';
import localeDe from '@angular/common/locales/de';
// add locale data for supported languages ['en-us', 'zh-cn', 'zh-tw', 'es-es', 'fr-fr', 'pt-br', 'tr-tr', 'de-de'];
// en-us defaulted supported
registerLocaleData(zh_cn, 'zh-cn');
registerLocaleData(zh_tw, 'zh-tw');
registerLocaleData(es, 'es-es');
registerLocaleData(localeFr, 'fr-fr');
registerLocaleData(localePt, 'pt-br');
registerLocaleData(localeTr, 'tr-tr');
registerLocaleData(localeDe, 'de-de');
// ClarityIcons is publicly accessible from the browser's window object.
declare const ClarityIcons: ClarityIconsApi;
@ -134,7 +154,8 @@ ClarityIcons.add({"robot-head": `
CronScheduleComponent,
ListChartVersionRoComponent,
DatePickerComponent,
ImageNameInputComponent
ImageNameInputComponent,
HarborDatetimePipe
],
exports: [
TranslateModule,
@ -171,7 +192,8 @@ ClarityIcons.add({"robot-head": `
CronScheduleComponent,
ListChartVersionRoComponent,
DatePickerComponent,
ImageNameInputComponent
ImageNameInputComponent,
HarborDatetimePipe
],
providers: [
{provide: EndpointService, useClass: EndpointDefaultService },

View File

@ -1,3 +1,7 @@
/***************************************************************************************************
* Load `$localize` onto the global scope - used if i18n tags appear in Angular templates.
*/
import '@angular/localize/init';
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");