mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-26 04:05:40 +01:00
Update datePicker component (#18070)
1.Fix date validator 2.Add i18n support Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
e995b59a94
commit
a86740e82a
@ -8,8 +8,11 @@ import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
|
|||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { throwError as observableThrowError } from 'rxjs/internal/observable/throwError';
|
import { throwError as observableThrowError } from 'rxjs/internal/observable/throwError';
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
import { SharedTestingModule } from '../../shared/shared.module';
|
|
||||||
import { UserPermissionService } from '../../shared/services';
|
import { UserPermissionService } from '../../shared/services';
|
||||||
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
|
import { ClarityModule } from '@clr/angular';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
describe('SignInComponent', () => {
|
describe('SignInComponent', () => {
|
||||||
let component: SignInComponent;
|
let component: SignInComponent;
|
||||||
@ -27,9 +30,15 @@ describe('SignInComponent', () => {
|
|||||||
};
|
};
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [SharedTestingModule],
|
imports: [
|
||||||
|
TranslateModule.forRoot(),
|
||||||
|
RouterTestingModule,
|
||||||
|
ClarityModule,
|
||||||
|
FormsModule,
|
||||||
|
],
|
||||||
declarations: [SignInComponent],
|
declarations: [SignInComponent],
|
||||||
providers: [
|
providers: [
|
||||||
|
TranslateService,
|
||||||
{
|
{
|
||||||
provide: UserPermissionService,
|
provide: UserPermissionService,
|
||||||
useValue: mockedUserPermissionService,
|
useValue: mockedUserPermissionService,
|
||||||
|
@ -4,6 +4,9 @@ import { ErrorHandler } from '../../../../shared/units/error-handler';
|
|||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { SharedTestingModule } from '../../../../shared/shared.module';
|
import { SharedTestingModule } from '../../../../shared/shared.module';
|
||||||
import { SecurityComponent } from './security.component';
|
import { SecurityComponent } from './security.component';
|
||||||
|
import { LOCALE_ID } from '@angular/core';
|
||||||
|
import { registerLocaleData } from '@angular/common';
|
||||||
|
import locale_en from '@angular/common/locales/en';
|
||||||
describe('SecurityComponent', () => {
|
describe('SecurityComponent', () => {
|
||||||
let component: SecurityComponent;
|
let component: SecurityComponent;
|
||||||
let fixture: ComponentFixture<SecurityComponent>;
|
let fixture: ComponentFixture<SecurityComponent>;
|
||||||
@ -26,7 +29,18 @@ describe('SecurityComponent', () => {
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
registerLocaleData(locale_en, 'en-us');
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
TestBed.overrideComponent(SecurityComponent, {
|
||||||
|
set: {
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: LOCALE_ID,
|
||||||
|
useValue: 'en-us',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [SharedTestingModule],
|
imports: [SharedTestingModule],
|
||||||
providers: [
|
providers: [
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
|
LOCALE_ID,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
@ -10,6 +11,7 @@ import { ErrorHandler } from '../../../../shared/units/error-handler';
|
|||||||
import {
|
import {
|
||||||
ConfirmationState,
|
ConfirmationState,
|
||||||
ConfirmationTargets,
|
ConfirmationTargets,
|
||||||
|
DEFAULT_LANG_LOCALSTORAGE_KEY,
|
||||||
} from '../../../../shared/entities/shared.const';
|
} from '../../../../shared/entities/shared.const';
|
||||||
import {
|
import {
|
||||||
SystemCVEAllowlist,
|
SystemCVEAllowlist,
|
||||||
@ -28,6 +30,12 @@ const TARGET_BLANK = '_blank';
|
|||||||
selector: 'app-security',
|
selector: 'app-security',
|
||||||
templateUrl: './security.component.html',
|
templateUrl: './security.component.html',
|
||||||
styleUrls: ['./security.component.scss'],
|
styleUrls: ['./security.component.scss'],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: LOCALE_ID,
|
||||||
|
useValue: localStorage.getItem(DEFAULT_LANG_LOCALSTORAGE_KEY),
|
||||||
|
},
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class SecurityComponent implements OnInit, OnDestroy {
|
export class SecurityComponent implements OnInit, OnDestroy {
|
||||||
onGoing = false;
|
onGoing = false;
|
||||||
|
@ -3,13 +3,16 @@ import { AuditLogComponent } from './audit-log.component';
|
|||||||
import { MessageHandlerService } from '../../../shared/services/message-handler.service';
|
import { MessageHandlerService } from '../../../shared/services/message-handler.service';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { CUSTOM_ELEMENTS_SCHEMA, DebugElement } from '@angular/core';
|
import { CUSTOM_ELEMENTS_SCHEMA, DebugElement, LOCALE_ID } from '@angular/core';
|
||||||
import { delay } from 'rxjs/operators';
|
import { delay } from 'rxjs/operators';
|
||||||
import { AuditLog } from '../../../../../ng-swagger-gen/models/audit-log';
|
import { AuditLog } from '../../../../../ng-swagger-gen/models/audit-log';
|
||||||
import { HttpHeaders, HttpResponse } from '@angular/common/http';
|
import { HttpHeaders, HttpResponse } from '@angular/common/http';
|
||||||
import { ProjectService } from '../../../../../ng-swagger-gen/services/project.service';
|
import { ProjectService } from '../../../../../ng-swagger-gen/services/project.service';
|
||||||
import { click } from '../../../shared/units/utils';
|
import { click } from '../../../shared/units/utils';
|
||||||
import { SharedTestingModule } from '../../../shared/shared.module';
|
import { SharedTestingModule } from '../../../shared/shared.module';
|
||||||
|
import { registerLocaleData } from '@angular/common';
|
||||||
|
import locale_en from '@angular/common/locales/en';
|
||||||
|
import { DatePickerComponent } from '../../../shared/components/datetime-picker/datetime-picker.component';
|
||||||
|
|
||||||
describe('AuditLogComponent', () => {
|
describe('AuditLogComponent', () => {
|
||||||
let component: AuditLogComponent;
|
let component: AuditLogComponent;
|
||||||
@ -78,8 +81,18 @@ describe('AuditLogComponent', () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
registerLocaleData(locale_en, 'en-us');
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
TestBed.overrideComponent(DatePickerComponent, {
|
||||||
|
set: {
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: LOCALE_ID,
|
||||||
|
useValue: 'en-us',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
imports: [SharedTestingModule],
|
imports: [SharedTestingModule],
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
// Copyright Project Harbor Authors
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
import { Directive, OnChanges, Input, SimpleChanges } from '@angular/core';
|
|
||||||
import {
|
|
||||||
NG_VALIDATORS,
|
|
||||||
Validator,
|
|
||||||
Validators,
|
|
||||||
ValidatorFn,
|
|
||||||
AbstractControl,
|
|
||||||
} from '@angular/forms';
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[dateValidator]',
|
|
||||||
providers: [
|
|
||||||
{
|
|
||||||
provide: NG_VALIDATORS,
|
|
||||||
useExisting: DateValidatorDirective,
|
|
||||||
multi: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
export class DateValidatorDirective implements Validator, OnChanges {
|
|
||||||
@Input() dateValidator: string;
|
|
||||||
private valFn = Validators.nullValidator;
|
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
|
||||||
const change = changes['dateValidator'];
|
|
||||||
if (change) {
|
|
||||||
this.valFn = dateValidator();
|
|
||||||
} else {
|
|
||||||
this.valFn = Validators.nullValidator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
validate(control: AbstractControl): { [key: string]: any } {
|
|
||||||
return this.valFn(control) || Validators.nullValidator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function dateValidator(): ValidatorFn {
|
|
||||||
return (control: AbstractControl): { [key: string]: any } => {
|
|
||||||
let controlValue = control.value;
|
|
||||||
let valid = true;
|
|
||||||
if (controlValue) {
|
|
||||||
const regYMD =
|
|
||||||
/^(19|20)\d\d([- /.])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/g;
|
|
||||||
const regDMY =
|
|
||||||
/^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/g;
|
|
||||||
const regMDY =
|
|
||||||
/^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$/g;
|
|
||||||
valid =
|
|
||||||
regYMD.test(controlValue) ||
|
|
||||||
regDMY.test(controlValue) ||
|
|
||||||
regMDY.test(controlValue);
|
|
||||||
}
|
|
||||||
return valid
|
|
||||||
? Validators.nullValidator
|
|
||||||
: { dateValidator: { value: controlValue } };
|
|
||||||
};
|
|
||||||
}
|
|
@ -12,4 +12,9 @@
|
|||||||
left: 75%;
|
left: 75%;
|
||||||
background-color: #c92100;
|
background-color: #c92100;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
>.tooltip-content::before {
|
||||||
|
border-left-color:#c92100;
|
||||||
|
border-top-color: #c92100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
import { LOCALE_ID, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { DatePickerComponent } from './datetime-picker.component';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||||
|
import { DateValidatorDirective } from '../../directives/date-validator.directive';
|
||||||
|
import { registerLocaleData } from '@angular/common';
|
||||||
|
import locale_en from '@angular/common/locales/en';
|
||||||
|
|
||||||
|
describe('DatePickerComponent', () => {
|
||||||
|
let component: DatePickerComponent;
|
||||||
|
let fixture: ComponentFixture<DatePickerComponent>;
|
||||||
|
registerLocaleData(locale_en, 'en-us');
|
||||||
|
beforeEach(async () => {
|
||||||
|
TestBed.overrideComponent(DatePickerComponent, {
|
||||||
|
set: {
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: LOCALE_ID,
|
||||||
|
useValue: 'en-us',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [FormsModule, TranslateModule.forRoot()],
|
||||||
|
declarations: [DatePickerComponent, DateValidatorDirective],
|
||||||
|
providers: [TranslateService],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
|
}).compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(DatePickerComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -5,13 +5,21 @@ import {
|
|||||||
EventEmitter,
|
EventEmitter,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
OnChanges,
|
OnChanges,
|
||||||
|
LOCALE_ID,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { NgModel } from '@angular/forms';
|
import { NgModel } from '@angular/forms';
|
||||||
|
import { DEFAULT_LANG_LOCALSTORAGE_KEY } from '../../entities/shared.const';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-datetime',
|
selector: 'hbr-datetime',
|
||||||
templateUrl: './datetime-picker.component.html',
|
templateUrl: './datetime-picker.component.html',
|
||||||
styleUrls: ['./datetime-picker.component.scss'],
|
styleUrls: ['./datetime-picker.component.scss'],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: LOCALE_ID,
|
||||||
|
useValue: localStorage.getItem(DEFAULT_LANG_LOCALSTORAGE_KEY),
|
||||||
|
},
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class DatePickerComponent implements OnChanges {
|
export class DatePickerComponent implements OnChanges {
|
||||||
@Input() dateInput: string;
|
@Input() dateInput: string;
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
clrDropdownItem
|
clrDropdownItem
|
||||||
(click)="switchLanguage(lang[0])"
|
(click)="switchLanguage(lang[0])"
|
||||||
[class.lang-selected]="matchLang(lang[0])"
|
[class.lang-selected]="matchLang(lang[0])"
|
||||||
>{{ lang[1] }}</a
|
>{{ lang[1][0] }}</a
|
||||||
>
|
>
|
||||||
</clr-dropdown-menu>
|
</clr-dropdown-menu>
|
||||||
</clr-dropdown>
|
</clr-dropdown>
|
||||||
|
@ -9,6 +9,9 @@ import { MessageHandlerService } from '../../services/message-handler.service';
|
|||||||
import { SearchTriggerService } from '../global-search/search-trigger.service';
|
import { SearchTriggerService } from '../global-search/search-trigger.service';
|
||||||
import { SkinableConfig } from '../../../services/skinable-config.service';
|
import { SkinableConfig } from '../../../services/skinable-config.service';
|
||||||
import { SharedTestingModule } from '../../shared.module';
|
import { SharedTestingModule } from '../../shared.module';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { DeFaultLang } from '../../entities/shared.const';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
|
||||||
describe('NavigatorComponent', () => {
|
describe('NavigatorComponent', () => {
|
||||||
let component: TestComponentWrapperComponent;
|
let component: TestComponentWrapperComponent;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
import { Component, Output, EventEmitter, OnInit } from '@angular/core';
|
import { Component, Output, EventEmitter, OnInit } from '@angular/core';
|
||||||
import { Router, NavigationExtras } from '@angular/router';
|
import { Router, NavigationExtras } from '@angular/router';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { PlatformLocation } from '@angular/common';
|
import { PlatformLocation, registerLocaleData } from '@angular/common';
|
||||||
import { ModalEvent } from '../../../base/modal-event';
|
import { ModalEvent } from '../../../base/modal-event';
|
||||||
import { modalEvents } from '../../../base/modal-events.const';
|
import { modalEvents } from '../../../base/modal-events.const';
|
||||||
import { SessionService } from '../../services/session.service';
|
import { SessionService } from '../../services/session.service';
|
||||||
@ -70,6 +70,12 @@ export class NavigatorComponent implements OnInit {
|
|||||||
// custom skin
|
// custom skin
|
||||||
this.customStyle = this.skinableConfig.getSkinConfig();
|
this.customStyle = this.skinableConfig.getSkinConfig();
|
||||||
this.selectedLang = this.translate.currentLang as SupportedLanguage;
|
this.selectedLang = this.translate.currentLang as SupportedLanguage;
|
||||||
|
if (this.selectedLang) {
|
||||||
|
registerLocaleData(
|
||||||
|
LANGUAGES[this.selectedLang][1],
|
||||||
|
this.selectedLang
|
||||||
|
);
|
||||||
|
}
|
||||||
this.selectedDatetimeRendering = getDatetimeRendering();
|
this.selectedDatetimeRendering = getDatetimeRendering();
|
||||||
if (this.appConfigService.isIntegrationMode()) {
|
if (this.appConfigService.isIntegrationMode()) {
|
||||||
this.appTitle = 'APP_TITLE.VIC';
|
this.appTitle = 'APP_TITLE.VIC';
|
||||||
@ -91,7 +97,7 @@ export class NavigatorComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get currentLang(): string {
|
public get currentLang(): string {
|
||||||
return LANGUAGES[this.selectedLang];
|
return LANGUAGES[this.selectedLang][0] as string;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get currentDatetimeRendering(): string {
|
public get currentDatetimeRendering(): string {
|
||||||
@ -180,6 +186,7 @@ export class NavigatorComponent implements OnInit {
|
|||||||
// Switch languages
|
// Switch languages
|
||||||
switchLanguage(lang: SupportedLanguage): void {
|
switchLanguage(lang: SupportedLanguage): void {
|
||||||
this.selectedLang = lang;
|
this.selectedLang = lang;
|
||||||
|
registerLocaleData(LANGUAGES[this.selectedLang][1], this.selectedLang);
|
||||||
localStorage.setItem(DEFAULT_LANG_LOCALSTORAGE_KEY, lang);
|
localStorage.setItem(DEFAULT_LANG_LOCALSTORAGE_KEY, lang);
|
||||||
// due to the bug(https://github.com/ngx-translate/core/issues/1258) of translate module
|
// due to the bug(https://github.com/ngx-translate/core/issues/1258) of translate module
|
||||||
// have to reload
|
// have to reload
|
||||||
|
@ -53,10 +53,15 @@ export function dateValidator(): ValidatorFn {
|
|||||||
let valid = true;
|
let valid = true;
|
||||||
if (controlValue) {
|
if (controlValue) {
|
||||||
const regYMD =
|
const regYMD =
|
||||||
/^(19|20)\d\d([- /.])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/g;
|
/^(19|20)\d\d([- /.])(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$/g;
|
||||||
const regDMY =
|
const regDMY =
|
||||||
/^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/g;
|
/^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/g;
|
||||||
valid = regYMD.test(controlValue) || regDMY.test(controlValue);
|
const regMDY =
|
||||||
|
/^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$/g;
|
||||||
|
valid =
|
||||||
|
regYMD.test(controlValue) ||
|
||||||
|
regDMY.test(controlValue) ||
|
||||||
|
regMDY.test(controlValue);
|
||||||
}
|
}
|
||||||
return valid ? null : { dateValidator: { value: controlValue } };
|
return valid ? null : { dateValidator: { value: controlValue } };
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,15 @@
|
|||||||
// 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 locale_en from '@angular/common/locales/en';
|
||||||
|
import locale_zh_CN from '@angular/common/locales/zh-Hans';
|
||||||
|
import locale_zh_TW from '@angular/common/locales/zh-Hans-HK';
|
||||||
|
import locale_es from '@angular/common/locales/es';
|
||||||
|
import locale_fr from '@angular/common/locales/fr';
|
||||||
|
import locale_pt from '@angular/common/locales/pt-PT';
|
||||||
|
import locale_tr from '@angular/common/locales/tr';
|
||||||
|
import locale_de from '@angular/common/locales/de';
|
||||||
|
|
||||||
export const enum AlertType {
|
export const enum AlertType {
|
||||||
DANGER,
|
DANGER,
|
||||||
WARNING,
|
WARNING,
|
||||||
@ -223,16 +232,16 @@ export const REFRESH_TIME_DIFFERENCE = 10000;
|
|||||||
//
|
//
|
||||||
|
|
||||||
export const DeFaultLang = 'en-us';
|
export const DeFaultLang = 'en-us';
|
||||||
export type SupportedLanguage = keyof typeof LANGUAGES;
|
export type SupportedLanguage = string;
|
||||||
export const LANGUAGES = {
|
export const LANGUAGES = {
|
||||||
'en-us': 'English',
|
'en-us': ['English', locale_en],
|
||||||
'zh-cn': '中文简体',
|
'zh-cn': ['中文简体', locale_zh_CN],
|
||||||
'zh-tw': '中文繁體',
|
'zh-tw': ['中文繁體', locale_zh_TW],
|
||||||
'es-es': 'Español',
|
'es-es': ['Español', locale_es],
|
||||||
'fr-fr': 'Français',
|
'fr-fr': ['Français', locale_fr],
|
||||||
'pt-br': 'Português do Brasil',
|
'pt-br': ['Português do Brasil', locale_pt],
|
||||||
'tr-tr': 'Türkçe',
|
'tr-tr': ['Türkçe', locale_tr],
|
||||||
'de-de': 'Deutsch',
|
'de-de': ['Deutsch', locale_de],
|
||||||
} as const;
|
} as const;
|
||||||
export const supportedLangs = Object.keys(LANGUAGES) as SupportedLanguage[];
|
export const supportedLangs = Object.keys(LANGUAGES) as SupportedLanguage[];
|
||||||
/**
|
/**
|
||||||
@ -240,7 +249,7 @@ export const supportedLangs = Object.keys(LANGUAGES) as SupportedLanguage[];
|
|||||||
*/
|
*/
|
||||||
export const DEFAULT_LANG_LOCALSTORAGE_KEY = 'harbor-lang';
|
export const DEFAULT_LANG_LOCALSTORAGE_KEY = 'harbor-lang';
|
||||||
|
|
||||||
export type DatetimeRendering = keyof typeof DATETIME_RENDERINGS;
|
export type DatetimeRendering = string;
|
||||||
export const DATETIME_RENDERINGS = {
|
export const DATETIME_RENDERINGS = {
|
||||||
'locale-default': 'TOP_NAV.DATETIME_RENDERING_DEFAULT',
|
'locale-default': 'TOP_NAV.DATETIME_RENDERING_DEFAULT',
|
||||||
'iso-8601': 'ISO 8601',
|
'iso-8601': 'ISO 8601',
|
||||||
|
@ -79,33 +79,8 @@ import { RouterTestingModule } from '@angular/router/testing';
|
|||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { HarborDatetimePipe } from './pipes/harbor-datetime.pipe';
|
import { HarborDatetimePipe } from './pipes/harbor-datetime.pipe';
|
||||||
import { RemainingTimeComponent } from './components/remaining-time/remaining-time.component';
|
import { RemainingTimeComponent } from './components/remaining-time/remaining-time.component';
|
||||||
|
|
||||||
import { registerLocaleData } from '@angular/common';
|
|
||||||
import locale_en from '@angular/common/locales/en';
|
|
||||||
import locale_zh_CN from '@angular/common/locales/zh-Hans';
|
|
||||||
import locale_zh_TW from '@angular/common/locales/zh-Hans-HK';
|
|
||||||
import locale_es from '@angular/common/locales/es';
|
|
||||||
import locale_fr from '@angular/common/locales/fr';
|
|
||||||
import locale_pt from '@angular/common/locales/pt-PT';
|
|
||||||
import locale_tr from '@angular/common/locales/tr';
|
|
||||||
import locale_de from '@angular/common/locales/de';
|
|
||||||
import { SupportedLanguage } from './entities/shared.const';
|
|
||||||
import { LabelSelectorComponent } from './components/label-selector/label-selector.component';
|
import { LabelSelectorComponent } from './components/label-selector/label-selector.component';
|
||||||
|
|
||||||
const localesForSupportedLangs: Record<SupportedLanguage, unknown[]> = {
|
|
||||||
'en-us': locale_en,
|
|
||||||
'zh-cn': locale_zh_CN,
|
|
||||||
'zh-tw': locale_zh_TW,
|
|
||||||
'es-es': locale_es,
|
|
||||||
'fr-fr': locale_fr,
|
|
||||||
'pt-br': locale_pt,
|
|
||||||
'tr-tr': locale_tr,
|
|
||||||
'de-de': locale_de,
|
|
||||||
};
|
|
||||||
for (const [lang, locale] of Object.entries(localesForSupportedLangs)) {
|
|
||||||
registerLocaleData(locale, lang);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClarityIcons is publicly accessible from the browser's window object.
|
// ClarityIcons is publicly accessible from the browser's window object.
|
||||||
declare const ClarityIcons: ClarityIconsApi;
|
declare const ClarityIcons: ClarityIconsApi;
|
||||||
|
|
||||||
|
@ -17,8 +17,6 @@ import {
|
|||||||
import { AbstractControl } from '@angular/forms';
|
import { AbstractControl } from '@angular/forms';
|
||||||
import { isValidCron } from 'cron-validator';
|
import { isValidCron } from 'cron-validator';
|
||||||
import { ClrDatagridStateInterface } from '@clr/angular';
|
import { ClrDatagridStateInterface } from '@clr/angular';
|
||||||
import { ScheduleListComponent } from '../../base/left-side-nav/job-service-dashboard/schedule-list/schedule-list.component';
|
|
||||||
import { PendingListComponent } from '../../base/left-side-nav/job-service-dashboard/pending-job-list/pending-job-list.component';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Api levels
|
* Api levels
|
||||||
|
Loading…
Reference in New Issue
Block a user