Translate of HR Information is implemented
This commit is contained in:
parent
4e2f19b91e
commit
9441a1304c
|
@ -8,7 +8,10 @@ import {
|
||||||
|
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
|
|
||||||
import { DialogService } from '@ucap-webmessenger/ui';
|
import {
|
||||||
|
DialogService,
|
||||||
|
TranslateService as UCapTranslateService
|
||||||
|
} from '@ucap-webmessenger/ui';
|
||||||
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
||||||
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
|
@ -44,6 +47,7 @@ export class MessengerSettingsDialogComponent implements OnInit {
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private sessionStorageService: SessionStorageService,
|
private sessionStorageService: SessionStorageService,
|
||||||
private localStorageService: LocalStorageService,
|
private localStorageService: LocalStorageService,
|
||||||
|
private ucapTranslateService: UCapTranslateService,
|
||||||
private store: Store<any>,
|
private store: Store<any>,
|
||||||
@Inject(DOCUMENT) private document: Document,
|
@Inject(DOCUMENT) private document: Document,
|
||||||
private renderer2: Renderer2
|
private renderer2: Renderer2
|
||||||
|
@ -71,6 +75,13 @@ export class MessengerSettingsDialogComponent implements OnInit {
|
||||||
setting.appTheme
|
setting.appTheme
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (this.appUserInfo.settings.general.locale !== setting.locale) {
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
this.appUserInfo.settings.general.hrInfoLocale !== setting.hrInfoLocale
|
||||||
|
) {
|
||||||
|
this.ucapTranslateService.use(setting.hrInfoLocale);
|
||||||
|
}
|
||||||
this.applySettings({ ...this.appUserInfo.settings, general: setting });
|
this.applySettings({ ...this.appUserInfo.settings, general: setting });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@ import { NGXLogger } from 'ngx-logger';
|
||||||
import { QueryProtocolService } from '@ucap-webmessenger/protocol-query';
|
import { QueryProtocolService } from '@ucap-webmessenger/protocol-query';
|
||||||
import { OptionProtocolService } from '@ucap-webmessenger/protocol-option';
|
import { OptionProtocolService } from '@ucap-webmessenger/protocol-option';
|
||||||
|
|
||||||
|
import { TranslateService as UCapTranslateService } from '@ucap-webmessenger/ui';
|
||||||
|
|
||||||
import * as AppStore from '@app/store';
|
import * as AppStore from '@app/store';
|
||||||
import * as CompanyStore from '@app/store/setting/company';
|
import * as CompanyStore from '@app/store/setting/company';
|
||||||
import * as VersionInfoStore from '@app/store/setting/version-info';
|
import * as VersionInfoStore from '@app/store/setting/version-info';
|
||||||
|
|
|
@ -6,6 +6,8 @@ import { EnvironmentsInfo, KEY_ENVIRONMENTS_INFO } from '@app/types';
|
||||||
import { AppNotificationService } from './notification.service';
|
import { AppNotificationService } from './notification.service';
|
||||||
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
|
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
|
||||||
import { AppNativeService } from './native.service';
|
import { AppNativeService } from './native.service';
|
||||||
|
import { TranslateService as UCapTranslateService } from '@ucap-webmessenger/ui';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AppService {
|
export class AppService {
|
||||||
|
@ -14,8 +16,16 @@ export class AppService {
|
||||||
private sessionStorageService: SessionStorageService,
|
private sessionStorageService: SessionStorageService,
|
||||||
private appNotificationService: AppNotificationService,
|
private appNotificationService: AppNotificationService,
|
||||||
private appNativeService: AppNativeService,
|
private appNativeService: AppNativeService,
|
||||||
|
// private translateService: TranslateService,
|
||||||
|
private ucapTranslateService: UCapTranslateService,
|
||||||
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService
|
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService
|
||||||
) {}
|
) {
|
||||||
|
// this.translateService.setDefaultLang('ko');
|
||||||
|
// this.translateService.use('ko');
|
||||||
|
|
||||||
|
this.ucapTranslateService.setDefaultLang('ko');
|
||||||
|
this.ucapTranslateService.use('ko');
|
||||||
|
}
|
||||||
|
|
||||||
public postInit(): Promise<any> {
|
public postInit(): Promise<any> {
|
||||||
const initPromise = new Promise<void>((resolve, reject) => {
|
const initPromise = new Promise<void>((resolve, reject) => {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {
|
||||||
KEY_URL_INFO
|
KEY_URL_INFO
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { PasswordUtil } from '@ucap-webmessenger/pi';
|
import { PasswordUtil } from '@ucap-webmessenger/pi';
|
||||||
|
|
||||||
import { DaesangCipherService } from '@ucap-webmessenger/daesang';
|
import { DaesangCipherService } from '@ucap-webmessenger/daesang';
|
||||||
|
|
||||||
import { environment } from '../../environments/environment';
|
import { environment } from '../../environments/environment';
|
||||||
|
|
|
@ -1,6 +1,38 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Actions, createEffect, ofType } from '@ngrx/effects';
|
||||||
|
|
||||||
|
import { TranslateService as UCapTranslateService } from '@ucap-webmessenger/ui';
|
||||||
|
import { map, tap } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import * as AuthenticationStore from '@app/store/account/authentication';
|
||||||
|
import { LocalStorageService } from '@ucap-webmessenger/web-storage';
|
||||||
|
import { AppUserInfo, KEY_APP_USER_INFO } from '@app/types/app-user-info.type';
|
||||||
|
|
||||||
|
import { environment } from '../../../../environments/environment';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class Effects {
|
export class Effects {
|
||||||
constructor() {}
|
postLogin$ = createEffect(
|
||||||
|
() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(AuthenticationStore.postLogin),
|
||||||
|
map(action => action.loginRes),
|
||||||
|
tap(async loginRes => {
|
||||||
|
const appUserInfo = this.localStorageService.encGet<AppUserInfo>(
|
||||||
|
KEY_APP_USER_INFO,
|
||||||
|
environment.customConfig.appKey
|
||||||
|
);
|
||||||
|
|
||||||
|
this.ucapTranslateService.use(
|
||||||
|
appUserInfo.settings.general.hrInfoLocale
|
||||||
|
);
|
||||||
|
})
|
||||||
|
),
|
||||||
|
{ dispatch: false }
|
||||||
|
);
|
||||||
|
constructor(
|
||||||
|
private actions$: Actions,
|
||||||
|
private ucapTranslateService: UCapTranslateService,
|
||||||
|
private localStorageService: LocalStorageService
|
||||||
|
) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ export const environment: Environment = {
|
||||||
autoStart: true,
|
autoStart: true,
|
||||||
continueRunWhenClose: true,
|
continueRunWhenClose: true,
|
||||||
locale: 'ko',
|
locale: 'ko',
|
||||||
|
hrInfoLocale: 'ko',
|
||||||
startBackgroudMode: false,
|
startBackgroudMode: false,
|
||||||
timezone: '+9'
|
timezone: '+9'
|
||||||
},
|
},
|
||||||
|
|
|
@ -43,6 +43,7 @@ export const environment: Environment = {
|
||||||
autoStart: true,
|
autoStart: true,
|
||||||
continueRunWhenClose: true,
|
continueRunWhenClose: true,
|
||||||
locale: 'ko',
|
locale: 'ko',
|
||||||
|
hrInfoLocale: 'ko',
|
||||||
startBackgroudMode: false,
|
startBackgroudMode: false,
|
||||||
timezone: '+9'
|
timezone: '+9'
|
||||||
},
|
},
|
||||||
|
|
|
@ -43,6 +43,7 @@ export const environment: Environment = {
|
||||||
autoStart: true,
|
autoStart: true,
|
||||||
continueRunWhenClose: true,
|
continueRunWhenClose: true,
|
||||||
locale: 'ko',
|
locale: 'ko',
|
||||||
|
hrInfoLocale: 'ko',
|
||||||
startBackgroudMode: false,
|
startBackgroudMode: false,
|
||||||
timezone: '+9'
|
timezone: '+9'
|
||||||
},
|
},
|
||||||
|
|
|
@ -43,6 +43,7 @@ export const environment: Environment = {
|
||||||
autoStart: true,
|
autoStart: true,
|
||||||
continueRunWhenClose: true,
|
continueRunWhenClose: true,
|
||||||
locale: 'ko',
|
locale: 'ko',
|
||||||
|
hrInfoLocale: 'ko',
|
||||||
startBackgroudMode: false,
|
startBackgroudMode: false,
|
||||||
timezone: '+9'
|
timezone: '+9'
|
||||||
},
|
},
|
||||||
|
|
|
@ -39,7 +39,9 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<li (click)="onClickNode(node)" matRipple>
|
<li (click)="onClickNode(node)" matRipple>
|
||||||
<div class="tree-node-body">{{ node.name }}</div>
|
<div class="tree-node-body">
|
||||||
|
{{ node.deptInfo | ucapTranslate: 'name' }}
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</mat-tree-node>
|
</mat-tree-node>
|
||||||
<!-- This is the tree node template for expandable nodes -->
|
<!-- This is the tree node template for expandable nodes -->
|
||||||
|
@ -83,7 +85,9 @@
|
||||||
{{ treeControl.isExpanded(node) ? 'remove' : 'add' }}
|
{{ treeControl.isExpanded(node) ? 'remove' : 'add' }}
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<span class="dept-name">{{ node.name }}</span>
|
<span class="dept-name">{{
|
||||||
|
node.deptInfo | ucapTranslate: 'name'
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- <ul class="tree-node-closer"></ul> -->
|
<!-- <ul class="tree-node-closer"></ul> -->
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,164 +0,0 @@
|
||||||
import {
|
|
||||||
ChangeDetectorRef,
|
|
||||||
Injectable,
|
|
||||||
OnDestroy,
|
|
||||||
Pipe,
|
|
||||||
PipeTransform
|
|
||||||
} from '@angular/core';
|
|
||||||
import {
|
|
||||||
LangChangeEvent,
|
|
||||||
TranslateService,
|
|
||||||
TranslationChangeEvent
|
|
||||||
} from '@ngx-translate/core';
|
|
||||||
import { ObjectUtil } from '@ucap-webmessenger/core';
|
|
||||||
import { Subscription } from 'rxjs';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
@Pipe({
|
|
||||||
name: 'ucap-organization-translate',
|
|
||||||
pure: false // required to update the value when the promise is resolved
|
|
||||||
})
|
|
||||||
export class TranslatePipe implements PipeTransform, OnDestroy {
|
|
||||||
value = '';
|
|
||||||
lastKey: string;
|
|
||||||
lastParams: any[];
|
|
||||||
onTranslationChange: Subscription;
|
|
||||||
onLangChange: Subscription;
|
|
||||||
onDefaultLangChange: Subscription;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private translate: TranslateService,
|
|
||||||
private changeDetectorRef: ChangeDetectorRef
|
|
||||||
) {}
|
|
||||||
|
|
||||||
updateValue(
|
|
||||||
key: string,
|
|
||||||
interpolateParams?: object,
|
|
||||||
translations?: any
|
|
||||||
): void {
|
|
||||||
const onTranslation = (res: string) => {
|
|
||||||
this.value = res !== undefined ? res : key;
|
|
||||||
this.lastKey = key;
|
|
||||||
this.changeDetectorRef.markForCheck();
|
|
||||||
};
|
|
||||||
if (translations) {
|
|
||||||
const res = this.translate.getParsedResult(
|
|
||||||
translations,
|
|
||||||
key,
|
|
||||||
interpolateParams
|
|
||||||
);
|
|
||||||
if (typeof res.subscribe === 'function') {
|
|
||||||
res.subscribe(onTranslation);
|
|
||||||
} else {
|
|
||||||
onTranslation(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.translate.get(key, interpolateParams).subscribe(onTranslation);
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(query: string, ...args: any[]): any {
|
|
||||||
if (!query || query.length === 0) {
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we ask another time for the same key, return the last value
|
|
||||||
if (
|
|
||||||
ObjectUtil.equals(query, this.lastKey) &&
|
|
||||||
ObjectUtil.equals(args, this.lastParams)
|
|
||||||
) {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
let interpolateParams: object;
|
|
||||||
if (!!args[0] && args.length) {
|
|
||||||
if (typeof args[0] === 'string' && args[0].length) {
|
|
||||||
// we accept objects written in the template such as {n:1}, {'n':1}, {n:'v'}
|
|
||||||
// which is why we might need to change it to real JSON objects such as {"n":1} or {"n":"v"}
|
|
||||||
const validArgs: string = args[0]
|
|
||||||
.replace(/(\')?([a-zA-Z0-9_]+)(\')?(\s)?:/g, '"$2":')
|
|
||||||
.replace(/:(\s)?(\')(.*?)(\')/g, ':"$3"');
|
|
||||||
try {
|
|
||||||
interpolateParams = JSON.parse(validArgs);
|
|
||||||
} catch (e) {
|
|
||||||
throw new SyntaxError(
|
|
||||||
`Wrong parameter in TranslatePipe. Expected a valid Object, received: ${args[0]}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if (typeof args[0] === 'object' && !Array.isArray(args[0])) {
|
|
||||||
interpolateParams = args[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// store the query, in case it changes
|
|
||||||
this.lastKey = query;
|
|
||||||
|
|
||||||
// store the params, in case they change
|
|
||||||
this.lastParams = args;
|
|
||||||
|
|
||||||
// set the value
|
|
||||||
this.updateValue(query, interpolateParams);
|
|
||||||
|
|
||||||
// if there is a subscription to onLangChange, clean it
|
|
||||||
this._dispose();
|
|
||||||
|
|
||||||
// subscribe to onTranslationChange event, in case the translations change
|
|
||||||
if (!this.onTranslationChange) {
|
|
||||||
this.onTranslationChange = this.translate.onTranslationChange.subscribe(
|
|
||||||
(event: TranslationChangeEvent) => {
|
|
||||||
if (this.lastKey && event.lang === this.translate.currentLang) {
|
|
||||||
this.lastKey = null;
|
|
||||||
this.updateValue(query, interpolateParams, event.translations);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// subscribe to onLangChange event, in case the language changes
|
|
||||||
if (!this.onLangChange) {
|
|
||||||
this.onLangChange = this.translate.onLangChange.subscribe(
|
|
||||||
(event: LangChangeEvent) => {
|
|
||||||
if (this.lastKey) {
|
|
||||||
this.lastKey = null; // we want to make sure it doesn't return the same value until it's been updated
|
|
||||||
this.updateValue(query, interpolateParams, event.translations);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// subscribe to onDefaultLangChange event, in case the default language changes
|
|
||||||
if (!this.onDefaultLangChange) {
|
|
||||||
this.onDefaultLangChange = this.translate.onDefaultLangChange.subscribe(
|
|
||||||
() => {
|
|
||||||
if (this.lastKey) {
|
|
||||||
this.lastKey = null; // we want to make sure it doesn't return the same value until it's been updated
|
|
||||||
this.updateValue(query, interpolateParams);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clean any existing subscription to change events
|
|
||||||
*/
|
|
||||||
private _dispose(): void {
|
|
||||||
if (typeof this.onTranslationChange !== 'undefined') {
|
|
||||||
this.onTranslationChange.unsubscribe();
|
|
||||||
this.onTranslationChange = undefined;
|
|
||||||
}
|
|
||||||
if (typeof this.onLangChange !== 'undefined') {
|
|
||||||
this.onLangChange.unsubscribe();
|
|
||||||
this.onLangChange = undefined;
|
|
||||||
}
|
|
||||||
if (typeof this.onDefaultLangChange !== 'undefined') {
|
|
||||||
this.onDefaultLangChange.unsubscribe();
|
|
||||||
this.onDefaultLangChange = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
|
||||||
this._dispose();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,6 +16,8 @@ import { MatTreeModule } from '@angular/material/tree';
|
||||||
|
|
||||||
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
|
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
|
||||||
|
|
||||||
|
import { UCapUiModule } from '@ucap-webmessenger/ui';
|
||||||
|
|
||||||
import { TenantSearchComponent } from './components/tenant-search.component';
|
import { TenantSearchComponent } from './components/tenant-search.component';
|
||||||
import { TreeComponent } from './components/tree.component';
|
import { TreeComponent } from './components/tree.component';
|
||||||
|
|
||||||
|
@ -37,7 +39,9 @@ const SERVICES = [];
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
MatTreeModule,
|
MatTreeModule,
|
||||||
|
|
||||||
PerfectScrollbarModule
|
PerfectScrollbarModule,
|
||||||
|
|
||||||
|
UCapUiModule
|
||||||
],
|
],
|
||||||
exports: [...COMPONENTS],
|
exports: [...COMPONENTS],
|
||||||
declarations: [...COMPONENTS]
|
declarations: [...COMPONENTS]
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
<mat-card class="example-card mat-elevation-z">
|
<mat-card class="example-card mat-elevation-z">
|
||||||
<mat-card-header>
|
<mat-card-header>
|
||||||
<mat-card-title>
|
<mat-card-title>
|
||||||
<span>{{ userInfo.name }}</span>
|
<span>{{ userInfo | ucapTranslate: 'name' }}</span>
|
||||||
<span>{{ userInfo.grade }}</span>
|
<span>{{ userInfo | ucapTranslate: 'grade' }}</span>
|
||||||
</mat-card-title>
|
</mat-card-title>
|
||||||
<mat-card-subtitle>{{ userInfo.deptName }}</mat-card-subtitle>
|
<mat-card-subtitle>{{
|
||||||
|
userInfo | ucapTranslate: 'deptName'
|
||||||
|
}}</mat-card-subtitle>
|
||||||
</mat-card-header>
|
</mat-card-header>
|
||||||
|
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
<dd class="info">
|
<dd class="info">
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
<span class="name">
|
<span class="name">
|
||||||
<b>{{ userInfo.name }}</b>
|
<b>{{ userInfo | ucapTranslate: 'name' }}</b>
|
||||||
{{ userInfo.grade }}
|
{{ userInfo | ucapTranslate: 'grade' }}
|
||||||
</span>
|
</span>
|
||||||
<span class="dept">
|
<span class="dept">
|
||||||
{{ userInfo.deptName }}
|
{{ userInfo | ucapTranslate: 'deptName' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- 상태메시지 제외
|
<!-- 상태메시지 제외
|
||||||
|
|
|
@ -24,7 +24,25 @@
|
||||||
<dd class="info">
|
<dd class="info">
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
<div class="room-name">
|
<div class="room-name">
|
||||||
<div class="name">{{ getRoomName(roomInfo) }}</div>
|
<div class="name">
|
||||||
|
<ng-template
|
||||||
|
[ngIf]="!!roomInfo.roomName && '' !== roomInfo.roomName.trim()"
|
||||||
|
[ngIfElse]="roomNameNotExist"
|
||||||
|
>
|
||||||
|
{{ roomInfo.roomName }}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template #roomNameNotExist>
|
||||||
|
<ng-template
|
||||||
|
[ngIf]="RoomType.Mytalk === roomInfo.roomType"
|
||||||
|
[ngIfElse]="roomNameByUserNames"
|
||||||
|
>Second</ng-template
|
||||||
|
>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template #roomNameByUserNames>
|
||||||
|
{{ _roomUserInfos | ucapTranslate: 'name':',' }}
|
||||||
|
</ng-template>
|
||||||
|
<!-- {{ getRoomName(roomInfo) }} -->
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="num bg-accent-light"
|
class="num bg-accent-light"
|
||||||
*ngIf="roomInfo.roomType === RoomType.Multi"
|
*ngIf="roomInfo.roomType === RoomType.Multi"
|
||||||
|
|
|
@ -114,6 +114,14 @@ export class ListItemComponent implements OnInit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get _roomUserInfos() {
|
||||||
|
return this.roomUserInfo.filter(roomUserInfo => {
|
||||||
|
return (
|
||||||
|
this.loginRes.userSeq !== roomUserInfo.seq && !!roomUserInfo.isJoinRoom
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// getChecked(value: boolean, roomInfo: RoomInfo) {
|
// getChecked(value: boolean, roomInfo: RoomInfo) {
|
||||||
// if (value && !this.multiCheckable) {
|
// if (value && !this.multiCheckable) {
|
||||||
// if (this.selected === roomInfo.roomSeq) {
|
// if (this.selected === roomInfo.roomSeq) {
|
||||||
|
|
|
@ -92,6 +92,25 @@
|
||||||
|
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
|
|
||||||
|
<h1 mat-subheader>인사 정보 언어</h1>
|
||||||
|
<mat-list-item>
|
||||||
|
<mat-form-field fxFlexFill>
|
||||||
|
<mat-select
|
||||||
|
[value]="setting.hrInfoLocale"
|
||||||
|
(selectionChange)="onSelectionChangeHrInfoLocale($event)"
|
||||||
|
>
|
||||||
|
<mat-option value="ko">
|
||||||
|
한국어 (대한민국)
|
||||||
|
</mat-option>
|
||||||
|
<mat-option value="en">
|
||||||
|
영어 (미국)
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</mat-list-item>
|
||||||
|
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
|
||||||
<h1 mat-subheader>시간대</h1>
|
<h1 mat-subheader>시간대</h1>
|
||||||
<mat-list-item>
|
<mat-list-item>
|
||||||
<mat-form-field fxFlexFill>
|
<mat-form-field fxFlexFill>
|
||||||
|
|
|
@ -81,6 +81,10 @@ export class GeneralComponent implements OnInit {
|
||||||
this.emit({ ...this.setting, locale: event.value });
|
this.emit({ ...this.setting, locale: event.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSelectionChangeHrInfoLocale(event: MatSelectChange) {
|
||||||
|
this.emit({ ...this.setting, hrInfoLocale: event.value });
|
||||||
|
}
|
||||||
|
|
||||||
onSelectionChangeTimezone(event: MatSelectChange) {
|
onSelectionChangeTimezone(event: MatSelectChange) {
|
||||||
this.emit({ ...this.setting, timezone: event.value });
|
this.emit({ ...this.setting, timezone: event.value });
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ export interface GeneralSetting {
|
||||||
continueRunWhenClose: boolean;
|
continueRunWhenClose: boolean;
|
||||||
autoLogin: boolean;
|
autoLogin: boolean;
|
||||||
locale: string;
|
locale: string;
|
||||||
|
hrInfoLocale: string;
|
||||||
timezone: string;
|
timezone: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
121
projects/ucap-webmessenger-ui/src/lib/pipes/translate.pipe.ts
Normal file
121
projects/ucap-webmessenger-ui/src/lib/pipes/translate.pipe.ts
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
import {
|
||||||
|
ChangeDetectorRef,
|
||||||
|
Injectable,
|
||||||
|
OnDestroy,
|
||||||
|
Pipe,
|
||||||
|
PipeTransform
|
||||||
|
} from '@angular/core';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
import { ObjectUtil } from '@ucap-webmessenger/core';
|
||||||
|
import {
|
||||||
|
TranslateService,
|
||||||
|
LangChangeEvent
|
||||||
|
} from '../services/translate.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
@Pipe({
|
||||||
|
name: 'ucapTranslate',
|
||||||
|
pure: false // required to update the value when the promise is resolved
|
||||||
|
})
|
||||||
|
export class TranslatePipe implements PipeTransform, OnDestroy {
|
||||||
|
value = '';
|
||||||
|
lastTarget: any;
|
||||||
|
lastKey: string;
|
||||||
|
lastSeparator: string;
|
||||||
|
onLangChange: Subscription;
|
||||||
|
onDefaultLangChange: Subscription;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private translateService: TranslateService,
|
||||||
|
private changeDetectorRef: ChangeDetectorRef
|
||||||
|
) {}
|
||||||
|
|
||||||
|
updateValue(target: any, key: string, separator?: string): void {
|
||||||
|
try {
|
||||||
|
const value = this.translateService.get(target, key, separator);
|
||||||
|
this.value = value;
|
||||||
|
} catch (error) {
|
||||||
|
this.value = key;
|
||||||
|
}
|
||||||
|
this.lastTarget = target;
|
||||||
|
this.lastKey = key;
|
||||||
|
this.changeDetectorRef.markForCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
transform(target: any, key: string, separator?: string): any {
|
||||||
|
if (
|
||||||
|
!target ||
|
||||||
|
0 === Object.keys(target).length ||
|
||||||
|
!key ||
|
||||||
|
0 === key.length
|
||||||
|
) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we ask another time for the same key, return the last value
|
||||||
|
if (
|
||||||
|
ObjectUtil.equals(target, this.lastTarget) &&
|
||||||
|
ObjectUtil.equals(key, this.lastKey) &&
|
||||||
|
ObjectUtil.equals(separator, this.lastSeparator)
|
||||||
|
) {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the target, in case it changes
|
||||||
|
this.lastTarget = target;
|
||||||
|
// store the key, in case it changes
|
||||||
|
this.lastKey = key;
|
||||||
|
// store the key, in case it changes
|
||||||
|
this.lastSeparator = separator;
|
||||||
|
|
||||||
|
// set the value
|
||||||
|
this.updateValue(target, key, separator);
|
||||||
|
|
||||||
|
// if there is a subscription to onLangChange, clean it
|
||||||
|
this._dispose();
|
||||||
|
|
||||||
|
// subscribe to onLangChange event, in case the language changes
|
||||||
|
if (!this.onLangChange) {
|
||||||
|
this.onLangChange = this.translateService.onLangChange.subscribe(
|
||||||
|
(event: LangChangeEvent) => {
|
||||||
|
if (this.lastKey) {
|
||||||
|
this.lastKey = null; // we want to make sure it doesn't return the same value until it's been updated
|
||||||
|
this.updateValue(target, key, separator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// subscribe to onDefaultLangChange event, in case the default language changes
|
||||||
|
if (!this.onDefaultLangChange) {
|
||||||
|
this.onDefaultLangChange = this.translateService.onDefaultLangChange.subscribe(
|
||||||
|
() => {
|
||||||
|
if (this.lastKey) {
|
||||||
|
this.lastKey = null; // we want to make sure it doesn't return the same value until it's been updated
|
||||||
|
this.updateValue(target, key, separator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean any existing subscription to change events
|
||||||
|
*/
|
||||||
|
private _dispose(): void {
|
||||||
|
if (typeof this.onLangChange !== 'undefined') {
|
||||||
|
this.onLangChange.unsubscribe();
|
||||||
|
this.onLangChange = undefined;
|
||||||
|
}
|
||||||
|
if (typeof this.onDefaultLangChange !== 'undefined') {
|
||||||
|
this.onDefaultLangChange.unsubscribe();
|
||||||
|
this.onDefaultLangChange = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this._dispose();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
import { Injectable, EventEmitter } from '@angular/core';
|
||||||
|
|
||||||
|
export interface LangChangeEvent {
|
||||||
|
lang: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DefaultLangChangeEvent {
|
||||||
|
lang: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class TranslateService {
|
||||||
|
// tslint:disable-next-line: variable-name
|
||||||
|
private _onLangChange: EventEmitter<LangChangeEvent> = new EventEmitter<
|
||||||
|
LangChangeEvent
|
||||||
|
>();
|
||||||
|
// tslint:disable-next-line: variable-name
|
||||||
|
private _onDefaultLangChange: EventEmitter<
|
||||||
|
DefaultLangChangeEvent
|
||||||
|
> = new EventEmitter<DefaultLangChangeEvent>();
|
||||||
|
// tslint:disable-next-line: variable-name
|
||||||
|
private _defaultLang: string;
|
||||||
|
// tslint:disable-next-line: variable-name
|
||||||
|
private _currentLang: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An EventEmitter to listen to lang change events
|
||||||
|
* onLangChange.subscribe((params: LangChangeEvent) => {
|
||||||
|
* // do something
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
get onLangChange(): EventEmitter<LangChangeEvent> {
|
||||||
|
return this._onLangChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An EventEmitter to listen to default lang change events
|
||||||
|
* onDefaultLangChange.subscribe((params: DefaultLangChangeEvent) => {
|
||||||
|
* // do something
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
get onDefaultLangChange() {
|
||||||
|
return this._onDefaultLangChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default lang to fallback when translations are missing on the current lang
|
||||||
|
*/
|
||||||
|
get defaultLang(): string {
|
||||||
|
return this._defaultLang;
|
||||||
|
}
|
||||||
|
|
||||||
|
set defaultLang(defaultLang: string) {
|
||||||
|
this._defaultLang = defaultLang;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The lang currently used
|
||||||
|
*/
|
||||||
|
get currentLang(): string {
|
||||||
|
return this._currentLang;
|
||||||
|
}
|
||||||
|
|
||||||
|
set currentLang(currentLang: string) {
|
||||||
|
this._currentLang = currentLang;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the default language to use as a fallback
|
||||||
|
*/
|
||||||
|
public setDefaultLang(lang: string): void {
|
||||||
|
if (lang === this.defaultLang) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.changeDefaultLang(lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default language used
|
||||||
|
*/
|
||||||
|
public getDefaultLang(): string {
|
||||||
|
return this.defaultLang;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the lang currently used
|
||||||
|
*/
|
||||||
|
public use(lang: string): void {
|
||||||
|
// don't change the language if the language given is already selected
|
||||||
|
if (lang === this.currentLang) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.changeLang(lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the translated value of a key (or an array of keys)
|
||||||
|
* @returns the translated key, or an object of translated keys
|
||||||
|
*/
|
||||||
|
public get(target: any, key: string, separator?: string): string {
|
||||||
|
if (!target || 0 === Object.keys(target).length) {
|
||||||
|
throw new Error(`Parameter "target" is not valid`);
|
||||||
|
}
|
||||||
|
if (!key || 0 === key.length) {
|
||||||
|
throw new Error(`Parameter "key" required`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target instanceof Array) {
|
||||||
|
const result: string[] = [];
|
||||||
|
target.forEach(t => {
|
||||||
|
result.push(this.get(t, key, separator));
|
||||||
|
});
|
||||||
|
return result.join(!!separator ? separator : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
const keys = Object.keys(target);
|
||||||
|
try {
|
||||||
|
const lang =
|
||||||
|
this.currentLang.charAt(0).toUpperCase() +
|
||||||
|
this.currentLang.substring(1);
|
||||||
|
const langKey = `${key}${lang}`;
|
||||||
|
|
||||||
|
if (-1 !== keys.indexOf(langKey)) {
|
||||||
|
return target[langKey];
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
|
||||||
|
if (-1 !== keys.indexOf(key)) {
|
||||||
|
return target[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`value is not exist`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the current lang
|
||||||
|
*/
|
||||||
|
private changeLang(lang: string): void {
|
||||||
|
this.currentLang = lang;
|
||||||
|
this.onLangChange.emit({ lang });
|
||||||
|
|
||||||
|
// if there is no default lang, use the one that we just set
|
||||||
|
if (!this.defaultLang) {
|
||||||
|
this.changeDefaultLang(lang);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the default lang
|
||||||
|
*/
|
||||||
|
private changeDefaultLang(lang: string): void {
|
||||||
|
this.defaultLang = lang;
|
||||||
|
this.onDefaultLangChange.emit({ lang });
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,6 +43,7 @@ import { ClipboardService } from './services/clipboard.service';
|
||||||
import { DialogService } from './services/dialog.service';
|
import { DialogService } from './services/dialog.service';
|
||||||
import { SnackBarService } from './services/snack-bar.service';
|
import { SnackBarService } from './services/snack-bar.service';
|
||||||
import { SplashScreenService } from './services/splash-screen.service';
|
import { SplashScreenService } from './services/splash-screen.service';
|
||||||
|
import { TranslateService } from './services/translate.service';
|
||||||
|
|
||||||
import { ClickOutsideDirective } from './directives/click-outside.directive';
|
import { ClickOutsideDirective } from './directives/click-outside.directive';
|
||||||
import { FileUploadForDirective } from './directives/file-upload-for.directive';
|
import { FileUploadForDirective } from './directives/file-upload-for.directive';
|
||||||
|
@ -61,6 +62,7 @@ import {
|
||||||
} from './pipes/dates.pipe';
|
} from './pipes/dates.pipe';
|
||||||
import { SecondsToMinutesPipe } from './pipes/seconds-to-minutes.pipe';
|
import { SecondsToMinutesPipe } from './pipes/seconds-to-minutes.pipe';
|
||||||
import { LinkyPipe } from './pipes/linky.pipe';
|
import { LinkyPipe } from './pipes/linky.pipe';
|
||||||
|
import { TranslatePipe } from './pipes/translate.pipe';
|
||||||
|
|
||||||
import { MatTabsModule } from '@angular/material';
|
import { MatTabsModule } from '@angular/material';
|
||||||
|
|
||||||
|
@ -96,14 +98,16 @@ const PIPES = [
|
||||||
DateToStringFormatPipe,
|
DateToStringFormatPipe,
|
||||||
DateDistanceToDatePipe,
|
DateDistanceToDatePipe,
|
||||||
SecondsToMinutesPipe,
|
SecondsToMinutesPipe,
|
||||||
LinkyPipe
|
LinkyPipe,
|
||||||
|
TranslatePipe
|
||||||
];
|
];
|
||||||
const SERVICES = [
|
const SERVICES = [
|
||||||
BottomSheetService,
|
BottomSheetService,
|
||||||
ClipboardService,
|
ClipboardService,
|
||||||
DialogService,
|
DialogService,
|
||||||
SnackBarService,
|
SnackBarService,
|
||||||
SplashScreenService
|
SplashScreenService,
|
||||||
|
TranslateService
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
@ -33,6 +33,7 @@ export * from './lib/services/clipboard.service';
|
||||||
export * from './lib/services/dialog.service';
|
export * from './lib/services/dialog.service';
|
||||||
export * from './lib/services/snack-bar.service';
|
export * from './lib/services/snack-bar.service';
|
||||||
export * from './lib/services/splash-screen.service';
|
export * from './lib/services/splash-screen.service';
|
||||||
|
export * from './lib/services/translate.service';
|
||||||
|
|
||||||
export * from './lib/types/file-viewer.type';
|
export * from './lib/types/file-viewer.type';
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user