520 lines
14 KiB
Plaintext
520 lines
14 KiB
Plaintext
|
번역
|
||
|
컴포넌트
|
||
|
데이터
|
||
|
번역 토글
|
||
|
번역 국가
|
||
|
오리지날 메세지
|
||
|
번역 메세지
|
||
|
대화방 번호
|
||
|
번역 프로그레스
|
||
|
로그인 사용자 seq
|
||
|
디바이스 타입
|
||
|
토큰
|
||
|
|
||
|
절차
|
||
|
form 컴포넌트 번역 버튼 클릭
|
||
|
번역 컴포넌트 활성화
|
||
|
번역 메세지 입력 -> 번역 클릭
|
||
|
전송 처리
|
||
|
성공
|
||
|
미리보기 옵션
|
||
|
일반 번역
|
||
|
대용량 번역
|
||
|
|
||
|
소켓 메세지 전송
|
||
|
실패
|
||
|
번역 실패 메세지
|
||
|
번역 프로그레스 초기화
|
||
|
|
||
|
대화방 id 변경 시 번역 데이터 초기화
|
||
|
|
||
|
|
||
|
// const destLocale = this.destLocale;
|
||
|
// const original = message;
|
||
|
// const roomSeq = this.roomInfoSubject.value.roomSeq;
|
||
|
// if (!!this.isTranslationProcess) {
|
||
|
// return;
|
||
|
// }
|
||
|
// this.isTranslationProcess = true;
|
||
|
// this.commonApiService
|
||
|
// .translationSave({
|
||
|
// userSeq: this.loginResSubject.value.userSeq,
|
||
|
// deviceType: this.environmentsInfo.deviceType,
|
||
|
// token: this.loginResSubject.value.tokenString,
|
||
|
// roomSeq,
|
||
|
// original,
|
||
|
// srcLocale: '',
|
||
|
// destLocale
|
||
|
// } as TranslationSaveRequest)
|
||
|
// .pipe(
|
||
|
// take(1),
|
||
|
// map((res) => {
|
||
|
// if (res.statusCode === StatusCode.Success) {
|
||
|
// let sentMessage = '';
|
||
|
// let eventType = EventType.Translation;
|
||
|
// let previewObject: TranslationEventJson | MassTranslationEventJson;
|
||
|
// if (res.translationSeq > 0) {
|
||
|
// // Mass Text Translation
|
||
|
// previewObject = res;
|
||
|
// sentMessage = res.returnJson;
|
||
|
// eventType = EventType.MassTranslation;
|
||
|
// } else {
|
||
|
// // Normal Text Translation
|
||
|
// previewObject = {
|
||
|
// locale: destLocale,
|
||
|
// original,
|
||
|
// translation: res.translation,
|
||
|
// stickername: '',
|
||
|
// stickerfile: !!this.selectedSticker
|
||
|
// ? this.selectedSticker.index
|
||
|
// : ''
|
||
|
// };
|
||
|
// sentMessage = JSON.stringify(previewObject);
|
||
|
// eventType = EventType.Translation;
|
||
|
// }
|
||
|
// if (!!this.translationPreview) {
|
||
|
// // preview
|
||
|
// this.translationPreviewInfo = {
|
||
|
// previewInfo: res,
|
||
|
// translationType: eventType
|
||
|
// };
|
||
|
// this.changeDetectorRef.detectChanges();
|
||
|
// } else {
|
||
|
// // direct send
|
||
|
// this.store.dispatch(
|
||
|
// EventStore.send({
|
||
|
// senderSeq: this.loginResSubject.value.userSeq,
|
||
|
// req: {
|
||
|
// roomSeq,
|
||
|
// eventType,
|
||
|
// sentMessage
|
||
|
// }
|
||
|
// })
|
||
|
// );
|
||
|
// if (!!this.translationPreviewInfo) {
|
||
|
// this.translationPreviewInfo = null;
|
||
|
// }
|
||
|
// }
|
||
|
// if (!!this.selectedSticker) {
|
||
|
// this.isShowStickerSelector = false;
|
||
|
// this.setStickerHistory(this.selectedSticker);
|
||
|
// this.selectedSticker = null;
|
||
|
// }
|
||
|
// } else {
|
||
|
// this.isTranslationProcess = false;
|
||
|
// this.dialogService.open<
|
||
|
// AlertDialogComponent,
|
||
|
// AlertDialogData,
|
||
|
// AlertDialogResult
|
||
|
// >(AlertDialogComponent, {
|
||
|
// panelClass: 'miniSize-dialog',
|
||
|
// data: {
|
||
|
// title: '',
|
||
|
// message: this.translateService.instant(
|
||
|
// 'chat.error.translateServerError'
|
||
|
// )
|
||
|
// }
|
||
|
// });
|
||
|
// this.logger.error('res', res);
|
||
|
// }
|
||
|
// }),
|
||
|
// catchError((error) => {
|
||
|
// this.isTranslationProcess = false;
|
||
|
// this.dialogService.open<
|
||
|
// AlertDialogComponent,
|
||
|
// AlertDialogData,
|
||
|
// AlertDialogResult
|
||
|
// >(AlertDialogComponent, {
|
||
|
// panelClass: 'miniSize-dialog',
|
||
|
// data: {
|
||
|
// title: '',
|
||
|
// message: this.translateService.instant(
|
||
|
// 'chat.error.translateServerError'
|
||
|
// )
|
||
|
// }
|
||
|
// });
|
||
|
// return of(this.logger.error('error', error));
|
||
|
// })
|
||
|
// )
|
||
|
// .subscribe(() => {
|
||
|
// this.isTranslationProcess = false;
|
||
|
// });
|
||
|
|
||
|
|
||
|
http://13.124.88.127:8011/Common/TranslationSave.aspx
|
||
|
|
||
|
|
||
|
destLocale: "en"
|
||
|
original: "안녕"
|
||
|
registrationDate: ""
|
||
|
returnJson: "
|
||
|
{"StatusCode":"200","ErrorMessage":"","EventTransSeq":"0","RoomID":"5109369","RegDate":"",
|
||
|
"Locale":"en","SrcLocale":"ko","DestLocale":"en","Original":"안녕","Translation":"Hi"}"
|
||
|
roomId: "5109369"
|
||
|
srcLocale: "ko"
|
||
|
statusCode: "200"
|
||
|
translation: "Hi"
|
||
|
translationSeq: 0
|
||
|
|
||
|
import { Subject } from 'rxjs';
|
||
|
import { takeUntil } from 'rxjs/operators';
|
||
|
|
||
|
import {
|
||
|
Component,
|
||
|
OnInit,
|
||
|
ChangeDetectorRef,
|
||
|
Input,
|
||
|
OnDestroy,
|
||
|
ChangeDetectionStrategy,
|
||
|
ViewChild
|
||
|
} from '@angular/core';
|
||
|
|
||
|
import { MediaObserver } from '@angular/flex-layout';
|
||
|
|
||
|
import { MatCheckboxChange, MatCheckbox } from '@angular/material/checkbox';
|
||
|
|
||
|
import { select, Store } from '@ngrx/store';
|
||
|
|
||
|
import { SortOrder } from '@ucap/core';
|
||
|
import { Company } from '@ucap/api-external';
|
||
|
import { LoginResponse } from '@ucap/protocol-authentication';
|
||
|
import { DeptInfo, UserInfoSS } from '@ucap/protocol-query';
|
||
|
import { UserInfo } from '@ucap/protocol-sync';
|
||
|
|
||
|
import { LoginSelector } from '@ucap/ng-store-authentication';
|
||
|
import {
|
||
|
DepartmentSelector,
|
||
|
CompanySelector
|
||
|
} from '@ucap/ng-store-organization';
|
||
|
|
||
|
import { SearchData } from '@app/ucap/organization/models/search-data';
|
||
|
import { ProfileListComponent as AppProfileListComponent } from '@app/ucap/organization/components/profile-list.component';
|
||
|
|
||
|
@Component({
|
||
|
selector: 'app-sections-organization-member-list',
|
||
|
templateUrl: './member-list.component.html',
|
||
|
styleUrls: ['./member-list.component.scss'],
|
||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||
|
})
|
||
|
export class MemberListComponent implements OnInit, OnDestroy {
|
||
|
@Input()
|
||
|
set searchData(searchData: SearchData) {
|
||
|
this._searchData = searchData;
|
||
|
|
||
|
this.selectedDeptInfo = undefined;
|
||
|
this.selectedCompanyInfo = undefined;
|
||
|
|
||
|
if (!!searchData && !searchData.bySearch && !!searchData.deptSeq) {
|
||
|
this.setDeptInfo(searchData.deptSeq);
|
||
|
} else {
|
||
|
this.setCompanyInfo(searchData.companyCode);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@ViewChild('profileList', { static: false })
|
||
|
profileList: AppProfileListComponent;
|
||
|
|
||
|
@ViewChild('checkboxAll', { static: false })
|
||
|
checkboxAll: MatCheckbox;
|
||
|
|
||
|
// tslint:disable-next-line: variable-name
|
||
|
_searchData: SearchData;
|
||
|
loginRes: LoginResponse;
|
||
|
selectedDeptInfo: DeptInfo;
|
||
|
selectedCompanyInfo: Company;
|
||
|
searchedProfileLength: number;
|
||
|
selectedUserInfos: UserInfoSS[] = [];
|
||
|
isExpanded = false;
|
||
|
|
||
|
sortOrderForProfileList: SortOrder = {
|
||
|
property: 'name',
|
||
|
ascending: undefined
|
||
|
};
|
||
|
|
||
|
layoutMode: 'min' | 'mid' | 'max';
|
||
|
|
||
|
private ngOnDestroySubject: Subject<void> = new Subject();
|
||
|
|
||
|
constructor(
|
||
|
private store: Store<any>,
|
||
|
public mediaObserver: MediaObserver,
|
||
|
private changeDetectorRef: ChangeDetectorRef
|
||
|
) {}
|
||
|
|
||
|
ngOnInit() {
|
||
|
this.store
|
||
|
.pipe(takeUntil(this.ngOnDestroySubject), select(LoginSelector.loginRes))
|
||
|
.subscribe((loginRes) => {
|
||
|
this.loginRes = loginRes;
|
||
|
});
|
||
|
|
||
|
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';
|
||
|
return;
|
||
|
case 'sm':
|
||
|
case 'md':
|
||
|
this.layoutMode = 'mid';
|
||
|
return;
|
||
|
case 'gt-md':
|
||
|
this.layoutMode = 'max';
|
||
|
return;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
ngOnDestroy(): void {
|
||
|
if (!!this.ngOnDestroySubject) {
|
||
|
this.ngOnDestroySubject.next();
|
||
|
this.ngOnDestroySubject.complete();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
onChangedSearch(data: { deptSeq: string; searchWord: string }) {
|
||
|
this._searchData = {
|
||
|
bySearch: true,
|
||
|
...data
|
||
|
};
|
||
|
this.setDeptInfo(data.deptSeq);
|
||
|
}
|
||
|
|
||
|
onSearchedProfileList(userInfos: UserInfoSS[]) {
|
||
|
if (!!this.checkboxAll) {
|
||
|
this.checkboxAll.checked = false;
|
||
|
}
|
||
|
this.searchedProfileLength = !!userInfos ? userInfos.length : 0;
|
||
|
}
|
||
|
|
||
|
onChangedCheckProfileList(
|
||
|
datas: { checked: boolean; userInfo: UserInfoSS }[]
|
||
|
) {
|
||
|
if (!datas || 0 === datas.length) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const pushs: UserInfoSS[] = [];
|
||
|
const pops: UserInfoSS[] = [];
|
||
|
|
||
|
datas.forEach((d) => {
|
||
|
const i = this.selectedUserInfos.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.selectedUserInfos = [...this.selectedUserInfos, ...pushs];
|
||
|
}
|
||
|
|
||
|
if (0 < pops.length) {
|
||
|
this.selectedUserInfos = this.selectedUserInfos.filter(
|
||
|
(u) => -1 === pops.findIndex((p) => p.seq === u.seq)
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
onRemovedProfileSelection(userInfo: UserInfo) {
|
||
|
const i = this.selectedUserInfos.findIndex(
|
||
|
(u) => u.seq === String(userInfo.seq)
|
||
|
);
|
||
|
|
||
|
if (-1 < i) {
|
||
|
this.selectedUserInfos = this.selectedUserInfos.filter(
|
||
|
(u) => u.seq !== String(userInfo.seq)
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
removableForSelection = (userInfo: UserInfo) => {
|
||
|
return true;
|
||
|
};
|
||
|
|
||
|
colorForSelection = (userInfo: UserInfo) => {
|
||
|
return 'accent';
|
||
|
};
|
||
|
|
||
|
onClickToggleSort() {
|
||
|
this.sortOrderForProfileList = {
|
||
|
...this.sortOrderForProfileList,
|
||
|
ascending:
|
||
|
undefined === this.sortOrderForProfileList.ascending
|
||
|
? true
|
||
|
: true === this.sortOrderForProfileList.ascending
|
||
|
? false
|
||
|
: undefined
|
||
|
};
|
||
|
}
|
||
|
|
||
|
onChangeSelectAll(event: MatCheckboxChange) {
|
||
|
if (event.checked) {
|
||
|
this.profileList.checkAll();
|
||
|
} else {
|
||
|
this.profileList.uncheckAll();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
getContainerLayout(type: 'max' | 'mid'): string {
|
||
|
switch (type) {
|
||
|
case 'max':
|
||
|
return 'row';
|
||
|
case 'mid':
|
||
|
return 'column';
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
onAfterExpandForSelection() {
|
||
|
this.isExpanded = true;
|
||
|
}
|
||
|
|
||
|
onAfterCollapseForSelection() {
|
||
|
this.isExpanded = false;
|
||
|
}
|
||
|
|
||
|
private setCompanyInfo(companyCode: string) {
|
||
|
const destroySubject: Subject<void> = new Subject();
|
||
|
this.store
|
||
|
.pipe(takeUntil(destroySubject), select(CompanySelector.companyList))
|
||
|
.subscribe((companyList) => {
|
||
|
if (!companyList) {
|
||
|
return;
|
||
|
}
|
||
|
this.selectedCompanyInfo = companyList.find(
|
||
|
(c) => c.companyCode === companyCode
|
||
|
);
|
||
|
this.changeDetectorRef.markForCheck();
|
||
|
destroySubject.next();
|
||
|
destroySubject.complete();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
private setDeptInfo(seq: string) {
|
||
|
const destroySubject: Subject<void> = new Subject();
|
||
|
this.store
|
||
|
.pipe(
|
||
|
takeUntil(destroySubject),
|
||
|
select(DepartmentSelector.departmentInfoList)
|
||
|
)
|
||
|
.subscribe((departmentInfoList) => {
|
||
|
if (!departmentInfoList) {
|
||
|
return;
|
||
|
}
|
||
|
this.selectedDeptInfo = departmentInfoList.find(
|
||
|
(d) => String(d.seq) === seq
|
||
|
);
|
||
|
this.changeDetectorRef.markForCheck();
|
||
|
destroySubject.next();
|
||
|
destroySubject.complete();
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/** 전체 체크여부 */
|
||
|
allCheckUser() {
|
||
|
if (this.allChecked) {
|
||
|
this.userInfos.forEach((userInfo) =>
|
||
|
this.onChangeCheckUser({ checked: true, userInfo })
|
||
|
);
|
||
|
} else {
|
||
|
this.userInfos.forEach((userInfo) =>
|
||
|
this.onChangeCheckUser({ checked: false, userInfo })
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
|
||
|
onChangedCheckProfileList(
|
||
|
datas: { checked: boolean; userInfo: UserInfoSS }[]
|
||
|
) {
|
||
|
if (!datas || 0 === datas.length) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const pushs: UserInfoSS[] = [];
|
||
|
const pops: UserInfoSS[] = [];
|
||
|
|
||
|
datas.forEach((d) => {
|
||
|
const i = this.selectedUserInfos.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.selectedUserInfos = [...this.selectedUserInfos, ...pushs];
|
||
|
}
|
||
|
|
||
|
if (0 < pops.length) {
|
||
|
this.selectedUserInfos = this.selectedUserInfos.filter(
|
||
|
(u) => -1 === pops.findIndex((p) => p.seq === u.seq)
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
<ucap-organization-profile-selection-01
|
||
|
[userInfoList]="selectedUserInfos"
|
||
|
[removableFor]="removableForSelection"
|
||
|
[colorFor]="colorForSelection"
|
||
|
(removed)="onRemovedProfileSelection($event)"
|
||
|
>
|
||
|
</ucap-organization-profile-selection-01>
|