sync
This commit is contained in:
parent
c06a39a2f9
commit
3ac4ee7865
94
documents/업무/6월/3째주/0618.txt
Normal file
94
documents/업무/6월/3째주/0618.txt
Normal file
|
@ -0,0 +1,94 @@
|
|||
그룹 디버그
|
||||
새그룹 추가
|
||||
그룹명 지정하지 않았는데 "그룹지정 후 완료" 버튼으로 진행됨.
|
||||
" " 블랭크 입력 후 "완료" 시 빈명칭의 그룹이 생성됨. (O)
|
||||
ime 처리 X
|
||||
전체 체크박스에 체크 안됨.
|
||||
전체 체크박스에 체크해제 안됨.
|
||||
기존 그룹 동료를 검색하면 체크가 되어 있지 않음(seq가 다른 타입)
|
||||
|
||||
그룹이름 바꾸기
|
||||
max length 체크 안되며, 매우 길 경우 바뀌지 않음.
|
||||
|
||||
그룹멤버관리
|
||||
|
||||
프로필 수정 사항
|
||||
프로필 이미지 출력 X
|
||||
닉네임 길이 체크
|
||||
닉네임 라벨이 없어지지 않음
|
||||
기존 닉네임값 출력 되지 않음
|
||||
|
||||
"http://13.124.88.127:8011/ProfileImage"
|
||||
/2019/12/16/PF_9824_84924202.jpg
|
||||
문의
|
||||
닉네임 입력 길이 문의
|
||||
|
||||
mat-form-field
|
||||
form-field-input-searchword
|
||||
ng-tns-c159-5
|
||||
mat-primary
|
||||
mat-form-field-type-mat-input
|
||||
mat-form-field-can-float
|
||||
mat-form-field-has-label
|
||||
mat-form-field-should-float
|
||||
|
||||
mat-form-field
|
||||
ng-tns-c159-7
|
||||
mat-primary
|
||||
mat-form-field-type-mat-input
|
||||
mat-form-field-can-float
|
||||
mat-form-field-should-float
|
||||
mat-form-field-has-label
|
||||
|
||||
|
||||
|
||||
1 CL → SS SSVC_TYPE_QUERY_USER_SEQ_REQ 21 사용자 SEQ 검색 DivCD(s) 로그인IDs(s) 기관코드(s) 상세정보여부(s) 발신자회사코드(s) 발신자임직원유형(s)
|
||||
2 SS → CL SSVC_TYPE_QUERY_USER_SEQ_DATA 22 사용자 SEQ 정보 (상세여부 E) DivCD(s) {사용자정보-F}1 {사용자정보-F}2 {사용자정보-F}n …
|
||||
22 사용자 SEQ 정보 (상세여부 N) DivCD(s) {SEQ정보}1 {SEQ정보}2 {SEQ정보}n
|
||||
2 SS → CL SSVC_TYPE_QUERY_USER_SEQ_DATA2 24 사용자 SEQ 정보 (상세여부 Y) DivCD(s) {사용자정보-SS}1 {사용자정보-SS}2 {사용자정보-SS}n …
|
||||
3 SS → CL SSVC_TYPE_QUERY_USER_SEQ_RES 23 DivCD(s)
|
||||
|
||||
|
||||
|
||||
"66264고재범 (책임) GUC00601064210909 jbgoh@cnspartner.comN석유화학정보화팀YKY999A41454 CJaebeom Goh (Manager) Petrochemical Information Team 155YNP"
|
||||
닉네임
|
||||
상태메세지
|
||||
대화 검색
|
||||
|
||||
userInfoF 프로토콜 생성 요청
|
||||
|
||||
ERROR TypeError: Cannot read property 'seq' of undefined
|
||||
at profile-01.component.ts:156
|
||||
at Array.filter (<anonymous>)
|
||||
at SafeSubscriber._next (profile-01.component.ts:155)
|
||||
at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)
|
||||
at SafeSubscriber.next (Subscriber.js:122)
|
||||
at Subscriber._next (Subscriber.js:72)
|
||||
at Subscriber.next (Subscriber.js:49)
|
||||
at DistinctUntilChangedSubscriber._next (distinctUntilChanged.js:50)
|
||||
at DistinctUntilChangedSubscriber.next (Subscriber.js:49)
|
||||
|
||||
|
||||
// switch (type) {
|
||||
// case 'CHAT':
|
||||
// this.appChatService.newOpenRoom(
|
||||
// [this.userInfo.seq as any],
|
||||
// false,
|
||||
// this.loginRes
|
||||
// );
|
||||
// break;
|
||||
// case 'MESSAGE':
|
||||
// break;
|
||||
// case 'MOBILE':
|
||||
// break;
|
||||
// case 'OFFICE':
|
||||
// break;
|
||||
// case 'VIDEO_CONFERENCE':
|
||||
// break;
|
||||
// }
|
||||
|
||||
assets/images/ico/img_nophoto.
|
||||
|
||||
http://13.124.88.127:8011/Prof
|
||||
|
||||
/2019/12/16/PF_9824_84924202.j
|
44
documents/업무/6월/3째주/0619.txt
Normal file
44
documents/업무/6월/3째주/0619.txt
Normal file
|
@ -0,0 +1,44 @@
|
|||
작업
|
||||
그룹
|
||||
관리 다이얼로그 컴포넌트
|
||||
타이틀 변경
|
||||
컨텍스트 변경에 대한 액션 변경
|
||||
그룹 선택, 동료 선택 체크 처리
|
||||
|
||||
동료 삭제
|
||||
동료 추가
|
||||
현재 그룹 seq
|
||||
기존 userseqs
|
||||
변경된 userseqs
|
||||
|
||||
동료 이동
|
||||
동료 복사
|
||||
그룹 생성
|
||||
|
||||
변수
|
||||
타이틀
|
||||
현재 인덱스
|
||||
그룹 이름
|
||||
현재 선택된 유저 리스트
|
||||
현재 선택된 그룹
|
||||
|
||||
그룹 셀렉트 컴포넌트
|
||||
그룹 체크 박스 (전체, 해제)
|
||||
유저 셀렉트 컴포넌트
|
||||
|
||||
프로필
|
||||
|
||||
list -> scroll checkbox label
|
||||
|
||||
|
||||
전체 체크박스
|
||||
아이템 한개 언체크 시 전체 체크박스 해제
|
||||
|
||||
|
||||
<ng-container
|
||||
*ngIf="
|
||||
!!dataSource && !!dataSource.data && dataSource.data.length > 0;
|
||||
else empty
|
||||
"
|
||||
>
|
||||
<ucap-organization-profile-list [dataSource]="dataSource">
|
67
documents/업무/6월/3째주/0620.txt
Normal file
67
documents/업무/6월/3째주/0620.txt
Normal file
|
@ -0,0 +1,67 @@
|
|||
angular 수정
|
||||
프로필 메뉴 클릭 시 사용자 바뀜
|
||||
|
||||
그룹 멤버 관리
|
||||
그룹 복사, 그룹이동 시 선택된 유저가 없는 경우
|
||||
버튼 비활성화
|
||||
그룹 정렬 방식이 그룹 메뉴의 리스트와 다름
|
||||
새그룹 추가시 validation 여부와 상관없이 확인 버튼 동작함
|
||||
조회시 검색결과 카운트 표출안됨
|
||||
조회시 검색결과 리스트 스크롤 오류
|
||||
기존그룹 없을 시 출력될 화면
|
||||
|
||||
|
||||
<perfect-scrollbar style="width: 100%; height: 100%;">
|
||||
<app-group-profile-list
|
||||
#groupProfileList
|
||||
[searchData]="companySearchData"
|
||||
[selectedUser]="selectedUserList"
|
||||
[checkable]="checkable"
|
||||
[isDialog]="isDialog"
|
||||
(toggleCheck)="onToggleCheckUser($event)"
|
||||
class="ucap-dialog-search-result-container"
|
||||
></app-group-profile-list>
|
||||
</perfect-scrollbar>
|
||||
if (
|
||||
!!datas &&
|
||||
!!this.searchUserInfos &&
|
||||
datas.length === this.searchUserInfos.length
|
||||
) {
|
||||
this.checkboxAllSearch.checked = datas[0].checked;
|
||||
} else {
|
||||
// if (!!this.searchUserInfos && this.searchUserInfos.length > 0) {
|
||||
// const tempUserInfos: UserInfoSS[] = [];
|
||||
|
||||
// this.searchUserInfos.map((user) => {
|
||||
// this.selectedUserList.every((selectUser) => {
|
||||
// if (user.seq === selectUser.seq) {
|
||||
// tempUserInfos.push(user);
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// });
|
||||
// });
|
||||
|
||||
// if (
|
||||
// tempUserInfos.length === this.searchUserInfos.length &&
|
||||
// !!this.checkboxAllSearch &&
|
||||
// !this.checkboxAllSearch.checked
|
||||
// ) {
|
||||
// this.checkboxAllSearch.checked = true;
|
||||
// } else {
|
||||
// this.checkboxAllSearch.checked = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
this.selectedUserList.
|
||||
}
|
||||
|
||||
그룹이동
|
||||
그룹하나 선택
|
||||
그룹 다중 선택
|
||||
사용자 한명
|
||||
사용자 다중 선택
|
||||
|
||||
기존 그룹에서 사용자 삭제
|
||||
이동시킬 그룹으로 업데이트
|
||||
|
108
documents/업무/6월/3째주/backup/manage.dialog.component.html
Normal file
108
documents/업무/6월/3째주/backup/manage.dialog.component.html
Normal file
|
@ -0,0 +1,108 @@
|
|||
<div class="dialog-container">
|
||||
<app-layouts-default-dialog
|
||||
[disableClose]="false"
|
||||
(closed)="onClosed($event)"
|
||||
>
|
||||
<div appLayoutsDefaultDialog="header">
|
||||
{{ data.title }}
|
||||
</div>
|
||||
<div class="dialog-body" appLayoutsDefaultDialog="body">
|
||||
<mat-horizontal-stepper
|
||||
fxFlexFill
|
||||
[linear]="true"
|
||||
#stepper
|
||||
[selectedIndex]="currentStep"
|
||||
>
|
||||
<mat-step label="Step 1">
|
||||
<div class="ucap-dialog-group-manage-container">
|
||||
<div class="group-name">
|
||||
<span class="sub-title">{{
|
||||
data.groupBuddyList.group.name
|
||||
}}</span>
|
||||
<button
|
||||
mat-button
|
||||
(click)="onAdd(stepper)"
|
||||
aria-label="대화상대 추가"
|
||||
>
|
||||
<mat-icon class="material-icons-outlined">person_add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="ucap-dialog-app-group-profile-list">
|
||||
<perfect-scrollbar style="width: 100%; height: 100%;">
|
||||
<app-group-profile-list-item-02
|
||||
*ngFor="let userInfo of this.data.groupBuddyList.buddyList"
|
||||
[userInfo]="userInfo"
|
||||
[isDialog]="true"
|
||||
[checked]="getCheckedUser(userInfo)"
|
||||
[checkable]="true"
|
||||
(changeCheckUser)="onToggleCheck($event)"
|
||||
></app-group-profile-list-item-02>
|
||||
</perfect-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</mat-step>
|
||||
<mat-step label="Step 2">
|
||||
<div class="ucap-dialog-app-group-select-user">
|
||||
<ng-template #dialogContainer></ng-template>
|
||||
<!-- <ng-container
|
||||
*ngIf="currentStep > 0"
|
||||
[ngSwitch]="selectContentType"
|
||||
></ng-container>
|
||||
<div *ngSwitchCase="ManageContentType.Add"></div> -->
|
||||
</div>
|
||||
<div class="ucap-dialog-organization-profile-selection">
|
||||
<ucap-organization-profile-selection-01
|
||||
[userInfoList]="selectedUserList"
|
||||
[removableFor]="removableForSelection"
|
||||
[colorFor]="colorForSelection"
|
||||
(removed)="onRemovedProfileSelection($event)"
|
||||
class="ucap-organization-selected-list"
|
||||
>
|
||||
<ng-template ucapOrganizationProfileSelection01Header>
|
||||
선택된 대화상대 (<span class="number">{{
|
||||
selectedUserList.length
|
||||
}}</span
|
||||
>)
|
||||
</ng-template>
|
||||
</ucap-organization-profile-selection-01>
|
||||
</div>
|
||||
</mat-step>
|
||||
</mat-horizontal-stepper>
|
||||
</div>
|
||||
|
||||
<div appLayoutsDefaultDialog="action" class="btn-box">
|
||||
<div *ngIf="currentStep === 0">
|
||||
<button mat-button mat-stroked-button (click)="onDelete(stepper)">
|
||||
삭제
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
class="bg-primary-darkest"
|
||||
(click)="onUpdateMember(stepper, GroupUserDialaogType.Copy)"
|
||||
>
|
||||
그룹복사
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
class="bg-primary-darkest"
|
||||
(click)="onUpdateMember(stepper, GroupUserDialaogType.Move)"
|
||||
>
|
||||
그룹이동
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="currentStep > 0">
|
||||
<button mat-button mat-stroked-button (click)="onCnacel(stepper)">
|
||||
취소
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
class="bg-primary-darkest"
|
||||
(click)="onConfirm(stepper)"
|
||||
>
|
||||
완료
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</app-layouts-default-dialog>
|
||||
</div>
|
394
documents/업무/6월/3째주/backup/manage.dialog.component.ts
Normal file
394
documents/업무/6월/3째주/backup/manage.dialog.component.ts
Normal file
|
@ -0,0 +1,394 @@
|
|||
import { Subject, of } from 'rxjs';
|
||||
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Inject,
|
||||
ComponentFactoryResolver,
|
||||
ViewChild,
|
||||
ViewContainerRef,
|
||||
ComponentRef
|
||||
} from '@angular/core';
|
||||
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import {
|
||||
MatDialogRef,
|
||||
MAT_DIALOG_DATA,
|
||||
MatDialog
|
||||
} from '@angular/material/dialog';
|
||||
|
||||
import { UserInfo, GroupDetailData } from '@ucap/protocol-sync';
|
||||
import { UserInfoSS, UserInfoF, UserInfoDN } from '@ucap/protocol-query';
|
||||
import { UserInfo as RoomUserInfo } from '@ucap/protocol-room';
|
||||
import { MatStepper } from '@angular/material/stepper';
|
||||
import { I18nService } from '@ucap/ng-i18n';
|
||||
import { GroupActions } from '@ucap/ng-store-group';
|
||||
import {
|
||||
AlertDialogComponent,
|
||||
AlertDialogData,
|
||||
AlertDialogResult,
|
||||
ConfirmDialogComponent,
|
||||
ConfirmDialogResult,
|
||||
ConfirmDialogData
|
||||
} from '@ucap/ng-ui';
|
||||
import { SelectUserSectionComponent } from '../components/select-user.section.component';
|
||||
import { take, map, catchError } from 'rxjs/operators';
|
||||
import { SelectGroupSectionComponent } from '../components/select-group.section.component';
|
||||
import { SelectUserDialogType, GroupUserDialaogType } from '@app/types';
|
||||
|
||||
export type UserInfoTypes =
|
||||
| UserInfo
|
||||
| UserInfoSS
|
||||
| UserInfoF
|
||||
| UserInfoDN
|
||||
| RoomUserInfo;
|
||||
|
||||
export enum ManageContentType {
|
||||
Add = 'ADD_COMPONENT',
|
||||
Copy = 'COPY_COMPONENT',
|
||||
Move = 'MOVE_COMPONENT',
|
||||
Delete = 'DELETE_COMPONENT',
|
||||
None = 'NONE_COMPONENT'
|
||||
}
|
||||
export interface ManageDialogData {
|
||||
title: string;
|
||||
groupBuddyList?: { group: GroupDetailData; buddyList: UserInfo[] };
|
||||
}
|
||||
export interface ManageDialogResult {
|
||||
type: GroupUserDialaogType;
|
||||
groupName: string;
|
||||
group?: GroupDetailData;
|
||||
selelctUserList?: UserInfoTypes[];
|
||||
selectGroupList?: GroupDetailData[];
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-dialog-group-manage',
|
||||
templateUrl: './manage.dialog.component.html',
|
||||
styleUrls: ['./manage.dialog.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ManageDialogComponent implements OnInit, OnDestroy {
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<ManageDialogData, ManageDialogResult>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: ManageDialogData,
|
||||
private changeDetectorRef: ChangeDetectorRef,
|
||||
private store: Store<any>,
|
||||
private i18nService: I18nService,
|
||||
public dialog: MatDialog,
|
||||
private cfResolver: ComponentFactoryResolver
|
||||
) {}
|
||||
|
||||
@ViewChild('dialogContainer', { static: true, read: ViewContainerRef })
|
||||
dialogContainer: ViewContainerRef;
|
||||
|
||||
componentRef: ComponentRef<any>;
|
||||
private ngOnDestroySubject: Subject<void>;
|
||||
currentType: GroupUserDialaogType;
|
||||
SelectUserDialogType = SelectUserDialogType;
|
||||
GroupUserDialaogType = GroupUserDialaogType;
|
||||
|
||||
currentStep = 0;
|
||||
groupName = '';
|
||||
|
||||
ManageContentType = ManageContentType;
|
||||
|
||||
selectedUserList: UserInfoTypes[];
|
||||
selectedGroupList: GroupDetailData[];
|
||||
selectContentType: ManageContentType;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.ngOnDestroySubject = new Subject();
|
||||
|
||||
this.selectedUserList = [];
|
||||
this.selectContentType = ManageContentType.None;
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (!!this.ngOnDestroySubject) {
|
||||
this.ngOnDestroySubject.next();
|
||||
this.ngOnDestroySubject.complete();
|
||||
}
|
||||
}
|
||||
|
||||
onClosed(event: MouseEvent): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
onDelete(stepper: MatStepper) {
|
||||
if (
|
||||
!!this.selectedUserList &&
|
||||
this.selectedUserList.length > 0 &&
|
||||
this.currentStep === 0
|
||||
) {
|
||||
let titleStr = '';
|
||||
this.selectedUserList.forEach((user, idx) => {
|
||||
let userTitle = user.name + ' ' + user.grade;
|
||||
if (idx < this.selectedUserList.length) {
|
||||
userTitle = userTitle + ', ';
|
||||
}
|
||||
titleStr = titleStr.concat('', userTitle);
|
||||
});
|
||||
const dialogRef = this.dialog.open<
|
||||
ConfirmDialogComponent,
|
||||
ConfirmDialogData,
|
||||
ConfirmDialogResult
|
||||
>(ConfirmDialogComponent, {
|
||||
panelClass: 'min-create-dialog',
|
||||
data: {
|
||||
title: '동료 삭제',
|
||||
html: titleStr + '을 삭제하시겠습니까?'
|
||||
}
|
||||
});
|
||||
dialogRef
|
||||
.afterClosed()
|
||||
.pipe(
|
||||
take(1),
|
||||
map((result) => {
|
||||
if (!!result && result.choice) {
|
||||
const trgtUserSeq: string[] = [];
|
||||
|
||||
this.selectedUserList.forEach((userIfno) => {
|
||||
const tempSeqs = this.data.groupBuddyList.group.userSeqs.filter(
|
||||
(seq) => seq !== userIfno.seq
|
||||
);
|
||||
|
||||
tempSeqs.map((seq) => trgtUserSeq.push(seq));
|
||||
});
|
||||
|
||||
console.log(trgtUserSeq);
|
||||
|
||||
this.store.dispatch(
|
||||
GroupActions.updateMember({
|
||||
targetGroup: this.data.groupBuddyList.group,
|
||||
targetUserSeqs: trgtUserSeq
|
||||
})
|
||||
);
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}),
|
||||
catchError((err) => {
|
||||
return of(err);
|
||||
})
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
onUpdateMember(stepper: MatStepper, type: GroupUserDialaogType) {
|
||||
this.dialogContainer.clear();
|
||||
this.currentType = type;
|
||||
this.selectedGroupList = [];
|
||||
const isMemberMove = type === GroupUserDialaogType.Copy ? false : true;
|
||||
|
||||
const factory = this.cfResolver.resolveComponentFactory(
|
||||
SelectGroupSectionComponent
|
||||
);
|
||||
|
||||
this.componentRef = this.dialogContainer.createComponent(factory);
|
||||
const cpInstance = this.componentRef.instance;
|
||||
// cpInstance.title = title;
|
||||
cpInstance.isMemberMove = isMemberMove;
|
||||
cpInstance.isDialog = true;
|
||||
cpInstance.checkable = true;
|
||||
cpInstance.curGroup = this.data.groupBuddyList.group;
|
||||
cpInstance.selectedGroupList = this.selectedGroupList;
|
||||
cpInstance.selectedUserList = this.selectedUserList;
|
||||
cpInstance.changeUserList.subscribe(
|
||||
(datas: { checked: boolean; userInfo: UserInfoSS }[]) => {
|
||||
this.changeSelectedUserList(datas);
|
||||
cpInstance.selectedUserList = this.selectedUserList;
|
||||
}
|
||||
);
|
||||
cpInstance.changeGroupList.subscribe((data: { group: GroupDetailData }) => {
|
||||
if (
|
||||
this.selectedGroupList.filter((g) => g.seq === data.group.seq)
|
||||
.length === 0
|
||||
) {
|
||||
this.selectedGroupList = [...this.selectedGroupList, data.group];
|
||||
} else {
|
||||
this.selectedGroupList = this.selectedGroupList.filter(
|
||||
(g) => g.seq !== data.group.seq
|
||||
);
|
||||
}
|
||||
cpInstance.selectedGroupList = this.selectedGroupList;
|
||||
});
|
||||
cpInstance.changeGroupName.subscribe((groupName) => {
|
||||
this.groupName = groupName;
|
||||
});
|
||||
this.currentStep++;
|
||||
stepper.next();
|
||||
}
|
||||
|
||||
onAdd(stepper: MatStepper) {
|
||||
this.dialogContainer.clear();
|
||||
this.currentType = GroupUserDialaogType.Add;
|
||||
|
||||
const factory = this.cfResolver.resolveComponentFactory(
|
||||
SelectUserSectionComponent
|
||||
);
|
||||
|
||||
this.componentRef = this.dialogContainer.createComponent(factory);
|
||||
const cpInstance = this.componentRef.instance;
|
||||
cpInstance.isDialog = true;
|
||||
cpInstance.checkable = true;
|
||||
cpInstance.selectedUserList = this.data.groupBuddyList.buddyList;
|
||||
|
||||
// const cpElement: HTMLElement = this.componentRef.location.nativeElement;
|
||||
// cpElement.style.height = '400px';
|
||||
|
||||
cpInstance.toggleCheckUser.subscribe(
|
||||
(datas: { checked: boolean; userInfo: UserInfoSS }[]) => {
|
||||
this.changeSelectedUserList(datas);
|
||||
cpInstance.selectedUserList = this.selectedUserList;
|
||||
}
|
||||
);
|
||||
|
||||
this.currentStep++;
|
||||
stepper.next();
|
||||
}
|
||||
|
||||
onChangeUserList(datas: { checked: boolean; userInfo: UserInfoSS }[]) {
|
||||
this.changeSelectedUserList(datas);
|
||||
}
|
||||
|
||||
private changeSelectedUserList(
|
||||
datas: {
|
||||
checked: boolean;
|
||||
userInfo: UserInfoSS;
|
||||
}[]
|
||||
) {
|
||||
if (!datas || 0 === datas.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pushs: UserInfoSS[] = [];
|
||||
const pops: UserInfoSS[] = [];
|
||||
|
||||
datas.forEach((d) => {
|
||||
const i = this.selectedUserList.findIndex(
|
||||
(u) => u.seq === d.userInfo.seq
|
||||
);
|
||||
if (d.checked) {
|
||||
if (-1 === i) {
|
||||
pushs.push(d.userInfo);
|
||||
}
|
||||
} else {
|
||||
if (-1 < i) {
|
||||
pops.push(d.userInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (0 < pushs.length) {
|
||||
this.selectedUserList = [...this.selectedUserList, ...pushs];
|
||||
}
|
||||
|
||||
if (0 < pops.length) {
|
||||
this.selectedUserList = this.selectedUserList.filter(
|
||||
(u) => -1 === pops.findIndex((p) => p.seq === u.seq)
|
||||
);
|
||||
}
|
||||
}
|
||||
onCnacel(stepper: MatStepper) {
|
||||
if (!!this.selectedUserList && this.selectedUserList.length > 0) {
|
||||
this.selectedUserList = [];
|
||||
}
|
||||
this.currentStep--;
|
||||
stepper.previous();
|
||||
}
|
||||
onConfirm(stepper: MatStepper) {
|
||||
switch (this.currentType) {
|
||||
case GroupUserDialaogType.Add:
|
||||
{
|
||||
if (!!this.selectedUserList && this.selectedUserList.length > 0) {
|
||||
this.doAction();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GroupUserDialaogType.Copy:
|
||||
case GroupUserDialaogType.Move:
|
||||
{
|
||||
if (
|
||||
!!this.selectedUserList &&
|
||||
this.selectedUserList.length === 0 &&
|
||||
this.groupName === ''
|
||||
) {
|
||||
this.dialog.open<
|
||||
AlertDialogComponent,
|
||||
AlertDialogData,
|
||||
AlertDialogResult
|
||||
>(AlertDialogComponent, {
|
||||
panelClass: 'min-create-dialog',
|
||||
data: {
|
||||
title: 'Error',
|
||||
html: '선택된 유저가 없습니다.'
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.doAction();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
doAction() {
|
||||
this.dialogContainer.clear();
|
||||
if (!!this.groupName && this.groupName.trim().localeCompare('') !== 0) {
|
||||
this.currentType = GroupUserDialaogType.Create;
|
||||
} else {
|
||||
this.groupName = undefined;
|
||||
}
|
||||
|
||||
this.dialogRef.close({
|
||||
type: this.currentType,
|
||||
groupName: this.groupName,
|
||||
group: this.data.groupBuddyList.group,
|
||||
selelctUserList: this.selectedUserList,
|
||||
selectGroupList: this.selectedGroupList
|
||||
});
|
||||
}
|
||||
|
||||
/** 개별 체크여부 */
|
||||
getCheckedUser(userInfo: UserInfoSS) {
|
||||
if (!!this.selectedUserList && this.selectedUserList.length > 0) {
|
||||
return (
|
||||
this.selectedUserList.filter(
|
||||
(item) => (item.seq as any) === (userInfo.seq as any)
|
||||
).length > 0
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
onToggleCheck(data: { checked: boolean; userInfo: UserInfoSS }) {
|
||||
this.changeSelectedUserList([data]);
|
||||
}
|
||||
|
||||
onRemovedProfileSelection(userInfo: UserInfo) {
|
||||
const i = this.selectedUserList.findIndex(
|
||||
(u) => (u.seq as any) === (userInfo.seq as any)
|
||||
);
|
||||
|
||||
if (-1 < i) {
|
||||
this.selectedUserList = this.selectedUserList.filter(
|
||||
(u) => (u.seq as any) !== (userInfo.seq as any)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
removableForSelection = (userInfo: UserInfo) => {
|
||||
return true;
|
||||
};
|
||||
|
||||
colorForSelection = (userInfo: UserInfo) => {
|
||||
return 'accent';
|
||||
};
|
||||
}
|
510
documents/업무/6월/3째주/temp.ts
Normal file
510
documents/업무/6월/3째주/temp.ts
Normal file
|
@ -0,0 +1,510 @@
|
|||
import { Subject } from 'rxjs';
|
||||
import { takeUntil, take } from 'rxjs/operators';
|
||||
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Input,
|
||||
Output,
|
||||
EventEmitter,
|
||||
NgZone
|
||||
} from '@angular/core';
|
||||
|
||||
import { Store, select } from '@ngrx/store';
|
||||
|
||||
import { SortOrder } from '@ucap/core';
|
||||
|
||||
import { VersionInfo2Response } from '@ucap/api-public';
|
||||
import { LoginResponse } from '@ucap/protocol-authentication';
|
||||
import {
|
||||
UserInfoSS,
|
||||
DeptSearchType,
|
||||
DeptUserRequest
|
||||
} from '@ucap/protocol-query';
|
||||
|
||||
import { LogService } from '@ucap/ng-logger';
|
||||
import {
|
||||
LoginSelector,
|
||||
ConfigurationSelector
|
||||
} from '@ucap/ng-store-authentication';
|
||||
import { QueryProtocolService } from '@ucap/ng-protocol-query';
|
||||
import {
|
||||
DepartmentActions,
|
||||
DepartmentSelector,
|
||||
PresenceActions
|
||||
} from '@ucap/ng-store-organization';
|
||||
|
||||
import { SearchData } from '../models/search-data';
|
||||
|
||||
const DEPT_ORDER_PROPERTY = 'order';
|
||||
|
||||
interface CheckedInfo {
|
||||
checked: boolean;
|
||||
userInfo: UserInfoSS;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-organization-profile-list',
|
||||
templateUrl: './profile-list.component.html',
|
||||
styleUrls: ['./profile-list.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ProfileListComponent implements OnInit, OnDestroy {
|
||||
@Input()
|
||||
set searchData(data: SearchData) {
|
||||
if (!this.loginRes) {
|
||||
this._searchData = data;
|
||||
return;
|
||||
}
|
||||
this.searchMember(data);
|
||||
}
|
||||
// tslint:disable-next-line: variable-name
|
||||
private _searchData: SearchData;
|
||||
|
||||
@Input()
|
||||
selectedUser: UserInfoSS[];
|
||||
|
||||
@Input()
|
||||
/** Cycle order of sorting by use ascending: undefined -> true -> false */
|
||||
set sortOrder(value: SortOrder) {
|
||||
this._sortOrder = value;
|
||||
this.userInfos = this.sort(this.userInfos);
|
||||
}
|
||||
get sortOrder() {
|
||||
return this._sortOrder;
|
||||
}
|
||||
// tslint:disable-next-line: variable-name
|
||||
_sortOrder: SortOrder = {
|
||||
property: 'name',
|
||||
ascending: undefined
|
||||
};
|
||||
|
||||
@Output()
|
||||
searched: EventEmitter<UserInfoSS[]> = new EventEmitter();
|
||||
|
||||
@Output()
|
||||
changedCheck: EventEmitter<CheckedInfo[]> = new EventEmitter();
|
||||
|
||||
set userInfos(userInfos: UserInfoSS[]) {
|
||||
this._userInfos = userInfos;
|
||||
this.searched.emit(userInfos);
|
||||
}
|
||||
get userInfos() {
|
||||
return this._userInfos;
|
||||
}
|
||||
// tslint:disable-next-line: variable-name
|
||||
_userInfos: UserInfoSS[] = [];
|
||||
|
||||
loginRes: LoginResponse;
|
||||
versionInfo2Res: VersionInfo2Response;
|
||||
|
||||
processing = false;
|
||||
|
||||
private ngOnDestroySubject: Subject<void> = new Subject();
|
||||
private myDeptDestroySubject: Subject<void>;
|
||||
|
||||
constructor(
|
||||
private queryProtocolService: QueryProtocolService,
|
||||
private store: Store<any>,
|
||||
private changeDetectorRef: ChangeDetectorRef,
|
||||
private logService: LogService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.store
|
||||
.pipe(
|
||||
takeUntil(this.ngOnDestroySubject),
|
||||
select(ConfigurationSelector.versionInfo2Response)
|
||||
)
|
||||
.subscribe((versionInfo2Res) => {
|
||||
this.versionInfo2Res = versionInfo2Res;
|
||||
});
|
||||
|
||||
this.store
|
||||
.pipe(takeUntil(this.ngOnDestroySubject), select(LoginSelector.loginRes))
|
||||
.subscribe((loginRes) => {
|
||||
this.loginRes = loginRes;
|
||||
if (!!this._searchData) {
|
||||
this.searchMember(this._searchData);
|
||||
this._searchData = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (!!this.ngOnDestroySubject) {
|
||||
this.ngOnDestroySubject.next();
|
||||
this.ngOnDestroySubject.complete();
|
||||
}
|
||||
}
|
||||
|
||||
checkAll() {
|
||||
if (!this.userInfos || 0 === this.userInfos.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const checked: CheckedInfo[] = [];
|
||||
this.userInfos.forEach((u) => {
|
||||
checked.push({
|
||||
checked: true,
|
||||
userInfo: u
|
||||
});
|
||||
});
|
||||
this.changedCheck.emit(checked);
|
||||
}
|
||||
|
||||
uncheckAll() {
|
||||
if (!this.userInfos || 0 === this.userInfos.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const unchecked: CheckedInfo[] = [];
|
||||
this.userInfos.forEach((u) => {
|
||||
unchecked.push({
|
||||
checked: false,
|
||||
userInfo: u
|
||||
});
|
||||
});
|
||||
this.changedCheck.emit(unchecked);
|
||||
}
|
||||
|
||||
/** 개별 체크여부 */
|
||||
getCheckedUser(userInfo: UserInfoSS) {
|
||||
if (!!this.selectedUser && this.selectedUser.length > 0) {
|
||||
return (
|
||||
this.selectedUser.filter((item) => item.seq === userInfo.seq).length > 0
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 개별선택(토글) 이벤트 */
|
||||
onChangeCheckUser(param: { checked: boolean; userInfo: UserInfoSS }) {
|
||||
this.changedCheck.emit([param]);
|
||||
}
|
||||
|
||||
onOpenProfile(userInfo: UserInfoSS): void {
|
||||
alert('Open Profile');
|
||||
}
|
||||
|
||||
private getMyDeptMember() {
|
||||
this.myDeptDestroySubject = new Subject();
|
||||
|
||||
const req: DeptUserRequest = {
|
||||
divCd: 'ORG',
|
||||
companyCode: this.loginRes.companyCode,
|
||||
seq: this.loginRes.departmentCode,
|
||||
search: '',
|
||||
searchRange: DeptSearchType.All,
|
||||
senderCompanyCode: this.loginRes.companyCode,
|
||||
senderEmployeeType: this.loginRes.userInfo.employeeType
|
||||
};
|
||||
|
||||
this.processing = true;
|
||||
|
||||
this.store
|
||||
.pipe(
|
||||
takeUntil(this.myDeptDestroySubject),
|
||||
select(DepartmentSelector.myDepartmentUserInfoList)
|
||||
)
|
||||
.subscribe(
|
||||
(myDepartmentUserInfoList) => {
|
||||
if (!myDepartmentUserInfoList) {
|
||||
this.store.dispatch(DepartmentActions.myDeptUser({ req }));
|
||||
return;
|
||||
}
|
||||
this._refreshUserInfos(myDepartmentUserInfoList);
|
||||
|
||||
this.myDeptDestroySubject.next();
|
||||
this.myDeptDestroySubject.complete();
|
||||
this.myDeptDestroySubject = undefined;
|
||||
},
|
||||
(error) => {},
|
||||
() => {
|
||||
this.processing = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private sort(userInfos: UserInfoSS[]): UserInfoSS[] {
|
||||
if (!userInfos || 0 === userInfos.length) {
|
||||
return userInfos;
|
||||
}
|
||||
|
||||
const property = this.sortOrder.property;
|
||||
const ascending = this.sortOrder.ascending;
|
||||
let deptA: any;
|
||||
let deptB: any;
|
||||
let c: any;
|
||||
let d: any;
|
||||
|
||||
return userInfos.slice().sort((a, b) => {
|
||||
try {
|
||||
deptA = a[DEPT_ORDER_PROPERTY];
|
||||
deptB = b[DEPT_ORDER_PROPERTY];
|
||||
|
||||
if (undefined === ascending) {
|
||||
return deptA < deptB
|
||||
? -1
|
||||
: deptA > deptB
|
||||
? 1
|
||||
: a[property] < b[property]
|
||||
? -1
|
||||
: a[property] > b[property]
|
||||
? 1
|
||||
: 0;
|
||||
}
|
||||
|
||||
c = ascending ? a[property] : b[property];
|
||||
d = ascending ? b[property] : a[property];
|
||||
|
||||
return c < d ? -1 : c > d ? 1 : 0;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private searchMember(searchData: SearchData) {
|
||||
if (
|
||||
!searchData ||
|
||||
(!searchData.bySearch && undefined === searchData.deptSeq)
|
||||
) {
|
||||
this.getMyDeptMember();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!!this.myDeptDestroySubject) {
|
||||
this.myDeptDestroySubject.next();
|
||||
this.myDeptDestroySubject.complete();
|
||||
this.myDeptDestroySubject = undefined;
|
||||
}
|
||||
|
||||
let req: DeptUserRequest;
|
||||
if (searchData.bySearch) {
|
||||
req = {
|
||||
divCd: 'ORGS',
|
||||
companyCode: searchData.companyCode,
|
||||
searchRange: DeptSearchType.All,
|
||||
search: searchData.searchWord,
|
||||
senderCompanyCode: this.loginRes.userInfo.companyCode,
|
||||
senderEmployeeType: this.loginRes.userInfo.employeeType
|
||||
};
|
||||
} else {
|
||||
req = {
|
||||
divCd: 'ORG',
|
||||
companyCode: this.loginRes.companyCode,
|
||||
seq: Number(searchData.deptSeq),
|
||||
search: '',
|
||||
searchRange: DeptSearchType.All,
|
||||
senderCompanyCode: this.loginRes.companyCode,
|
||||
senderEmployeeType: this.loginRes.userInfo.employeeType
|
||||
};
|
||||
}
|
||||
|
||||
this.processing = true;
|
||||
this.queryProtocolService
|
||||
.deptUser(req)
|
||||
.pipe(take(1))
|
||||
.subscribe(
|
||||
(data) => {
|
||||
this._refreshUserInfos(data.userInfos);
|
||||
},
|
||||
(error) => {},
|
||||
() => {
|
||||
this.processing = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private _refreshUserInfos(userInfos: UserInfoSS[]) {
|
||||
this.userInfos = this.sort(userInfos);
|
||||
|
||||
// 검색 결과에 따른 프레즌스 조회.
|
||||
const userSeqList: string[] = userInfos.map((user) => user.seq);
|
||||
|
||||
if (userSeqList.length > 0) {
|
||||
this.store.dispatch(
|
||||
PresenceActions.bulkInfo({
|
||||
divCd: 'orgSrch',
|
||||
userSeqs: userSeqList
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Input
|
||||
} from '@angular/core';
|
||||
|
||||
import { Store, select } from '@ngrx/store';
|
||||
|
||||
import { VersionInfo2Response } from '@ucap/api-public';
|
||||
import { UserInfoSS } from '@ucap/protocol-query';
|
||||
|
||||
import { LogService } from '@ucap/ng-logger';
|
||||
import { PresenceSelector } from '@ucap/ng-store-organization';
|
||||
import { StatusBulkInfo } from '@ucap/protocol-status';
|
||||
|
||||
@Component({
|
||||
selector: 'app-organization-profile-image-01',
|
||||
templateUrl: './profile-image-01.component.html',
|
||||
styleUrls: ['./profile-image-01.component.scss']
|
||||
})
|
||||
export class ProfileImage01Component implements OnInit, OnDestroy {
|
||||
@Input()
|
||||
set userInfo(userInfo: UserInfoSS) {
|
||||
this._userInfo = userInfo;
|
||||
}
|
||||
get userInfo(): UserInfoSS {
|
||||
return this._userInfo;
|
||||
}
|
||||
_userInfo: UserInfoSS;
|
||||
|
||||
@Input()
|
||||
versionInfo: VersionInfo2Response;
|
||||
|
||||
presenceInfo: StatusBulkInfo;
|
||||
|
||||
private ngOnDestroySubject: Subject<void> = new Subject();
|
||||
|
||||
constructor(
|
||||
private store: Store<any>,
|
||||
private changeDetectorRef: ChangeDetectorRef,
|
||||
private logService: LogService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.store
|
||||
.pipe(
|
||||
takeUntil(this.ngOnDestroySubject),
|
||||
select(
|
||||
PresenceSelector.selectStatusBulkInfo,
|
||||
Number(this.userInfo?.seq)
|
||||
)
|
||||
)
|
||||
.subscribe((status) => {
|
||||
this.presenceInfo = status;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (!!this.ngOnDestroySubject) {
|
||||
this.ngOnDestroySubject.next();
|
||||
this.ngOnDestroySubject.complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
label,
|
||||
contextmenu,
|
||||
profile,
|
||||
group
|
||||
confirm,
|
||||
error,
|
||||
|
||||
{
|
||||
"label": {
|
||||
"organization": "조직도",
|
||||
"selectedUsers": "선택한 대화상대",
|
||||
"addGroup": "그룹추가",
|
||||
"chat": "대화",
|
||||
"message": "쪽지",
|
||||
"call": "전화",
|
||||
"videoConference": "화상",
|
||||
"searchResult": "검색결과",
|
||||
"sortName": "이름"
|
||||
},
|
||||
"presence": {
|
||||
"offline": "오프라인",
|
||||
"online": "온라인",
|
||||
"away": "부재중",
|
||||
"statusMessage1": "다른용무중",
|
||||
"statusMessage2": "회의중",
|
||||
"statusMessage3": "집중근무중"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
"label": {
|
||||
"confirmRemoveBuddy": "선택한 멤버를 삭제하시겠습니까?\n해당 그룹에서만 선택하신 멤버가 삭제됩니다."
|
||||
},
|
||||
"category": {
|
||||
"favorite": "즐겨찾기",
|
||||
"default": "기본",
|
||||
"myDept": "소속부서"
|
||||
},
|
||||
"moreMenu": {
|
||||
"show": {
|
||||
"all": "전체 보기",
|
||||
"onlineBuddy": "접속한 동료만 보기",
|
||||
"onOff": "온/오프라인 보기"
|
||||
},
|
||||
"group": {
|
||||
"addNew": "새 그룹 추가",
|
||||
"expandMore": "그룹 전체 열기",
|
||||
"expandLess": "그룹 전체 닫기",
|
||||
"changeOrder": "그룹 순서 바꾸기",
|
||||
"startChatWithGroup": "그룹 대화하기",
|
||||
"sendMessageToGroup": "그룹 쪽지 보내기",
|
||||
"groupMemberManagement": "그룹 멤버 관리",
|
||||
"changeGroupName": "그룹 이름 바꾸기",
|
||||
"removeGroup": "그룹 삭제"
|
||||
},
|
||||
"profile": {
|
||||
"open": "프로필 보기",
|
||||
"unfavorite": "즐겨찾기 해제",
|
||||
"favorite": "즐겨찾기 등록",
|
||||
"nickname": "닉네임 설정",
|
||||
"moveBuddy": "대화상대 이동",
|
||||
"copyBuddy": "대화상대 복사",
|
||||
"removeBuddy": "이 그룹에서 삭제"
|
||||
},
|
||||
"confirm": {
|
||||
"removeGroup": "그룹을 삭제하시겠습니까?<br/>그룹 멤버는 해당 그룹에서만 삭제됩니다."
|
||||
},
|
||||
"error": {
|
||||
"label": "그룹 에러",
|
||||
"requireName": "그룹명은 필수입력입니다.",
|
||||
"invalidName": "유효하지 않은 그룹명입니다.",
|
||||
"invalidSelectedUser": "선택된 유저가 존재하지 않습니다."
|
||||
}
|
||||
},
|
||||
|
||||
"profile": {
|
||||
"labels": {
|
||||
"myProfile": "내 프로필",
|
||||
"company": "회사",
|
||||
"email": "이메일",
|
||||
"linePhoneNumber": "사무실",
|
||||
"mobilePhoneNumber": "핸드폰",
|
||||
"department": "부서",
|
||||
"mytalk": "MyTalk",
|
||||
"setting": "환경설정",
|
||||
"chat": "대화",
|
||||
"sms": "SMS",
|
||||
"videoConference": "화상회의",
|
||||
"message": "쪽지",
|
||||
"nickname": "닉네임 미설정"
|
||||
},
|
||||
"fields": {
|
||||
"intro": "인트로"
|
||||
},
|
||||
"errors": {}
|
||||
}
|
||||
}
|
40
documents/업무/6월/4째주/0622.txt
Normal file
40
documents/업무/6월/4째주/0622.txt
Normal file
|
@ -0,0 +1,40 @@
|
|||
기획 문의
|
||||
그룹복사, 그룹이동 시 그룹 이름과 사용자들을 선택 시 -> 그룹생성으로 간주? 아니면 그룹생성 그룹 복사 둘다? 문의
|
||||
|
||||
<app-group-expansion
|
||||
#appGroupExpansion
|
||||
[showType]="showType"
|
||||
(clicked)="onClickUser($event)"
|
||||
(selectGroupMenu)="onSelectGroupMenu($event)"
|
||||
(selectProfileMenu)="onSelectProfileMenu($event)"
|
||||
(floatingProfileMenu)="onFloatingProfileMenu($event)"
|
||||
(profileMenu)="onProfileMenu($event)"
|
||||
>
|
||||
|
||||
|
||||
_ngcontent-laf-c391
|
||||
|
||||
<div _ngcontent-laf-c391="" fxflex="1 1 auto" ng-reflect-fx-flex="1 1 auto" style="flex: 1 1
|
||||
auto;box-sizing: border-box;"><app-organization-profile-list _ngcontent-laf-c391=""
|
||||
_nghost-laf-c296="" ng-reflect-search-data="[object Object]"
|
||||
ng-reflect-selected-user="[object Object],[object Object"
|
||||
ng-reflect-sort-order="[object Object]">
|
||||
|
||||
|
||||
{StatusCode: "500", ErrorMessage: "empty UserSeq", ProfileURL: "", ProfileSubDir: "", Intro: ""}
|
||||
ErrorMessage: "empty UserSeq"
|
||||
Intro: ""
|
||||
ProfileSubDir: ""
|
||||
ProfileURL: ""
|
||||
StatusCode: "500"
|
||||
|
||||
|
||||
554, 773966
|
||||
|
||||
|
||||
|
||||
|
||||
701307
|
||||
476791
|
||||
8890
|
||||
677714
|
102
documents/업무/6월/4째주/0623.txt
Normal file
102
documents/업무/6월/4째주/0623.txt
Normal file
|
@ -0,0 +1,102 @@
|
|||
프로필 이미지
|
||||
리듀서
|
||||
loginRes 업데이트
|
||||
액션
|
||||
프로필 변경 액션 정의
|
||||
notification 액션 정의
|
||||
|
||||
이펙트
|
||||
대화방 프로필 이미지 업데이트
|
||||
대상 RoomType: bot, single
|
||||
대화방 유저 리스트 프로필 이미지 업데이트
|
||||
|
||||
대화방 리스트, 대화방 유저 프로필 이미지
|
||||
roomUsersShort.userInfos
|
||||
|
||||
동료 프로필 이미지 업데이트
|
||||
BuddySelector.buddies
|
||||
|
||||
동료, 대화방 프로필 이미지 스테이트 확인
|
||||
|
||||
자신 프로필 변경
|
||||
스토어 변경
|
||||
동료 프로필 변경 알림
|
||||
동료, 대화방 프로필 변경
|
||||
|
||||
프로필 변경 데이터
|
||||
|
||||
|
||||
updateUserInfoNoti
|
||||
|
||||
updateProfileImageNoti
|
||||
|
||||
updateBuddyProfile
|
||||
|
||||
대화방
|
||||
user seq find -> room info -> userList||userShort -> update
|
||||
|
||||
|
||||
|
||||
this.store.pipe(select(RoomSelector.rooms)),
|
||||
this.store.pipe(select(RoomSelector.roomUsers)),
|
||||
this.store.pipe(select(RoomSelector.roomUsersShort))
|
||||
|
||||
roomUsers = (roomUsers || []).filter(
|
||||
(userMap) =>
|
||||
rooms.findIndex((roomInfo) => roomInfo.roomId === userMap.roomId) >
|
||||
-1
|
||||
);
|
||||
roomUsersShort = (roomUsersShort || []).filter(
|
||||
(userMap) =>
|
||||
rooms.findIndex((roomInfo) => roomInfo.roomId === userMap.roomId) >
|
||||
-1
|
||||
);
|
||||
|
||||
const recommendedWordList = [];
|
||||
for (const r of rooms) {
|
||||
if (!!r.roomName && '' !== r.roomName.trim()) {
|
||||
recommendedWordList.push(r.roomName);
|
||||
}
|
||||
}
|
||||
for (const ru of roomUsers) {
|
||||
for (const u of ru.userInfos) {
|
||||
if (!!this.loginRes && u.seq !== Number(this.loginRes.userSeq)) {
|
||||
if (!!u.name && '' !== u.name.trim() && u.isJoinRoom) {
|
||||
recommendedWordList.push(u.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const ru of roomUsersShort) {
|
||||
for (const u of ru.userInfos) {
|
||||
if (!!this.loginRes && u.seq !== Number(this.loginRes.userSeq)) {
|
||||
if (!!u.name && '' !== u.name.trim() && u.isJoinRoom) {
|
||||
recommendedWordList.push(u.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.recommendedWordList = [
|
||||
...recommendedWordList.filter(
|
||||
(item, index) => recommendedWordList.indexOf(item) === index
|
||||
)
|
||||
];
|
||||
|
||||
auth 12
|
||||
group 17
|
||||
org 12
|
||||
chat 44
|
||||
|
||||
|
||||
const profile = {
|
||||
userSeq: this.loginRes.userSeq + '',
|
||||
deviceType: 'W',
|
||||
token: this.loginRes.tokenString,
|
||||
file: profileImageFileUploadItem.file,
|
||||
fileUploadItem: profileImageFileUploadItem
|
||||
} as FileProfileSaveRequest;
|
||||
|
||||
this.appFileServie.fileProfileSave(
|
||||
profile,
|
||||
this.versionInfo2Res.profileUploadUrl
|
||||
);
|
39
documents/업무/6월/4째주/0624.txt
Normal file
39
documents/업무/6월/4째주/0624.txt
Normal file
|
@ -0,0 +1,39 @@
|
|||
const findIdx = noti.info.indexOf('ProfileImage');
|
||||
let imgInfo: string = noti.info;
|
||||
|
||||
if (findIdx > -1) {
|
||||
const startIdx = noti.info.indexOf('/', findIdx);
|
||||
imgInfo = noti.info.substring(startIdx);
|
||||
}
|
||||
|
||||
const roomInfo1 = rooms.filter(
|
||||
(r) => r.roomId === ru.roomId
|
||||
)[0];
|
||||
const cUser = {
|
||||
...u,
|
||||
profileImageFile: 'imgInfo'
|
||||
};
|
||||
|
||||
const idx = ru.userInfos.findIndex(
|
||||
(u3) => Number(u3.seq) === Number(u.seq)
|
||||
);
|
||||
if (idx > -1) {
|
||||
ru.userInfos[idx] = cUser;
|
||||
}
|
||||
const tempShort: UserInfoShort[] = [];
|
||||
ru.userInfos.map((u2) => {
|
||||
if (Number(u2.seq) === Number(u.seq)) {
|
||||
tempShort.push(cUser);
|
||||
} else {
|
||||
tempShort.push(u2);
|
||||
}
|
||||
});
|
||||
const tempUserShort = [...ru.userInfos, cUser];
|
||||
|
||||
tempRoomList.push({
|
||||
roomInfo: roomInfo1,
|
||||
userInfoS: tempShort
|
||||
});
|
||||
|
||||
/2020/06/24/PF_338127_103928272.jpg
|
||||
|
1
documents/업무/6월/4째주/0625.txt
Normal file
1
documents/업무/6월/4째주/0625.txt
Normal file
|
@ -0,0 +1 @@
|
|||
즐겨찾기 구성원을 모두 해제 시 즐겨찾기 그룹 없어지지 않음
|
124
documents/업무/6월/4째주/0626.txt
Normal file
124
documents/업무/6월/4째주/0626.txt
Normal file
|
@ -0,0 +1,124 @@
|
|||
this.mediaObserver
|
||||
.asObservable()
|
||||
.pipe(takeUntil(this.ngOnDestroySubject))
|
||||
.subscribe((changes) => {
|
||||
if (!changes || 0 === changes.length) {
|
||||
return;
|
||||
}
|
||||
for (const change of changes) {
|
||||
switch (change.mqAlias) {
|
||||
case 'lt-sm':
|
||||
this.layoutMode = 'min';
|
||||
this.changeDetectorRef.detectChanges();
|
||||
return;
|
||||
case 'sm':
|
||||
case 'md':
|
||||
this.layoutMode = 'mid';
|
||||
this.changeDetectorRef.detectChanges();
|
||||
return;
|
||||
case 'gt-md':
|
||||
this.layoutMode = 'max';
|
||||
this.changeDetectorRef.detectChanges();
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
대화 이슈
|
||||
리스트
|
||||
백 스페이스로 입력된 검색어 모두 삭제 시 기존 리스트를 출력 하지 않음
|
||||
대화
|
||||
폼 컴포넌트 입력창 간헐적으로 입력이 안됨
|
||||
-> 한글일 때 키보드 연속으로 누르고 있을 때 화면에 나타나지 않다가 key up 할때 한번에 입력
|
||||
번역
|
||||
간략보기 기능 미구현
|
||||
대화방 멤버
|
||||
me 표시 없음
|
||||
프레즌스 표현안됨
|
||||
컨텍스트 메뉴 (미구현)
|
||||
프로필, 대화, 쪽지
|
||||
삭제, 회수
|
||||
모바일, 피시 간 연동 안됨, 상대방 대화에서 회수되지 않음(방이동 이나 새로고침)
|
||||
|
||||
다이얼로그
|
||||
일반 대화방 생성
|
||||
-> 인원 선택 X 대화방 생성 버튼 활성화
|
||||
타이머 대화방 상동
|
||||
1:n 대화방 생성 후 '대화방 이름 설정 안내 팝업' 노출되지 않음
|
||||
대화 x
|
||||
type(pin):"J"
|
||||
senderSeq(pin):"770074"
|
||||
|
||||
타이머 설정 안내 팝업 노출되지 않음
|
||||
|
||||
|
||||
<form name="chatSettingForm" [formGroup]="chatSettingForm" novalidate>
|
||||
<div class="ucap-chat-room-setting-body">
|
||||
<div class="setting-content-box roomName">
|
||||
<span class="tit-setting-content">{{
|
||||
'chat:dialog.roomName' | ucapI18n
|
||||
}}</span>
|
||||
<mat-form-field
|
||||
hintLabel="{{ 'common:useSpecialCharactor' | ucapI18n }}"
|
||||
style="display: block; margin-bottom: 10px;"
|
||||
color="accent"
|
||||
>
|
||||
<input
|
||||
matInput
|
||||
#input
|
||||
maxlength="20"
|
||||
formControlName="roomName"
|
||||
(keyup)="onKeyupName()"
|
||||
/>
|
||||
<mat-hint align="end"
|
||||
><em>{{ input.value?.length || 0 }}</em
|
||||
>/20</mat-hint
|
||||
>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="setting-content-box roomName-target">
|
||||
<span class="tit-setting-content">{{
|
||||
'chat:dialog.roomNameChangeTarget' | ucapI18n
|
||||
}}</span>
|
||||
<mat-radio-group
|
||||
aria-label="Select an option"
|
||||
value="me"
|
||||
formControlName="changeTarget"
|
||||
>
|
||||
<mat-radio-button value="me">{{
|
||||
'chat:dialog.me' | ucapI18n
|
||||
}}</mat-radio-button>
|
||||
<mat-radio-button value="all">{{
|
||||
'chat:dialog.all' | ucapI18n
|
||||
}}</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<!-- <div class="radio-hint-copy">
|
||||
※ 설정시간이 초과되면 대화내용이 삭제됩니다.
|
||||
</div> -->
|
||||
</div>
|
||||
<div
|
||||
class="setting-content-box timer"
|
||||
[style.display]="!!roomInfo?.isTimeRoom ? 'block' : 'none'"
|
||||
>
|
||||
<span class="tit-setting-content">{{
|
||||
'chat:dialog.settingTimer' | ucapI18n
|
||||
}}</span>
|
||||
<mat-form-field class="form-select-timer" color="accent">
|
||||
<mat-select formControlName="timerInterval">
|
||||
<mat-option
|
||||
*ngFor="let timer of timerArray"
|
||||
[value]="timer.value"
|
||||
>
|
||||
{{ timer.text }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-hint>{{
|
||||
'chat:dialog:settingTimerHint' | ucapI18n
|
||||
}}</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
183
documents/업무/6월/4째주/temp.txt
Normal file
183
documents/업무/6월/4째주/temp.txt
Normal file
|
@ -0,0 +1,183 @@
|
|||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Input,
|
||||
EventEmitter,
|
||||
Output
|
||||
} from '@angular/core';
|
||||
|
||||
import { Subject, combineLatest, merge } from 'rxjs';
|
||||
import { Store, select } from '@ngrx/store';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { LoginResponse } from '@ucap/protocol-authentication';
|
||||
import {
|
||||
RoomInfo,
|
||||
UpdateRequest,
|
||||
UpdateTimerSetRequest
|
||||
} from '@ucap/protocol-room';
|
||||
import { RoomSelector, RoomActions } from '@ucap/ng-store-chat';
|
||||
import { LoginSelector } from '@ucap/ng-store-authentication';
|
||||
import { I18nService } from '@ucap/ng-i18n';
|
||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'app-drawer-chat-setting',
|
||||
templateUrl: './setting.drawer.component.html',
|
||||
styleUrls: ['./setting.drawer.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SettingDrawerComponent implements OnInit, OnDestroy {
|
||||
private roomIdSubject = new Subject<string>();
|
||||
private ngOnDestroySubject = new Subject<boolean>();
|
||||
|
||||
@Input()
|
||||
set roomId(value: string) {
|
||||
this._roomId = value;
|
||||
this.roomIdSubject.next(value);
|
||||
this._initializeData();
|
||||
}
|
||||
get roomId(): string {
|
||||
return this._roomId;
|
||||
}
|
||||
// tslint:disable-next-line: variable-name
|
||||
_roomId: string;
|
||||
|
||||
@Output()
|
||||
closed = new EventEmitter<void>();
|
||||
|
||||
loginRes: LoginResponse;
|
||||
roomInfo: RoomInfo;
|
||||
|
||||
roomName: string;
|
||||
timerArray: { value: number; text: string }[];
|
||||
|
||||
chatSettingForm: FormGroup;
|
||||
|
||||
constructor(
|
||||
private i18nService: I18nService,
|
||||
private store: Store<any>,
|
||||
private formBuilder: FormBuilder,
|
||||
private changeDetectorRef: ChangeDetectorRef
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this._initializeData();
|
||||
|
||||
this.i18nService.languageChanged$
|
||||
.pipe(takeUntil(this.ngOnDestroySubject))
|
||||
.subscribe((_) => {
|
||||
this.setTimerArray();
|
||||
});
|
||||
this.setTimerArray();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (!!this.ngOnDestroySubject) {
|
||||
this.ngOnDestroySubject.next();
|
||||
this.ngOnDestroySubject.complete();
|
||||
}
|
||||
}
|
||||
|
||||
private _initializeData() {
|
||||
combineLatest([
|
||||
this.store.pipe(select(LoginSelector.loginRes)),
|
||||
this.store.pipe(select(RoomSelector.room, this.roomId))
|
||||
])
|
||||
.pipe(takeUntil(merge(this.ngOnDestroySubject, this.roomIdSubject)))
|
||||
.subscribe(([loginRes, roomInfo]) => {
|
||||
this.loginRes = loginRes;
|
||||
this.roomInfo = roomInfo;
|
||||
|
||||
this.chatSettingForm = this.formBuilder.group({
|
||||
roomName: [
|
||||
this.roomInfo?.roomName,
|
||||
!this.roomInfo?.isTimeRoom ? [Validators.required] : []
|
||||
],
|
||||
changeTarget: ['me'],
|
||||
timerInterval: [this.roomInfo?.timeRoomInterval]
|
||||
});
|
||||
|
||||
this.changeDetectorRef.detectChanges();
|
||||
});
|
||||
}
|
||||
|
||||
onChange() {
|
||||
const checkInvalid = this.chatSettingForm.invalid;
|
||||
let roomName: string;
|
||||
if (checkInvalid) {
|
||||
roomName = '';
|
||||
} else {
|
||||
roomName = this.chatSettingForm.get('roomName').value;
|
||||
}
|
||||
}
|
||||
|
||||
onKeyupName() {
|
||||
this.chatSettingForm.get('roomName').markAsTouched();
|
||||
}
|
||||
|
||||
setTimerArray() {
|
||||
const hourFrom = this.i18nService.t('common:units.hourFrom');
|
||||
const minute = this.i18nService.t('common:units.minute');
|
||||
const second = this.i18nService.t('common:units.second');
|
||||
|
||||
this.timerArray = [
|
||||
{ value: 5, text: `5 ${second}` },
|
||||
{ value: 10, text: `10 ${second}` },
|
||||
{ value: 30, text: `30 ${second}` },
|
||||
{ value: 60, text: `1 ${minute}` },
|
||||
{ value: 300, text: `5 ${minute}` },
|
||||
{ value: 600, text: `10 ${minute}` },
|
||||
{ value: 1800, text: `30 ${minute}` },
|
||||
{ value: 3600, text: `1 ${hourFrom}` },
|
||||
{ value: 21600, text: `6 ${hourFrom}` },
|
||||
{ value: 43200, text: `12 ${hourFrom}` },
|
||||
{ value: 86400, text: `24 ${hourFrom}` }
|
||||
];
|
||||
}
|
||||
|
||||
onChangeGroupName(name: string) {
|
||||
this.roomName = name;
|
||||
}
|
||||
|
||||
onClosed(event: MouseEvent): void {
|
||||
this.closed.emit();
|
||||
}
|
||||
|
||||
const forbidden = /[\{\}\[\]\/?.;:|\)*~`!^+<>@\#$%&\\\=\(\'\"]/g.test(
|
||||
inputValue
|
||||
);
|
||||
|
||||
onConfirm(): void {
|
||||
const roomName = this.chatSettingForm.get('roomName').value;
|
||||
const roomNameChangeTarget = this.chatSettingForm.get('changeTarget').value;
|
||||
const timerInterval = this.chatSettingForm.get('timerInterval').value;
|
||||
|
||||
this.store.dispatch(
|
||||
RoomActions.update({
|
||||
req: {
|
||||
roomId: this.roomInfo.roomId,
|
||||
roomName,
|
||||
receiveAlarm: this.roomInfo.receiveAlarm,
|
||||
syncAll: roomNameChangeTarget.toUpperCase() === 'ALL' ? true : false
|
||||
} as UpdateRequest
|
||||
})
|
||||
);
|
||||
|
||||
if (!!this.roomInfo?.isTimeRoom) {
|
||||
this.store.dispatch(
|
||||
RoomActions.updateTimeRoomInterval({
|
||||
req: {
|
||||
roomId: this.roomInfo.roomId,
|
||||
timerInterval
|
||||
} as UpdateTimerSetRequest
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
this.closed.emit();
|
||||
}
|
||||
}
|
BIN
documents/업무/6월/4째주/ucap-0626.zip
Normal file
BIN
documents/업무/6월/4째주/ucap-0626.zip
Normal file
Binary file not shown.
BIN
documents/업무/6월/4째주/ucap-angular-0626.zip
Normal file
BIN
documents/업무/6월/4째주/ucap-angular-0626.zip
Normal file
Binary file not shown.
BIN
documents/업무/6월/4째주/ucap-lg-web-0626.zip
Normal file
BIN
documents/업무/6월/4째주/ucap-lg-web-0626.zip
Normal file
Binary file not shown.
BIN
weekly-report/6월/주간보고_박병은_2020.0619.pptx
Normal file
BIN
weekly-report/6월/주간보고_박병은_2020.0619.pptx
Normal file
Binary file not shown.
BIN
weekly-report/6월/주간보고_박병은_2020.0626.pptx
Normal file
BIN
weekly-report/6월/주간보고_박병은_2020.0626.pptx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user