bug fixed

This commit is contained in:
richard-loafle 2020-04-01 17:31:04 +09:00
parent ee88f862a7
commit 66466e22b9
19 changed files with 968 additions and 899 deletions

View File

@ -60,6 +60,37 @@
}
]
},
"production-es5": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"es5BrowserSupport": true,
"outputPath": "dist/ucap-lg-web-es5",
"tsConfig": "tsconfig.app.es5.json",
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
},
"hmr": {
"fileReplacements": [
{
@ -67,6 +98,16 @@
"with": "src/environments/environment.hmr.ts"
}
]
},
"hmr-es5": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.hmr.ts"
}
],
"es5BrowserSupport": true,
"tsConfig": "tsconfig.app.es5.json"
}
}
},
@ -80,9 +121,16 @@
"production": {
"browserTarget": "ucap-lg-web:build:production"
},
"production-5": {
"browserTarget": "ucap-lg-web:build:production-es5"
},
"hmr": {
"hmr": true,
"browserTarget": "ucap-lg-web:build:hmr"
},
"hmr-es5": {
"hmr": true,
"browserTarget": "ucap-lg-web:build:hmr-es5"
}
}
},

1046
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,10 @@
"ng": "ng",
"start": "ng serve",
"start:hmr": "ng serve --configuration hmr",
"start:hmr-es5": "ng serve --configuration hmr-es5",
"build": "ng build",
"build:production": "ng build --prod",
"build:production-es5": "ng build --configuration production-es5",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
@ -28,16 +31,16 @@
"@ngrx/entity": "^9.0.0",
"@ngrx/router-store": "^9.0.0",
"@ngrx/store": "^9.0.0",
"@ucap/api": "~0.0.1",
"@ucap/api-common": "~0.0.2",
"@ucap/api-external": "~0.0.4",
"@ucap/api-message": "~0.0.2",
"@ucap/api-prompt": "~0.0.2",
"@ucap/api-public": "~0.0.2",
"@ucap/core": "~0.0.2",
"@ucap/logger": "~0.0.4",
"@ucap/native": "~0.0.2",
"@ucap/native-browser": "~0.0.2",
"@ucap/api": "~0.0.2",
"@ucap/api-common": "~0.0.3",
"@ucap/api-external": "~0.0.5",
"@ucap/api-message": "~0.0.3",
"@ucap/api-prompt": "~0.0.3",
"@ucap/api-public": "~0.0.3",
"@ucap/core": "~0.0.4",
"@ucap/logger": "~0.0.7",
"@ucap/native": "~0.0.6",
"@ucap/native-browser": "~0.0.5",
"@ucap/ng-api-common": "~0.0.1",
"@ucap/ng-api-external": "~0.0.1",
"@ucap/ng-api-message": "~0.0.1",
@ -45,7 +48,7 @@
"@ucap/ng-api-public": "~0.0.1",
"@ucap/ng-core": "~0.0.1",
"@ucap/ng-logger": "~0.0.1",
"@ucap/ng-i18n": "~0.0.5",
"@ucap/ng-i18n": "~0.0.6",
"@ucap/ng-native": "~0.0.1",
"@ucap/ng-native-browser": "~0.0.1",
"@ucap/ng-pi": "~0.0.1",
@ -71,28 +74,33 @@
"@ucap/ng-store-organization": "~0.0.3",
"@ucap/ng-web-storage": "~0.0.1",
"@ucap/ng-ui": "~0.0.3",
"@ucap/ng-ui-authentication": "~0.0.5",
"@ucap/ng-ui-authentication": "~0.0.8",
"@ucap/ng-ui-skin-default": "~0.0.1",
"@ucap/pi": "~0.0.2",
"@ucap/protocol": "~0.0.1",
"@ucap/protocol-authentication": "~0.0.1",
"@ucap/protocol-buddy": "~0.0.1",
"@ucap/protocol-event": "~0.0.1",
"@ucap/protocol-file": "~0.0.1",
"@ucap/protocol-group": "~0.0.1",
"@ucap/protocol-info": "~0.0.1",
"@ucap/protocol-inner": "~0.0.1",
"@ucap/protocol-option": "~0.0.3",
"@ucap/protocol-ping": "~0.0.1",
"@ucap/protocol-query": "~0.0.1",
"@ucap/protocol-room": "~0.0.1",
"@ucap/protocol-service": "~0.0.1",
"@ucap/protocol-status": "~0.0.1",
"@ucap/protocol-sync": "~0.0.1",
"@ucap/protocol-umg": "~0.0.1",
"@ucap/web-socket": "~0.0.1",
"@ucap/web-storage": "~0.0.1",
"@ucap/pi": "~0.0.4",
"@ucap/protocol": "~0.0.2",
"@ucap/protocol-authentication": "~0.0.2",
"@ucap/protocol-buddy": "~0.0.2",
"@ucap/protocol-event": "~0.0.2",
"@ucap/protocol-file": "~0.0.2",
"@ucap/protocol-group": "~0.0.2",
"@ucap/protocol-info": "~0.0.2",
"@ucap/protocol-inner": "~0.0.2",
"@ucap/protocol-option": "~0.0.4",
"@ucap/protocol-ping": "~0.0.2",
"@ucap/protocol-query": "~0.0.2",
"@ucap/protocol-room": "~0.0.2",
"@ucap/protocol-service": "~0.0.2",
"@ucap/protocol-status": "~0.0.2",
"@ucap/protocol-sync": "~0.0.2",
"@ucap/protocol-umg": "~0.0.2",
"@ucap/web-socket": "~0.0.2",
"@ucap/web-storage": "~0.0.2",
"autolinker": "^3.13.0",
"axios": "^0.19.2",
"classlist.js": "^1.1.20150312",
"crypto-js": "^4.0.0",
"detect-browser": "^5.0.0",
"file-type": "^14.1.4",
"i18next": "^19.3.3",
"i18next-browser-languagedetector": "^4.0.2",
"i18next-node-fs-backend": "^2.1.3",
@ -102,8 +110,11 @@
"moment-timezone": "^0.5.28",
"ngx-perfect-scrollbar": "^9.0.0",
"ngx-virtual-scroller": "^4.0.3",
"pino": "^6.0.0",
"queueing-subject": "^0.3.4",
"rxjs": "~6.5.4",
"tslib": "^1.10.0",
"web-animations-js": "^2.3.2",
"zone.js": "~0.10.2"
},
"devDependencies": {

View File

@ -2,10 +2,7 @@ import { NgModule, APP_INITIALIZER } from '@angular/core';
import axios from 'axios';
import { NativeService, NativeType } from '@ucap/native';
import { AXIOS_INSTANCE } from '@ucap/ng-core';
import { I18nService } from '@ucap/ng-i18n';
import { UCAP_NATIVE_SERVICE } from '@ucap/ng-native';
import { environment } from '@environments';
@ -14,9 +11,10 @@ import { AppAuthenticationGuard } from './guards/app-authentication.guard';
import { AppAuthenticationService } from './services/app-authentication.service';
import { AppNativeService } from './services/app-native.service';
import { AppService } from './services/app.service';
const GUARDS = [AppAuthenticationGuard];
const SERVICES = [AppAuthenticationService, AppNativeService];
const SERVICES = [AppService, AppAuthenticationService, AppNativeService];
const axiosFactory = () => {
const i = axios.create();
@ -24,51 +22,8 @@ const axiosFactory = () => {
return i;
};
const appInit = (nativeService: NativeService, i18nService: I18nService) => {
return () =>
new Promise<void>(async (resolve, reject) => {
switch (nativeService.type()) {
case NativeType.Browser:
const xhr = await import('i18next-xhr-backend').then(m => m.default);
const languageDetector = await import(
'i18next-browser-languagedetector'
).then(m => m.default);
i18nService.use(xhr).use(languageDetector);
break;
// case NativeType.Electron:
// const nodeFs = await import('i18next-node-fs-backend').then(m => m);
// i18nService.use(nodeFs);
// break;
default:
break;
}
i18nService
.init({
whitelist: ['ko', 'en'],
fallbackLng: 'ko',
debug: true, // set debug?
returnEmptyString: false,
ns: [
'common',
'organization',
'authentication',
'group',
'chat',
'call',
'message'
],
backend: {
loadPath: 'assets/i18n/{{lng}}/{{ns}}.json'
}
})
.then(() => {
resolve();
})
.catch(reason => {
reject(reason);
});
});
const appInit = (appService: AppService) => {
return () => appService.initialize();
};
@NgModule({
@ -90,7 +45,7 @@ const appInit = (nativeService: NativeService, i18nService: I18nService) => {
{
provide: APP_INITIALIZER,
useFactory: appInit,
deps: [UCAP_NATIVE_SERVICE, I18nService],
deps: [AppService],
multi: true
},
...GUARDS,

View File

@ -64,6 +64,7 @@ import { environment } from '@environments';
LoggerModule.forRoot({
optionsOrStream: {
level: 'debug',
browser: {
write: o => {
console.log(o);

View File

@ -3,6 +3,7 @@
<div class="login-section-container">
<app-sections-account-login
[companyGroupCode]="companyGroupCode"
[fixedCompanyCode]="fixedCompanyCode"
[userStore]="userStore"
[useRememberMe]="useRememberMe"
[useAutoLogin]="useAutoLogin"

View File

@ -17,10 +17,11 @@ export class LoginPageComponent implements OnInit, OnDestroy {
userStore: UserStore;
readonly useRememberMe =
environment.productConfig.authentication.rememberMe.use;
environment.productConfig.authentication.useRememberMe;
readonly useAutoLogin =
environment.productConfig.authentication.autoLogin.use;
readonly useAutoLogin = environment.productConfig.authentication.useAutoLogin;
readonly fixedCompanyCode = environment.companyConfig.fixedCompanyCode;
constructor(private localStorageService: LocalStorageService) {}

View File

@ -3,6 +3,8 @@ import { CommonModule } from '@angular/common';
import { FlexLayoutModule } from '@angular/flex-layout';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { I18nModule, UCAP_I18N_NAMESPACE } from '@ucap/ng-i18n';
import { AuthenticationUiModule } from '@ucap/ng-ui-authentication';
@ -10,7 +12,13 @@ import { AuthenticationUiModule } from '@ucap/ng-ui-authentication';
import { COMPONENTS } from './components';
@NgModule({
imports: [CommonModule, FlexLayoutModule, I18nModule, AuthenticationUiModule],
imports: [
CommonModule,
FlexLayoutModule,
MatCheckboxModule,
I18nModule,
AuthenticationUiModule
],
exports: [...COMPONENTS],
declarations: [...COMPONENTS],
entryComponents: [],

View File

@ -1,11 +1,10 @@
<ucap-authentication-login
[companyList]="companyList"
[fixedCompanyCode]="fixedCompanyCode"
[companyCode]="userStore?.companyCode"
[loginId]="userStore?.loginId"
[rememberMe]="userStore?.rememberMe"
[autoLogin]="userStore?.settings?.general?.autoLogin"
[useRememberMe]="useRememberMe"
[useAutoLogin]="useAutoLogin"
[disable]="disableLoginForm"
[processing]="loginProcessing"
(login)="onLogin($event)"
>
<div
@ -15,9 +14,42 @@
{{ 'login.labels.instructionsOfLogin' | ucapI18n }}
</div>
<div ucapAuthenticationLogin="footer">
<div
class="remember-forgot-password"
fxLayout="row"
fxLayout.xs="column"
fxLayoutAlign="space-between center"
>
<mat-checkbox
#chkUseRememberMe
*ngIf="useRememberMe"
class="remember-me"
aria-label="Remember Me"
>
{{ 'login.labels.rememberMe' | ucapI18n }}
</mat-checkbox>
<mat-checkbox
#chkUseAutoLogin
*ngIf="useAutoLogin"
class="auto-login"
aria-label="Auto Login"
>
{{ 'login.labels.autoLogin' | ucapI18n }}
</mat-checkbox>
</div>
<div class="register" fxLayout="column" fxLayoutAlign="center center">
<button class="link btn-login-forgot" (click)="onClickForgotPassword()">
Forgot Password?
<button
class="link btn-login-forgot"
(click)="onClickForgotPassword('ko')"
>
Forgot Password? KO
</button>
<button
class="link btn-login-forgot"
(click)="onClickForgotPassword('en')"
>
Forgot Password? EN
</button>
</div>

View File

@ -1,16 +1,25 @@
import { Subscription } from 'rxjs';
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { Component, OnInit, OnDestroy, Input, ViewChild } from '@angular/core';
import { MatCheckbox } from '@angular/material/checkbox';
import { Store, select } from '@ngrx/store';
import { Company } from '@ucap/api-external';
import { ProtocolService } from '@ucap/ng-protocol';
import { LogService } from '@ucap/ng-logger';
import { I18nService } from '@ucap/ng-i18n';
import { SessionStorageService } from '@ucap/ng-web-storage';
import { PiService } from '@ucap/ng-pi';
import { ProtocolService } from '@ucap/ng-protocol';
import { CompanyActions, CompanySelector } from '@ucap/ng-store-organization';
import { LoginActions } from '@ucap/ng-store-authentication';
import { UserStore } from '@app/models/user-store';
import { LoginSession } from '@app/models/login-session';
import { AppKey } from '@app/types/app-key.type';
import { take } from 'rxjs/operators';
@Component({
selector: 'app-sections-account-login',
@ -21,6 +30,9 @@ export class LoginSectionComponent implements OnInit, OnDestroy {
@Input()
companyGroupCode: string;
@Input()
fixedCompanyCode: string;
@Input()
userStore: UserStore;
@ -30,17 +42,33 @@ export class LoginSectionComponent implements OnInit, OnDestroy {
@Input()
useAutoLogin: boolean;
@ViewChild('chkUseRememberMe', { static: false })
chkUseRememberMe: MatCheckbox;
@ViewChild('chkUseAutoLogin', { static: false })
chkUseAutoLogin: MatCheckbox;
loginSession: LoginSession;
companyList: Company[];
disableLoginForm = false;
loginProcessing = false;
private companyListSubscription: Subscription;
constructor(
private piService: PiService,
private protocolService: ProtocolService,
private sessionStorageService: SessionStorageService,
private i18nService: I18nService,
private store: Store<any>
private store: Store<any>,
private logService: LogService
) {}
ngOnInit(): void {
this.loginSession = this.sessionStorageService.get<LoginSession>(
AppKey.LoginSession
);
this.protocolService.disconnect();
this.store.dispatch(
@ -66,12 +94,54 @@ export class LoginSectionComponent implements OnInit, OnDestroy {
companyCode: string;
loginId: string;
loginPw: string;
rememberMe: boolean;
autoLogin: boolean;
notValid: () => void;
}) {}
}) {
const useRememberMe: boolean = this.chkUseRememberMe.checked;
const useAutoLogin: boolean = this.chkUseAutoLogin.checked;
onClickForgotPassword() {
this.i18nService.changeLanguage('ko');
this.disableLoginForm = true;
this.loginProcessing = true;
this.piService
.login2({
companyCode: event.companyCode,
loginId: event.loginId,
loginPw: event.loginPw,
deviceType: this.loginSession.deviceType
})
.pipe(take(1))
.subscribe(
res => {
if ('success' !== res.status.toLowerCase()) {
this.store.dispatch(
LoginActions.webLoginFailure({ error: res.status })
);
return;
} else {
this.store.dispatch(
LoginActions.webLoginSuccess({
companyCode: event.companyCode,
loginId: event.loginId,
loginPw: event.loginPw,
autoLogin: useAutoLogin,
rememberMe: useRememberMe,
login2Response: res
})
);
return;
}
},
error => {
this.store.dispatch(LoginActions.webLoginFailure({ error }));
},
() => {
this.disableLoginForm = false;
this.loginProcessing = false;
}
);
}
onClickForgotPassword(lng: string) {
this.i18nService.changeLanguage(lng);
}
}

View File

@ -0,0 +1,108 @@
import { Injectable, Inject } from '@angular/core';
import { DeviceType, DesktopType } from '@ucap/core';
import { NativeService, NativeType, OsType } from '@ucap/native';
import { I18nService } from '@ucap/ng-i18n';
import { UCAP_NATIVE_SERVICE } from '@ucap/ng-native';
import { SessionStorageService } from '@ucap/ng-web-storage';
import { LoginSession } from '@app/models/login-session';
import { AppKey } from '@app/types/app-key.type';
@Injectable()
export class AppService {
constructor(
private sessionStorageService: SessionStorageService,
private i18nService: I18nService,
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService
) {}
initialize(): Promise<void[]> {
const initSession = new Promise<void>(async (resolve, reject) => {
try {
let deviceType: DeviceType;
let desktopType: DesktopType;
switch (this.nativeService.type()) {
case NativeType.Browser:
deviceType = DeviceType.Web;
break;
case NativeType.Electron:
deviceType = DeviceType.PC;
break;
default:
break;
}
const osType = await this.nativeService.osType();
switch (osType) {
case OsType.Windows:
desktopType = DesktopType.Windows;
break;
case OsType.MacOS:
desktopType = DesktopType.MacOS;
break;
default:
desktopType = DesktopType.Linux;
break;
}
this.sessionStorageService.set<LoginSession>(AppKey.LoginSession, {
deviceType,
desktopType
});
resolve();
} catch (error) {
reject(error);
}
});
const initI18n = new Promise<void>(async (resolve, reject) => {
switch (this.nativeService.type()) {
case NativeType.Browser:
const xhr = await import('i18next-xhr-backend').then(m => m.default);
const languageDetector = await import(
'i18next-browser-languagedetector'
).then(m => m.default);
this.i18nService.use(xhr).use(languageDetector);
break;
// case NativeType.Electron:
// const nodeFs = await import('i18next-node-fs-backend').then(m => m);
// i18nService.use(nodeFs);
// break;
default:
break;
}
this.i18nService
.init({
whitelist: ['ko', 'en'],
fallbackLng: 'ko',
debug: true, // set debug?
returnEmptyString: false,
ns: [
'common',
'organization',
'authentication',
'group',
'chat',
'call',
'message'
],
backend: {
loadPath: 'assets/i18n/{{lng}}/{{ns}}.json'
}
})
.then(() => {
resolve();
})
.catch(reason => {
reject(reason);
});
});
return Promise.all([initSession, initI18n]);
}
}

View File

@ -1,7 +1,8 @@
{
"login": {
"labels": {
"rememberMe": "",
"doLogin": "Login",
"rememberMe": "Remember me",
"autoLogin": "Auto login",
"instructionsOfLogin": "LOGIN TO YOUR ACCOUNT"
},

View File

@ -1,7 +1,8 @@
{
"login": {
"labels": {
"rememberMe": "",
"doLogin": "로그인",
"rememberMe": "아이디 저장",
"autoLogin": "자동 로그인",
"instructionsOfLogin": "계정에 로그인 하세요."
},

View File

@ -64,12 +64,8 @@ export const environment: Environment = {
},
authentication: {
usePrivateInformationAgree: false,
rememberMe: {
use: false
},
autoLogin: {
use: true
}
useRememberMe: true,
useAutoLogin: true
},
profile: {
editableProfileImage: false

View File

@ -63,12 +63,8 @@ export const environment: Environment = {
},
authentication: {
usePrivateInformationAgree: false,
rememberMe: {
use: false
},
autoLogin: {
use: true
}
useRememberMe: true,
useAutoLogin: true
},
profile: {
editableProfileImage: false

View File

@ -66,12 +66,8 @@ export const environment: Environment = {
},
authentication: {
usePrivateInformationAgree: false,
rememberMe: {
use: false
},
autoLogin: {
use: true
}
useRememberMe: true,
useAutoLogin: true
},
profile: {
editableProfileImage: false

View File

@ -59,12 +59,8 @@ export interface Environment {
};
authentication: {
usePrivateInformationAgree: boolean;
rememberMe: {
use: boolean;
};
autoLogin: {
use: boolean;
};
useRememberMe: boolean;
useAutoLogin: boolean;
};
profile: {
/** 내 프로필 이미지 수정 가능 여부 */

62
src/polyfills.es5.ts Normal file
View File

@ -0,0 +1,62 @@
/**
* This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file.
*
* This file is divided into 2 sections:
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
* file.
*
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
*
* Learn more in https://angular.io/guide/browser-support
*/
/***************************************************************************************************
* BROWSER POLYFILLS
*/
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
import 'classlist.js'; // Run `npm install --save classlist.js`.
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
*/
import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/**
* By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags
* because those flags need to be set before `zone.js` being loaded, and webpack
* will put import in the top of bundle, so user need to create a separate file
* in this directory (for example: zone-flags.ts), and put the following flags
* into that file, and then add the following code before importing zone.js.
* import './zone-flags';
*
* The flags allowed in zone-flags.ts are listed here.
*
* The following flags will work for all browsers.
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
*
* (window as any).__Zone_enable_cross_context_check = true;
*
*/
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
import 'zone.js/dist/zone'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/

10
tsconfig.app.es5.json Normal file
View File

@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"target": "ES5",
"types": []
},
"files": ["src/main.ts", "src/polyfills.ts"],
"include": ["src/**/*.d.ts"]
}