Merge branch 'master' of http://10.81.13.221:6990/Web/next-ucap-messenger
This commit is contained in:
		
						commit
						0f88633aea
					
				
							
								
								
									
										2
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @ -8,7 +8,7 @@ | ||||
|   "files.trimTrailingWhitespace": true, | ||||
|   "files.trimFinalNewlines": true, | ||||
|   "files.watcherExclude": { | ||||
|     "**/dist/electron/win-unpacked/**": true | ||||
|     "**/dist": true | ||||
|   }, | ||||
|   "go.testFlags": ["-v"], | ||||
|   "go.testTimeout": "100s", | ||||
|  | ||||
| @ -44,7 +44,7 @@ import { ROOT_REDUCERS, metaReducers, effects } from './store'; | ||||
|      * See: https://github.com/zalmoxisus/redux-devtools-extension
 | ||||
|      */ | ||||
|     StoreDevtoolsModule.instrument({ | ||||
|       name: 'NgRx Book Store App' | ||||
|       name: 'UCAP Store App' | ||||
| 
 | ||||
|       // In a production build you would want to disable the Store Devtools
 | ||||
|       // logOnly: environment.production,
 | ||||
|  | ||||
| @ -0,0 +1 @@ | ||||
| <ucap-account-change-password></ucap-account-change-password> | ||||
| @ -0,0 +1,27 @@ | ||||
| /* tslint:disable:no-unused-variable */ | ||||
| import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| import { By } from '@angular/platform-browser'; | ||||
| import { DebugElement } from '@angular/core'; | ||||
| 
 | ||||
| import { ChangePasswordDialogComponent } from './change-password.dialog.component'; | ||||
| 
 | ||||
| describe('ChangePasswordDialogComponent', () => { | ||||
|   let component: ChangePasswordDialogComponent; | ||||
|   let fixture: ComponentFixture<ChangePasswordDialogComponent>; | ||||
| 
 | ||||
|   beforeEach(async(() => { | ||||
|     TestBed.configureTestingModule({ | ||||
|       declarations: [ChangePasswordDialogComponent] | ||||
|     }).compileComponents(); | ||||
|   })); | ||||
| 
 | ||||
|   beforeEach(() => { | ||||
|     fixture = TestBed.createComponent(ChangePasswordDialogComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
| 
 | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,56 @@ | ||||
| import { Component, OnInit, Inject, OnDestroy } from '@angular/core'; | ||||
| import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; | ||||
| import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type'; | ||||
| import { KEY_VER_INFO } from '@app/types/ver-info.type'; | ||||
| import { SessionStorageService } from '@ucap-webmessenger/web-storage'; | ||||
| 
 | ||||
| import { Store } from '@ngrx/store'; | ||||
| 
 | ||||
| import { UserInfo } from '@ucap-webmessenger/protocol-sync'; | ||||
| import { | ||||
|   UserInfoSS, | ||||
|   UserInfoF, | ||||
|   UserInfoDN | ||||
| } from '@ucap-webmessenger/protocol-query'; | ||||
| import { DialogService } from '@ucap-webmessenger/ui'; | ||||
| import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; | ||||
| import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; | ||||
| 
 | ||||
| export interface ChangePasswordDialogData {} | ||||
| 
 | ||||
| export interface ChangePasswordDialogResult { | ||||
|   choice: boolean; | ||||
| } | ||||
| 
 | ||||
| @Component({ | ||||
|   selector: 'app-change-password.dialog', | ||||
|   templateUrl: './change-password.dialog.component.html', | ||||
|   styleUrls: ['./change-password.dialog.component.scss'] | ||||
| }) | ||||
| export class ChangePasswordDialogComponent implements OnInit, OnDestroy { | ||||
|   loginRes: LoginResponse; | ||||
|   sessionVerinfo: VersionInfo2Response; | ||||
|   isMe: boolean; | ||||
| 
 | ||||
|   constructor( | ||||
|     public dialogRef: MatDialogRef< | ||||
|       ChangePasswordDialogData, | ||||
|       ChangePasswordDialogResult | ||||
|     >, | ||||
|     @Inject(MAT_DIALOG_DATA) public data: ChangePasswordDialogData, | ||||
|     private dialogService: DialogService, | ||||
|     private sessionStorageService: SessionStorageService, | ||||
|     private store: Store<any> | ||||
|   ) { | ||||
|     this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>( | ||||
|       KEY_VER_INFO | ||||
|     ); | ||||
|     this.loginRes = this.sessionStorageService.get<LoginResponse>( | ||||
|       KEY_LOGIN_RES_INFO | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   ngOnInit() {} | ||||
| 
 | ||||
|   ngOnDestroy(): void {} | ||||
| } | ||||
| @ -0,0 +1,3 @@ | ||||
| import { ChangePasswordDialogComponent } from './change-password.dialog.component'; | ||||
| 
 | ||||
| export const DIALOGS = [ChangePasswordDialogComponent]; | ||||
| @ -1,3 +1,4 @@ | ||||
| import { DIALOGS as ACCOUNT_DIALOGS } from './account'; | ||||
| import { DIALOGS as CHAT_DIALOGS } from './chat'; | ||||
| import { DIALOGS as GROUP_DIALOGS } from './group'; | ||||
| import { DIALOGS as MESSAGE_DIALOGS } from './message'; | ||||
| @ -5,6 +6,7 @@ import { DIALOGS as PROFILE_DIALOGS } from './profile'; | ||||
| import { DIALOGS as SETTINGS_DIALOGS } from './settings'; | ||||
| 
 | ||||
| export const DIALOGS = [ | ||||
|   ...ACCOUNT_DIALOGS, | ||||
|   ...CHAT_DIALOGS, | ||||
|   ...GROUP_DIALOGS, | ||||
|   ...MESSAGE_DIALOGS, | ||||
|  | ||||
| @ -40,6 +40,7 @@ import { OverlayModule } from '@angular/cdk/overlay'; | ||||
| import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar'; | ||||
| 
 | ||||
| import { UCapUiModule } from '@ucap-webmessenger/ui'; | ||||
| import { UCapUiAccountModule } from '@ucap-webmessenger/ui-account'; | ||||
| import { UCapUiChatModule } from '@ucap-webmessenger/ui-chat'; | ||||
| import { UCapUiRoomModule } from '@ucap-webmessenger/ui-room'; | ||||
| import { UCapUiProfileModule } from '@ucap-webmessenger/ui-profile'; | ||||
| @ -89,6 +90,7 @@ import { DIALOGS } from './dialogs'; | ||||
|     PerfectScrollbarModule, | ||||
| 
 | ||||
|     UCapUiModule, | ||||
|     UCapUiAccountModule, | ||||
|     UCapUiChatModule, | ||||
|     UCapUiRoomModule, | ||||
|     UCapUiProfileModule, | ||||
|  | ||||
| @ -50,6 +50,8 @@ import * as SyncStore from '@app/store/messenger/sync'; | ||||
| import { KEY_VER_INFO } from '@app/types/ver-info.type'; | ||||
| import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type'; | ||||
| 
 | ||||
| import { environment } from '../../environments/environment'; | ||||
| 
 | ||||
| @Injectable() | ||||
| export class AppMessengerResolver implements Resolve<void> { | ||||
|   constructor( | ||||
| @ -115,8 +117,8 @@ export class AppMessengerResolver implements Resolve<void> { | ||||
|               hostName: '', | ||||
|               ssoMode: SSOMode.AUTH, | ||||
|               userSpecificInformation: 'PRO_000482', | ||||
|               productId: 'PRO_000482', | ||||
|               productName: 'EZMessenger' | ||||
|               productId: environment.productConfig.productId, | ||||
|               productName: environment.productConfig.productName | ||||
|             }); | ||||
|           }), | ||||
|           switchMap(res => { | ||||
| @ -141,11 +143,9 @@ export class AppMessengerResolver implements Resolve<void> { | ||||
| 
 | ||||
|             this.store.dispatch( | ||||
|               CompanyStore.companyList({ | ||||
|                 companyGroupCode: 'LG' | ||||
|                 companyGroupCode: environment.companyConfig.companyGroupCode | ||||
|               }) | ||||
|             ); | ||||
| 
 | ||||
|             // this.store.dispatch(AuthenticationStore.postLogin({ loginRes }));
 | ||||
|           }), | ||||
|           withLatestFrom( | ||||
|             this.store.pipe( | ||||
| @ -189,6 +189,7 @@ export class AppMessengerResolver implements Resolve<void> { | ||||
|                 loginRes | ||||
|               }) | ||||
|             ); | ||||
|             this.store.dispatch(AuthenticationStore.postLogin({ loginRes })); | ||||
|             resolve(); | ||||
|           }, | ||||
|           err => { | ||||
|  | ||||
| @ -32,6 +32,7 @@ export class AppAuthenticationService { | ||||
| 
 | ||||
|     this.sessionStorageService.set<LoginInfo>(KEY_LOGIN_INFO, { | ||||
|       ...loginInfo, | ||||
|       initPw: loginInfo.loginId === loginInfo.loginPw, | ||||
|       loginPw: CryptoJS.enc.Hex.stringify(CryptoJS.SHA256(loginInfo.loginPw)) | ||||
|     }); | ||||
| 
 | ||||
|  | ||||
| @ -58,6 +58,14 @@ import { | ||||
|   LoginResponse | ||||
| } from '@ucap-webmessenger/protocol-authentication'; | ||||
| import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type'; | ||||
| import { ProtocolService } from '@ucap-webmessenger/protocol'; | ||||
| 
 | ||||
| import { environment } from '../../../../environments/environment'; | ||||
| import { | ||||
|   ChangePasswordDialogComponent, | ||||
|   ChangePasswordDialogData, | ||||
|   ChangePasswordDialogResult | ||||
| } from '@app/layouts/messenger/dialogs/account/change-password.dialog.component'; | ||||
| 
 | ||||
| @Injectable() | ||||
| export class Effects { | ||||
| @ -128,13 +136,12 @@ export class Effects { | ||||
|       this.actions$.pipe( | ||||
|         ofType(loginRedirect), | ||||
|         tap(authed => { | ||||
|           this.ngZone.run(() => { | ||||
|           // this.ngZone.run(() => {
 | ||||
|           // location.href = this.router.parseUrl('/account/login').toString();
 | ||||
|             this.router.navigate(['/account/login']).then(() => { | ||||
|           this.router.navigate(['/account/login']); | ||||
|           this.appAuthenticationService.logout(); | ||||
|           this.store.dispatch(logoutInitialize()); | ||||
|             }); | ||||
|           }); | ||||
|           // });
 | ||||
|         }) | ||||
|       ), | ||||
|     { dispatch: false } | ||||
| @ -147,6 +154,7 @@ export class Effects { | ||||
|         switchMap(action => { | ||||
|           return this.authenticationProtocolService.logout({}).pipe( | ||||
|             map(res => { | ||||
|               this.protocolService.disconnect(); | ||||
|               this.store.dispatch(loginRedirect()); | ||||
|             }), | ||||
|             catchError(error => of(error)) | ||||
| @ -199,7 +207,11 @@ export class Effects { | ||||
|             EnvironmentsInfo | ||||
|           >(KEY_ENVIRONMENTS_INFO); | ||||
| 
 | ||||
|           if (!loginRes.privateInformationAgree) { | ||||
|           if ( | ||||
|             environment.productConfig.authentication | ||||
|               .usePrivateInformationAgree && | ||||
|             !loginRes.privateInformationAgree | ||||
|           ) { | ||||
|             const privacyTotalUrl = this.piService.privacyTotalUrl({ | ||||
|               companyCode: loginInfo.companyCode, | ||||
|               userSeq: loginRes.userSeq, | ||||
| @ -218,8 +230,8 @@ export class Effects { | ||||
|               height: '500px', | ||||
|               disableClose: true, | ||||
|               data: { | ||||
|                 title: '개인정보 동의' | ||||
|                 // html: `<iframe id="ifm_privacy" src="${privacyTotalUrl}" style="width: 100%;height: 300px;" />`
 | ||||
|                 title: '개인정보 동의', | ||||
|                 html: `<iframe id="ifm_privacy" src="${privacyTotalUrl}" style="width: 100%;height: 300px;" />` | ||||
|               } | ||||
|             }); | ||||
| 
 | ||||
| @ -231,7 +243,13 @@ export class Effects { | ||||
|             } | ||||
|           } | ||||
| 
 | ||||
|           if (!!loginRes.passwordExpired) { | ||||
|           if (loginInfo.initPw) { | ||||
|             this.store.dispatch(logout()); | ||||
| 
 | ||||
|             const passwordInitStep1Url = this.piService.passwordInitStep1Url({ | ||||
|               localeCode: loginInfo.localeCode | ||||
|             }); | ||||
| 
 | ||||
|             const result = await this.dialogService.open< | ||||
|               ConfirmDialogComponent, | ||||
|               ConfirmDialogData, | ||||
| @ -241,8 +259,8 @@ export class Effects { | ||||
|               height: '500px', | ||||
|               disableClose: true, | ||||
|               data: { | ||||
|                 title: '패스워드 만료', | ||||
|                 message: '' | ||||
|                 title: '패스워드 초기화', | ||||
|                 html: `<iframe id="ifm_privacy" src="${passwordInitStep1Url}" style="width: 100%;height: 300px;" />` | ||||
|               } | ||||
|             }); | ||||
| 
 | ||||
| @ -251,6 +269,24 @@ export class Effects { | ||||
|               return; | ||||
|             } | ||||
|           } | ||||
| 
 | ||||
|           if (!!loginRes.passwordExpired) { | ||||
|             const result = await this.dialogService.open< | ||||
|               ChangePasswordDialogComponent, | ||||
|               ChangePasswordDialogData, | ||||
|               ChangePasswordDialogResult | ||||
|             >(ChangePasswordDialogComponent, { | ||||
|               width: '500px', | ||||
|               height: '500px', | ||||
|               disableClose: false, | ||||
|               data: {} | ||||
|             }); | ||||
| 
 | ||||
|             if (!!result && result.choice) { | ||||
|             } else { | ||||
|               return; | ||||
|             } | ||||
|           } | ||||
|         }) | ||||
|       ), | ||||
|     { dispatch: false } | ||||
| @ -319,6 +355,7 @@ export class Effects { | ||||
|     private sessionStorageService: SessionStorageService, | ||||
|     private piService: PiService, | ||||
|     private appAuthenticationService: AppAuthenticationService, | ||||
|     private protocolService: ProtocolService, | ||||
|     private authenticationProtocolService: AuthenticationProtocolService, | ||||
|     private serviceProtocolService: ServiceProtocolService, | ||||
|     private dialogService: DialogService, | ||||
|  | ||||
| @ -155,7 +155,7 @@ export class Effects { | ||||
|         tap(() => { | ||||
|           groupList = []; | ||||
|         }), | ||||
|         switchMap(req => { | ||||
|         exhaustMap(req => { | ||||
|           return this.syncProtocolService.group2(req).pipe( | ||||
|             map(res => { | ||||
|               switch (res.SSVC_TYPE) { | ||||
| @ -167,7 +167,7 @@ export class Effects { | ||||
|                 case SSVC_TYPE_SYNC_GROUP_RES2: | ||||
|                   this.store.dispatch( | ||||
|                     group2Success({ | ||||
|                       groupList, | ||||
|                       groupList: [...groupList], | ||||
|                       syncDate: (res as GroupResponse).syncDate | ||||
|                     }) | ||||
|                   ); | ||||
|  | ||||
| @ -5,6 +5,7 @@ export const KEY_LOGIN_INFO = 'ucap::LOGIN_INFO'; | ||||
| export interface LoginInfo { | ||||
|   loginId?: string; | ||||
|   loginPw?: string; | ||||
|   initPw?: boolean; | ||||
|   companyCode?: string; | ||||
|   companyGroupType?: string; | ||||
|   localeCode?: LocaleCode; | ||||
|  | ||||
| @ -13,6 +13,18 @@ export const environment: Environment = { | ||||
|   production: false, | ||||
|   title: `[개발] UCapMessenger`, | ||||
| 
 | ||||
|   companyConfig: { | ||||
|     companyGroupCode: 'LG' | ||||
|   }, | ||||
| 
 | ||||
|   productConfig: { | ||||
|     productId: 'PRO_000482', | ||||
|     productName: 'EZMessenger', | ||||
|     authentication: { | ||||
|       usePrivateInformationAgree: false | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   commonApiModuleConfig: { | ||||
|     hostConfig: { | ||||
|       protocol: 'http', | ||||
|  | ||||
| @ -13,6 +13,18 @@ export const environment: Environment = { | ||||
|   production: true, | ||||
|   title: `[개발] UCapMessenger`, | ||||
| 
 | ||||
|   companyConfig: { | ||||
|     companyGroupCode: 'LG' | ||||
|   }, | ||||
| 
 | ||||
|   productConfig: { | ||||
|     productId: 'PRO_000482', | ||||
|     productName: 'EZMessenger', | ||||
|     authentication: { | ||||
|       usePrivateInformationAgree: false | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   commonApiModuleConfig: { | ||||
|     hostConfig: { | ||||
|       protocol: 'http', | ||||
|  | ||||
| @ -31,6 +31,18 @@ export interface Environment { | ||||
|   runtime?: UCapRuntime; | ||||
|   title: string; | ||||
| 
 | ||||
|   companyConfig: { | ||||
|     companyGroupCode: string; | ||||
|   }; | ||||
| 
 | ||||
|   productConfig: { | ||||
|     productId: string; | ||||
|     productName: string; | ||||
|     authentication: { | ||||
|       usePrivateInformationAgree: boolean; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   commonApiModuleConfig: CommonApiModuleConfig; | ||||
|   publicApiModuleConfig: PublicApiModuleConfig; | ||||
|   externalApiModuleConfig: ExternalApiModuleConfig; | ||||
|  | ||||
| @ -0,0 +1,17 @@ | ||||
| import { PIRequest } from './pi'; | ||||
| import { LocaleCode } from '@ucap-webmessenger/core'; | ||||
| import { APIEncoder, ParameterUtil } from '@ucap-webmessenger/api'; | ||||
| 
 | ||||
| export interface PasswordInitStep1Request extends PIRequest { | ||||
|   localeCode: LocaleCode; | ||||
| } | ||||
| 
 | ||||
| const passwordInitStep1EncodeMap = { | ||||
|   localeCode: 'locale' | ||||
| }; | ||||
| 
 | ||||
| export const encodePasswordInitStep1: APIEncoder<PasswordInitStep1Request> = ( | ||||
|   req: PasswordInitStep1Request | ||||
| ) => { | ||||
|   return ParameterUtil.encode(passwordInitStep1EncodeMap, req); | ||||
| }; | ||||
| @ -8,7 +8,7 @@ import { | ||||
|   Login2Request, | ||||
|   Login2Response, | ||||
|   encodeLogin2, | ||||
|   decodeLogin2, | ||||
|   decodeLogin2 | ||||
| } from '../apis/login2'; | ||||
| import { PrivacyTotalRequest, encodePrivacyTotal } from '../apis/privacy-total'; | ||||
| import { UrlUtil, Parameter } from '@ucap-webmessenger/api'; | ||||
| @ -16,8 +16,12 @@ import { | ||||
|   UserTermsActionRequest, | ||||
|   UserTermsActionResponse, | ||||
|   encodeUserTermsAction, | ||||
|   decodeUserTermsAction, | ||||
|   decodeUserTermsAction | ||||
| } from '../apis/user-terms-action'; | ||||
| import { | ||||
|   PasswordInitStep1Request, | ||||
|   encodePasswordInitStep1 | ||||
| } from '../apis/password-init-step1'; | ||||
| 
 | ||||
| import { _MODULE_CONFIG } from '../config/token'; | ||||
| import { ModuleConfig } from '../config/module-config'; | ||||
| @ -25,7 +29,7 @@ import { Urls } from '../config/urls'; | ||||
| import { UrlConfig } from '@ucap-webmessenger/core'; | ||||
| 
 | ||||
| @Injectable({ | ||||
|   providedIn: 'root', | ||||
|   providedIn: 'root' | ||||
| }) | ||||
| export class PiService { | ||||
|   readonly urls: Urls; | ||||
| @ -46,7 +50,7 @@ export class PiService { | ||||
|         this.urls.login2, | ||||
|         {}, | ||||
|         { | ||||
|           params: encodeLogin2(req), | ||||
|           params: encodeLogin2(req) | ||||
|         } | ||||
|       ) | ||||
|       .pipe(map(res => decodeLogin2(res))); | ||||
| @ -60,7 +64,7 @@ export class PiService { | ||||
|         this.urls.userTermsAction, | ||||
|         {}, | ||||
|         { | ||||
|           params: encodeUserTermsAction(req), | ||||
|           params: encodeUserTermsAction(req) | ||||
|         } | ||||
|       ) | ||||
|       .pipe(map(res => decodeUserTermsAction(res))); | ||||
| @ -75,4 +79,14 @@ export class PiService { | ||||
|       encodePrivacyTotal(req) as Parameter | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * passwordInitStep1Url | ||||
|    */ | ||||
|   public passwordInitStep1Url(req: PasswordInitStep1Request): string { | ||||
|     return UrlUtil.format( | ||||
|       this.urls.passwordInitStep1, | ||||
|       encodePasswordInitStep1(req) as Parameter | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -6,6 +6,7 @@ export * from './lib/apis/pi'; | ||||
| export * from './lib/apis/login2'; | ||||
| export * from './lib/apis/privacy-total'; | ||||
| export * from './lib/apis/user-terms-action'; | ||||
| export * from './lib/apis/password-init-step1'; | ||||
| 
 | ||||
| export * from './lib/types/response-status.type'; | ||||
| 
 | ||||
|  | ||||
| @ -0,0 +1,52 @@ | ||||
| <div class="change-password-form"> | ||||
|   <div class="mat-title">비밀번호 변경</div> | ||||
| 
 | ||||
|   <form name="changePasswordForm" [formGroup]="changePasswordForm" novalidate> | ||||
|     <mat-form-field> | ||||
|       <mat-label>현재 패스워드</mat-label> | ||||
|       <input | ||||
|         matInput | ||||
|         type="password" | ||||
|         formControlName="currentLoginPw" | ||||
|         #currentLoginPw | ||||
|       /> | ||||
|       <mat-error> | ||||
|         현재 패스워드를 입력해 주세요 | ||||
|       </mat-error> | ||||
|     </mat-form-field> | ||||
|     <mat-form-field> | ||||
|       <mat-label>신규 패스워드</mat-label> | ||||
|       <input | ||||
|         matInput | ||||
|         type="password" | ||||
|         formControlName="newLoginPw" | ||||
|         #newLoginPw | ||||
|       /> | ||||
|       <mat-error> | ||||
|         신규 패스워드를 입력해 주세요 | ||||
|       </mat-error> | ||||
|     </mat-form-field> | ||||
|     <mat-form-field> | ||||
|       <mat-label>신규 패스워드 확인</mat-label> | ||||
|       <input | ||||
|         matInput | ||||
|         type="password" | ||||
|         formControlName="newConfirmLoginPw" | ||||
|         #newConfirmLoginPw | ||||
|       /> | ||||
|       <mat-error> | ||||
|         신규 패스워드 확인을 입력해 주세요 | ||||
|       </mat-error> | ||||
|     </mat-form-field> | ||||
| 
 | ||||
|     <button | ||||
|       mat-raised-button | ||||
|       class="submit-button bg-accent-dark" | ||||
|       aria-label="패스워드 변경" | ||||
|       [disabled]="changePasswordForm.invalid || !changePasswordBtnEnable" | ||||
|       (click)="onClickLogin()" | ||||
|     > | ||||
|       패스워드 변경 | ||||
|     </button> | ||||
|   </form> | ||||
| </div> | ||||
| @ -0,0 +1,63 @@ | ||||
| .change-password-form { | ||||
|   position: relative; | ||||
|   width: 384px; | ||||
|   max-width: 384px; | ||||
|   padding: 50px; | ||||
|   text-align: center; | ||||
|   background-color: rgba(255, 255, 255, 0.8); | ||||
|   border-radius: 0px; | ||||
|   box-shadow: 4px 4px 0px rgba(0, 0, 0, 0.1); | ||||
| 
 | ||||
|   .mat-title { | ||||
|     margin: 16px 0 32px 0; | ||||
|   } | ||||
| 
 | ||||
|   form { | ||||
|     width: 100%; | ||||
|     text-align: left; | ||||
| 
 | ||||
|     mat-form-field { | ||||
|       width: 100%; | ||||
|     } | ||||
| 
 | ||||
|     .submit-button { | ||||
|       width: 100%; | ||||
|       margin: 0 auto; | ||||
|       display: block; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   .separator { | ||||
|     font-size: 15px; | ||||
|     font-weight: 600; | ||||
|     margin: 24px auto; | ||||
|     position: relative; | ||||
|     overflow: hidden; | ||||
|     width: 100px; | ||||
| 
 | ||||
|     .text { | ||||
|       display: inline-flex; | ||||
|       position: relative; | ||||
|       padding: 0 8px; | ||||
|       z-index: 9999; | ||||
| 
 | ||||
|       &:before, | ||||
|       &:after { | ||||
|         content: ''; | ||||
|         display: block; | ||||
|         width: 30px; | ||||
|         position: absolute; | ||||
|         top: 10px; | ||||
|         border-top: 1px solid; | ||||
|       } | ||||
| 
 | ||||
|       &:before { | ||||
|         right: 100%; | ||||
|       } | ||||
| 
 | ||||
|       &:after { | ||||
|         left: 100%; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,24 @@ | ||||
| import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| 
 | ||||
| import { ChangePasswordComponent } from './change-password.component'; | ||||
| 
 | ||||
| describe('Account::ChangePasswordComponent', () => { | ||||
|   let component: ChangePasswordComponent; | ||||
|   let fixture: ComponentFixture<ChangePasswordComponent>; | ||||
| 
 | ||||
|   beforeEach(async(() => { | ||||
|     TestBed.configureTestingModule({ | ||||
|       declarations: [ChangePasswordComponent] | ||||
|     }).compileComponents(); | ||||
|   })); | ||||
| 
 | ||||
|   beforeEach(() => { | ||||
|     fixture = TestBed.createComponent(ChangePasswordComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
| 
 | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,67 @@ | ||||
| import { | ||||
|   Component, | ||||
|   OnInit, | ||||
|   Input, | ||||
|   Output, | ||||
|   EventEmitter, | ||||
|   ViewChild, | ||||
|   ElementRef, | ||||
|   ChangeDetectorRef | ||||
| } from '@angular/core'; | ||||
| import { FormGroup, FormBuilder, Validators } from '@angular/forms'; | ||||
| import { Company } from '@ucap-webmessenger/api-external'; | ||||
| import { LocalStorageService } from '@ucap-webmessenger/web-storage'; | ||||
| import { LoginInfo, KEY_LOGIN_INFO } from '@app/types'; | ||||
| 
 | ||||
| @Component({ | ||||
|   selector: 'ucap-account-change-password', | ||||
|   templateUrl: './change-password.component.html', | ||||
|   styleUrls: ['./change-password.component.scss'] | ||||
| }) | ||||
| export class ChangePasswordComponent implements OnInit { | ||||
|   @Input() | ||||
|   changePasswordBtnEnable: boolean; | ||||
| 
 | ||||
|   @Output() | ||||
|   changePassword = new EventEmitter<{ | ||||
|     currentLoginPw: string; | ||||
|     newLoginPw: string; | ||||
|     newConfirmLoginPw: string; | ||||
|     notValid: () => void; | ||||
|   }>(); | ||||
| 
 | ||||
|   @ViewChild('currentLoginPw', { static: true }) | ||||
|   currentLoginPwElementRef: ElementRef; | ||||
|   @ViewChild('newLoginPw', { static: true }) | ||||
|   newLoginPwElementRef: ElementRef; | ||||
| 
 | ||||
|   changePasswordForm: FormGroup; | ||||
| 
 | ||||
|   constructor( | ||||
|     private formBuilder: FormBuilder, | ||||
|     private changeDetectorRef: ChangeDetectorRef, | ||||
|     private localStorageService: LocalStorageService | ||||
|   ) {} | ||||
| 
 | ||||
|   ngOnInit() { | ||||
|     const loginInfo: LoginInfo = this.localStorageService.get<LoginInfo>( | ||||
|       KEY_LOGIN_INFO | ||||
|     ); | ||||
|     this.changePasswordForm = this.formBuilder.group({ | ||||
|       currentLoginPw: ['', Validators.required], | ||||
|       newLoginPw: ['', Validators.required], | ||||
|       newConfirmLoginPw: ['', Validators.required] | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   onClickLogin() { | ||||
|     this.changePassword.emit({ | ||||
|       currentLoginPw: this.changePasswordForm.get('currentLoginPw').value, | ||||
|       newLoginPw: this.changePasswordForm.get('newLoginPw').value, | ||||
|       newConfirmLoginPw: this.changePasswordForm.get('newConfirmLoginPw').value, | ||||
|       notValid: () => { | ||||
|         this.currentLoginPwElementRef.nativeElement.focus(); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| @ -11,11 +11,12 @@ import { MatIconModule } from '@angular/material/icon'; | ||||
| import { MatInputModule } from '@angular/material/input'; | ||||
| import { MatSelectModule } from '@angular/material/select'; | ||||
| 
 | ||||
| import { ChangePasswordComponent } from './components/change-password.component'; | ||||
| import { LoginComponent } from './components/login.component'; | ||||
| 
 | ||||
| import { AccountService } from './services/account.service'; | ||||
| 
 | ||||
| const COMPONENTS = [LoginComponent]; | ||||
| const COMPONENTS = [ChangePasswordComponent, LoginComponent]; | ||||
| const SERVICES = [AccountService]; | ||||
| 
 | ||||
| @NgModule({ | ||||
|  | ||||
| @ -3,5 +3,6 @@ | ||||
|  */ | ||||
| 
 | ||||
| export * from './lib/services/account.service'; | ||||
| export * from './lib/components/change-password.component'; | ||||
| export * from './lib/components/login.component'; | ||||
| export * from './lib/ucap-ui-account.module'; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user