UNPKG

@schoolbelle/common

Version:

Demo library to showcase Angular packaging format

1,667 lines (1,634 loc) 502 kB
import { Injectable, Inject, NgModule, Component, Input, EventEmitter, InjectionToken, Optional, ViewEncapsulation, ApplicationRef, Injector, ComponentFactoryResolver, NgZone } from '@angular/core'; import { REST_SERVER_HOST, SOCKET_SERVER_HOST, AUTH_FRONT_HOST } from '@schoolbelle/common/tokens'; import { HttpClient, HttpClientModule, HttpParams } from '@angular/common/http'; import { StorageService, StorageServiceModule } from '@schoolbelle/common/services/storage'; import 'rxjs/add/operator/toPromise'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { UserService } from '@schoolbelle/common/services/user'; import { UserToGroupService } from '@schoolbelle/common/services/user-to-group'; import { find, get, set, findIndex, forEach, maxBy, mapValues, pickBy, identity, minBy, filter, isEqual, unset, sortBy, times, isMatch, findLast } from 'lodash'; import { BsModalRef } from 'ngx-bootstrap/modal/bs-modal-ref.service'; import { BsModalService, ModalModule } from 'ngx-bootstrap/modal'; import 'rxjs/add/operator/take'; import { CommonModule } from '@angular/common'; import { GroupService } from '@schoolbelle/common/services/group'; import { SocketService } from '@schoolbelle/common/services/socket'; import { Observable, Subject, BehaviorSubject as BehaviorSubject$1 } from 'rxjs'; import jwt_decode from 'jwt-decode'; import { TranslationService } from '@schoolbelle/common/services/translation'; import { FileService } from '@schoolbelle/common/services/file'; import { LetterToGroupService } from '@schoolbelle/common/services/letter-to-group'; import { SmsService } from '@schoolbelle/common/services/sms'; import { PubsubService } from '@schoolbelle/common/services/pubsub'; import { InfiniteScrollListService } from '@schoolbelle/common/services/infinite-scroll-list'; import { Subscription } from 'rxjs/Subscription'; import { trigger, style, transition, animate } from '@angular/animations'; import { Subject as Subject$1 } from 'rxjs/Subject'; import { fromJS } from 'immutable'; import io from 'socket.io-client'; import { WINDOW } from '@schoolbelle/common/services/window'; import { ObjectChangeTracker } from '@schoolbelle/common/services/object-change-tracker'; import { MemberService } from '@schoolbelle/common/services/member'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class AuthService { /** * @param {?} http * @param {?} storageService * @param {?} serverHost */ constructor(http, storageService, serverHost) { this.http = http; this.storageService = storageService; this.serverHost = serverHost; let /** @type {?} */ type = /** @type {?} */ (this.storageService.get('sbe-auth.session.type', 'session')); let /** @type {?} */ intltel = this.storageService.get('sbe-auth.session.intltel', 'session'); let /** @type {?} */ verificationCode = this.storageService.get('sbe-auth.session.verificationCode', 'session'); if (type) this.type = type; if (intltel) this.intltel = intltel; if (verificationCode) this.verificationCode = verificationCode; } /** * @return {?} */ get type() { return this._type; } /** * @param {?} v * @return {?} */ set type(v) { this._type = v; if (v) { this.storageService.set('sbe-auth.session.type', v, 'session'); } else { this.storageService.remove('sbe-auth.session.type', 'session'); } } /** * @return {?} */ get intltel() { return this._intltel; } /** * @param {?} v * @return {?} */ set intltel(v) { this._intltel = v; if (v) { this.storageService.set('sbe-auth.session.intltel', v, 'session'); } else { this.storageService.remove('sbe-auth.session.intltel', 'session'); } } /** * @return {?} */ get verificationCode() { return this._verificationCode; } /** * @param {?} v * @return {?} */ set verificationCode(v) { this._verificationCode = v; if (v) { this.storageService.set('sbe-auth.session.verificationCode', v, 'session'); } else { this.storageService.remove('sbe-auth.session.verificationCode', 'session'); } } /** * @return {?} */ clear() { this.type = undefined; this.intltel = undefined; this.verificationCode = undefined; } /** * @param {?} idtoken * @return {?} */ saveToken(idtoken) { if (idtoken) { this.storageService.set(AuthService.localStorageIdTokenKey, idtoken, 'local'); } else { this.storageService.remove(AuthService.localStorageIdTokenKey, 'local'); } } /** * @param {?=} type * @param {?=} countryDialCode * @param {?=} tel * @return {?} */ requestCode(type = 'register', countryDialCode, tel) { const /** @type {?} */ url = `${this.serverHost}/verification/request_code`; return this.http .post(url, { type: type, countryDialCode: countryDialCode, tel: tel }, { responseType: 'text' }) .toPromise(); } /** * @param {?=} type * @param {?=} countryDialCode * @param {?=} tel * @param {?=} verificationCode * @param {?=} callback_url * @return {?} */ verifyCode(type = 'register', countryDialCode, tel, verificationCode, callback_url = undefined) { const /** @type {?} */ url = `${this.serverHost}/verification/verify_code`; return this.http .post(url, { type: type, countryDialCode: countryDialCode, tel: tel, code: verificationCode, callback_url: callback_url }, { responseType: 'text' }) .toPromise() .then(token => { if (type === 'tmp' && token) { this.saveToken(token); } return token; }); } /** * @param {?} countryDialCode * @param {?} tel * @param {?} password * @param {?=} callback_url * @return {?} */ login(countryDialCode, tel, password, callback_url = undefined) { const /** @type {?} */ url = `${this.serverHost}/login`; return this.http .post(url, { countryDialCode: countryDialCode, tel: tel, password: password, callback_url: callback_url }, { responseType: 'text' }) .toPromise() .then(token => { this.saveToken(token); return token; }); } /** * @param {?} countryDialCode * @param {?} tel * @param {?} verificationCode * @param {?} name * @param {?} password * @param {?=} callback_url * @return {?} */ register(countryDialCode, tel, verificationCode, name, password, callback_url = undefined) { const /** @type {?} */ url = `${this.serverHost}/register`; return this.http .post(url, { countryDialCode: countryDialCode, tel: tel, code: verificationCode, name: name, password: password }) .toPromise() .then(() => this.login(countryDialCode, tel, password, callback_url)); } /** * @return {?} */ getTermsOfUse() { const /** @type {?} */ url = `${this.serverHost}/legal/user_agreement`; return this.http.get(url, { responseType: 'text' }).toPromise(); } /** * @return {?} */ getPrivacyPolicy() { const /** @type {?} */ url = `${this.serverHost}/legal/privacy_policy`; return this.http.get(url, { responseType: 'text' }).toPromise(); } /** * @param {?} countryDialCode * @param {?} tel * @param {?} password * @return {?} */ agreeToTerms(countryDialCode, tel, password) { const /** @type {?} */ url = `${this.serverHost}/legal/agree_to_terms`; return this.http .post(url, { countryDialCode: countryDialCode, tel: tel, password: password }) .toPromise(); } } AuthService.localStorageIdTokenKey = 'sbe-auth.idToken'; AuthService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ AuthService.ctorParameters = () => [ { type: HttpClient, }, { type: StorageService, }, { type: undefined, decorators: [{ type: Inject, args: [REST_SERVER_HOST,] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class AuthServiceModule { /** * @return {?} */ static forRoot() { return { ngModule: AuthServiceModule, providers: [AuthService] }; } } AuthServiceModule.decorators = [ { type: NgModule, args: [{ imports: [HttpClientModule, StorageServiceModule] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class BadgeService { /** * @param {?} http * @param {?} userService * @param {?} utgService * @param {?} serverHost */ constructor(http, userService, utgService, serverHost) { this.http = http; this.userService = userService; this.utgService = utgService; this.serverHost = serverHost; this.list = []; this.badges = { total: 0 }; this.changeEvent = new BehaviorSubject(this.badges); } /** * @return {?} */ get onChange() { return this.changeEvent.asObservable(); } /** * @param {?=} path * @return {?} */ get(path = undefined) { return path ? get(this.badges, path) : this.badges; } /** * @return {?} */ refresh() { const /** @type {?} */ url = `${this.serverHost}/user/notification/list`; return this.http .get(url, { headers: { Authorization: 'Bearer ' + this.userService.token }, responseType: 'json' }) .toPromise() .then((list) => { this.list.splice(0, this.list.length); forEach(Object.keys(this.badges), key => delete this.badges[key]); this.badges.total = 0; list.forEach(li => { if (!find(this.list, { notification_id: li.notification_id })) { this.list.push(li); this.addToBadges(li); } }); this.changeEvent.next(this.badges); }); } /** * @return {?} */ fetch() { let /** @type {?} */ last_id = (maxBy(this.list, 'notification_id') || {}).notification_id; const /** @type {?} */ url = `${this.serverHost}/user/notification/list`; const /** @type {?} */ params = new HttpParams().set('last_id', last_id); return this.http .get(url, { params: params, headers: { Authorization: 'Bearer ' + this.userService.token }, responseType: 'json' }) .toPromise() .then((list) => { list.forEach(li => { if (!find(this.list, { notification_id: li.notification_id })) { this.list.push(li); this.addToBadges(li); } }); this.changeEvent.next(this.badges); }); } /** * @param {?} params * @return {?} */ find(params) { return find(this.list, li => { for (let /** @type {?} */ path in params) { let /** @type {?} */ value = params[path]; if (get(li, path) !== value) return false; } return true; }); } /** * @param {?} params * @return {?} */ read(params) { // path-value pairs let /** @type {?} */ li = this.find(params); if (!li) return Promise.resolve(); const /** @type {?} */ url = `${this.serverHost}/user/notification/read`; const /** @type {?} */ httpParams = new HttpParams().set('notification_id', '' + params.notification_id); return this.http .post(url, { params: httpParams, headers: { Authorization: 'Bearer ' + this.userService.token } }) .toPromise() .then(() => { this.removeFromBadges(li); let /** @type {?} */ index = findIndex(this.list, { notification_id: li.notification_id }); if (index !== -1) this.list.splice(index, 1); this.changeEvent.next(this.badges); }); } /** * @param {?} li * @return {?} */ addToBadges(li) { let /** @type {?} */ group = find(this.utgService.list, { group_id: li.group_id }); if (!group) return; if (BadgeService.notificationToRecord.indexOf(li.table + '.*') !== -1 || BadgeService.notificationToRecord.indexOf(li.table + '.' + li.type) === -1) return; if (!li.new || !li.new.ltg_id) return; if (li.new.type && group.type && group.type.match(/school/)) return; if (li.new.type) { let /** @type {?} */ value_o = get(this.badges, [li.group_id, li.new.type]) || 0; let /** @type {?} */ total_o = get(this.badges, [li.group_id, 'total']) || 0; let /** @type {?} */ grand_total_o = get(this.badges, ['total']) || 0; set(this.badges, [li.group_id, li.new.type], value_o + 1); set(this.badges, [li.group_id, 'total'], total_o + 1); set(this.badges, ['total'], grand_total_o + 1); } } /** * @param {?} li * @return {?} */ removeFromBadges(li) { let /** @type {?} */ group = find(this.utgService.list, { group_id: li.group_id }); if (!group) return; if (li.group_id && li.old && li.old.type) { if (group.type && group.type.match(/school/)) return; let /** @type {?} */ value_o = get(this.badges, [li.group_id, li.old.type]) || 1; let /** @type {?} */ total_o = get(this.badges, [li.group_id, 'total']) || 1; let /** @type {?} */ grand_total_o = get(this.badges, ['total']) || 1; if (value_o <= 0) value_o = 1; if (total_o <= 0) value_o = 1; set(this.badges, [li.group_id, li.old.type], value_o - 1); set(this.badges, [li.group_id, 'total'], total_o - 1); set(this.badges, ['total'], grand_total_o - 1); } } } BadgeService.notificationToRecord = ['letter_to_group.insert', 'utgRequest.insert']; BadgeService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ BadgeService.ctorParameters = () => [ { type: HttpClient, }, { type: UserService, }, { type: UserToGroupService, }, { type: undefined, decorators: [{ type: Inject, args: [REST_SERVER_HOST,] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class BadgeServiceModule { /** * @return {?} */ static forRoot() { return { NgModule: BadgeService, providers: [BadgeService] }; } } BadgeServiceModule.decorators = [ { type: NgModule, args: [{},] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class DialogAbstractComponent { /** * @param {?} modalRef */ constructor(modalRef) { this.modalRef = modalRef; this.action = new EventEmitter(); } /** * @param {?=} result * @return {?} */ ok(result = true) { this.modalRef.hide(); this.action.emit(result); } /** * @return {?} */ cancel() { this.modalRef.hide(); this.action.emit(false); } } DialogAbstractComponent.decorators = [ { type: Component, args: [{ template: '' },] }, ]; /** @nocollapse */ DialogAbstractComponent.ctorParameters = () => [ { type: BsModalRef, }, ]; DialogAbstractComponent.propDecorators = { "title": [{ type: Input },], "message": [{ type: Input },], }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class DialogConfirmComponent extends DialogAbstractComponent { } DialogConfirmComponent.decorators = [ { type: Component, args: [{ selector: 'dialog-confirm', template: `<div *ngIf="title" class="card-header" [innerHTML]="title"></div> <div *ngIf="message" class="card-body" [innerHTML]="message"></div> <div class="modal-footer"> <button type="button" class="btn btn-outline-danger" (click)="modalRef.hide(); action.emit(false)" i18n>Cancel</button> <button type="button" class="btn btn-outline-primary" (click)="modalRef.hide(); action.emit(true)" i18n>Confirm</button> </div> ` },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class DialogAlertComponent extends DialogAbstractComponent { } DialogAlertComponent.decorators = [ { type: Component, args: [{ selector: 'dialog-alert', template: `<div class="card"> <div *ngIf="title" class="card-header" [innerHTML]="title"></div> <div *ngIf="message" class="card-body" [innerHTML]="message"></div> <div class="card-footer text-right"> <button type="button" class="btn btn-outline-danger" (click)="modalRef.hide(); action.emit(true)" i18n>Close</button> </div> </div> ` },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class DialogSelectComponent extends DialogAbstractComponent { constructor() { super(...arguments); this.selections = []; } /** * @param {?} i * @return {?} */ select(i) { this.modalRef.hide(); this.action.emit(i); } } DialogSelectComponent.decorators = [ { type: Component, args: [{ selector: 'dialog-select', template: `<div *ngIf="title" class="card-header" [innerHTML]="title"></div> <div class="card-body"> <button class="btn btn-block btn-outline-dark" *ngFor="let selection of selections; index as i" (click)="select(i)" [innerHTML]="selection.html" [ngClass]="selection.class"></button> <button type="button" class="btn btn-block btn-outline-danger" (click)="cancel()" i18n>Cancel</button> </div> ` },] }, ]; /** @nocollapse */ DialogSelectComponent.propDecorators = { "selections": [{ type: Input },], }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class DialogService { /** * @param {?} modalService */ constructor(modalService) { this.modalService = modalService; } /** * @param {?=} title * @param {?=} message * @param {?=} options * @return {?} */ confirm(title = '', message = '', options = {}) { return new Promise((resolve, reject) => { const /** @type {?} */ modalRef = this.modalService.show(DialogConfirmComponent, Object.assign({}, options, { backdrop: 'static' })); modalRef.content.title = title; modalRef.content.message = message; modalRef.content.action.take(1).subscribe(result => { if (result !== false) resolve(result); else reject(result); }); }); } /** * @param {?=} title * @param {?=} message * @param {?=} options * @return {?} */ alert(title = '', message = '', options = {}) { return new Promise((resolve, reject) => { const /** @type {?} */ modalRef = this.modalService.show(DialogAlertComponent, Object.assign({}, options, { backdrop: 'static' })); modalRef.content.title = title; modalRef.content.message = message; modalRef.content.action.take(1).subscribe(result => { if (result !== false) resolve(result); else reject(result); }); }); } /** * @param {?=} title * @param {?=} selections * @param {?=} options * @return {?} */ select(title = '', selections, options = {}) { return new Promise((resolve, reject) => { const /** @type {?} */ modalRef = this.modalService.show(DialogSelectComponent, Object.assign({}, options, { backdrop: 'static' })); modalRef.content.title = title; modalRef.content.selections = selections; modalRef.content.action.take(1).subscribe(result => { if (result !== false) resolve(result); else reject(result); }); }); } } DialogService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ DialogService.ctorParameters = () => [ { type: BsModalService, }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class DialogModule { } DialogModule.decorators = [ { type: NgModule, args: [{ imports: [CommonModule, ModalModule.forRoot()], entryComponents: [ DialogConfirmComponent, DialogAlertComponent, DialogSelectComponent ], declarations: [ DialogAbstractComponent, DialogConfirmComponent, DialogAlertComponent, DialogSelectComponent ], providers: [DialogService] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class FileService$1 { /** * @param {?} http * @param {?} groupService * @param {?} socketService * @param {?} serverHost */ constructor(http, groupService, socketService, serverHost) { this.http = http; this.groupService = groupService; this.socketService = socketService; this.serverHost = serverHost; this.uploadStatusChangeEvent = new Subject(); this.uploadStatus = new Map(); } /** * @return {?} */ get onUploadStatusChange() { return this.uploadStatusChangeEvent.asObservable(); } /** * @param {?} key * @param {?} data * @return {?} */ setUploadStatus(key, data) { this.uploadStatus.set(key, data); this.uploadStatusChangeEvent.next(this.caculatePercent()); } /** * @param {?} key * @param {?} data * @return {?} */ updateUploadStatus(key, data) { let /** @type {?} */ found = this.uploadStatus.get(key); if (found) { Object.assign(found, data); this.uploadStatusChangeEvent.next(this.caculatePercent()); } } /** * @return {?} */ caculatePercent() { let /** @type {?} */ perc = 0; this.uploadStatus.forEach((uploadState, key) => { perc += (uploadState.upload * 0.5 + (typeof uploadState.process === 'undefined' ? 1 : uploadState.process) * 0.5) / this.uploadStatus.size; }); return perc; } /** * @param {?} file * @param {?} opts * @return {?} */ getUrl(file, opts) { return this.http .post(this.serverHost + '/group/file/sign_url', { sign_for: 'upload', name: file.name, type: file.type, size: file.size, process: opts.process }, { headers: { Authorization: `Bearer ${this.groupService.token}` } }) .toPromise(); } /** * @param {?} file * @param {?=} opts * @return {?} */ upload(file, opts = { process: false }) { return new Promise((resolve, reject) => { this.getUrl(file, opts) .then((data) => { this.setUploadStatus(data.file_id, { name: file.name, size: file.size, type: file.type, upload: 0, process: opts.process ? 0 : undefined }); this.http .put(data.signedUrl, file, { reportProgress: true }) .subscribe(event => { console.log(event); // let perc = Math.round(progressEvent.loaded / progressEvent.total * 100); // let info = this.uploadStatus.get(data.file_id); // if (info) info.upload = perc; // observer.next(perc); }, reject, () => { this.updateUploadStatus(data.file_id, { upload: 100 }); if (opts.process === true) this.observeProgress(data.file_id).subscribe(null, reject, () => resolve(data.file_id)); else resolve(data.file_id); }); }) .catch(reject); }).then((sbe_file_id) => this.register(sbe_file_id)); } /** * @param {?} sbe_file_id * @return {?} */ register(sbe_file_id) { return this.http .post(this.serverHost + '/group/file/register', { file_id: sbe_file_id }, { headers: { Authorization: `Bearer ${this.groupService.token}` } }) .toPromise(); // .then(response=>response.json()); } /** * @param {?} file_id * @return {?} */ observeProgress(file_id) { return new Observable(observer => { let /** @type {?} */ uploadStatus = this.uploadStatus.get(file_id); let /** @type {?} */ process = uploadStatus ? uploadStatus.process : undefined; if (process === undefined) observer.error('no processing found'); else if (process === 100) observer.complete(); else { this.socketService.listen('f' + file_id); let /** @type {?} */ subscription = this.socketService .getObservable('f' + file_id) .subscribe(event => { let /** @type {?} */ data = event.data; if (data.match(/download \d+/)) process = Math.round(FileService$1.Weights.download * parseInt(data.replace(/\D/g, ''))); else if (data.match(/convert.low \d+/)) process = Math.round(FileService$1.Weights.download * 100 + FileService$1.Weights.convert * parseInt(data.replace(/\D/g, ''))); else if (data.match(/upload.low \d+/)) process = Math.round((FileService$1.Weights.download + FileService$1.Weights.convert) * 100 + FileService$1.Weights.upload * parseInt(data.replace(/\D/g, ''))); this.updateUploadStatus(file_id, { process: process }); if (process === 100 || data.match('job is done')) { observer.complete(); this.socketService.unlisten('f' + file_id); subscription.unsubscribe(); } else if (data.match('timeout')) { observer.error('timeout'); subscription.unsubscribe(); } else { observer.next(process); } }); } }); } /** * @param {?} letterFiles * @param {?=} process * @return {?} */ multipleUpload(letterFiles, process = true) { this.uploadStatus.clear(); if (process) this.socketService.connect(true); let /** @type {?} */ promises = []; forEach(letterFiles, (file, index) => { if (file instanceof File) { promises.push(this.upload(file, { process: process }).then((fileInfo) => { letterFiles.splice(index, 1, fileInfo); })); } }); return Promise.all(promises).then(() => /** @type {?} */ (letterFiles)); } /** * @param {?} uri * @param {?} name * @return {?} */ download(uri, name) { } } FileService$1.Weights = { download: 0.1, convert: 0.8, upload: 0.1 }; FileService$1.decorators = [ { type: Injectable }, ]; /** @nocollapse */ FileService$1.ctorParameters = () => [ { type: HttpClient, }, { type: GroupService, }, { type: SocketService, }, { type: undefined, decorators: [{ type: Inject, args: [REST_SERVER_HOST,] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class FileServiceModule { /** * @return {?} */ static forRoot() { return { ngModule: FileServiceModule, providers: [FileService$1] }; } } FileServiceModule.decorators = [ { type: NgModule, args: [{ imports: [HttpClientModule] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class GroupInfo { /** * @param {?} params */ constructor(params) { this.type = params.type; this.group_name = params.group_name; this.school_name = params.school_name; } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class Group { /** * @param {?} params */ constructor(params) { this.uid = params.uid; this.gid = params.gid; this.sid = params.sid; this.scopes = params.scopes; this.tabs = params.tabs; this.info = new GroupInfo(params.info); this.groupIdToken = params.groupIdToken; } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class GroupTranslationComponent { } GroupTranslationComponent.decorators = [ { type: Component, args: [{ selector: 'translation-group', template: `<div hidden id="fetching-group" i18n-translation-text="@@fetchingGroup" translation-text="학급정보를 불러오는 중입니다..."></div> ` },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class GroupService$1 { /** * @param {?} http * @param {?} userService * @param {?} translationService * @param {?} serverHost */ constructor(http, userService, translationService, serverHost) { this.http = http; this.userService = userService; this.translationService = translationService; this.serverHost = serverHost; this.group = undefined; this.changeEvent = new BehaviorSubject(this.group); this.translationService.injectComponent(GroupTranslationComponent); } /** * @return {?} */ get onChange() { return this.changeEvent.asObservable(); } /** * @return {?} */ get token() { return this.group ? this.group.groupIdToken : undefined; } /** * @param {?} group_id * @return {?} */ checkIn(group_id) { if (this.group && this.group.gid === group_id) { return Promise.resolve(null); } else { return this.refresh(group_id); } } /** * @param {?} groupTmpToken * @return {?} */ checkInWithTmpToken(groupTmpToken) { const /** @type {?} */ url = `${this.serverHost}/user/tmptoken/exchange`; return this.http .get(url, { headers: { Authorization: 'Bearer ' + groupTmpToken }, responseType: 'text' }) .toPromise() .then(groupIdToken => this.setGroupIdToken(groupIdToken)); } /** * @param {?} scope * @return {?} */ checkPermission(scope) { if (!this.group) return false; return this.group.scopes.indexOf(scope) !== -1; } /** * @param {?=} group_id * @return {?} */ refresh(group_id = undefined) { const /** @type {?} */ url = `${this.serverHost}/group/token`; const /** @type {?} */ httpParams = new HttpParams().set('group_id', '' + (group_id || this.group.gid)); return this.http .get(url, { params: httpParams, headers: { Authorization: 'Bearer ' + this.userService.token }, responseType: 'text' }) .toPromise() .then(groupIdToken => this.setGroupIdToken(groupIdToken)); } /** * @param {?=} root_group_id * @return {?} */ getTree(root_group_id = undefined) { let /** @type {?} */ httpParams = new HttpParams({ fromObject: mapValues({ root_id: root_group_id }, v => '' + v) }); return this.http .get(this.serverHost + '/group/tree/get', { params: httpParams, headers: { Authorization: 'Bearer ' + this.token }, responseType: 'json' }) .toPromise(); } /** * @param {?} params * @return {?} */ classSearch(params) { const /** @type {?} */ url = `${this.serverHost}/classsearch`; let /** @type {?} */ httpParams = new HttpParams({ fromObject: mapValues(pickBy(params, identity), v => '' + v) }); return this.http .get(url, { params: httpParams, headers: { Authorization: 'Bearer ' + this.userService.token }, responseType: 'json' }) .toPromise(); } /** * @param {?} params * @return {?} */ create(params) { const /** @type {?} */ url = `${this.serverHost}/group/create`; return this.http .post(url, params, { responseType: 'text', headers: { Authorization: 'Bearer ' + this.userService.token } }) .toPromise() .then((group_id) => parseInt(group_id)); } /** * @return {?} */ delete() { } /** * @return {?} */ link() { } /** * @return {?} */ unlink() { } /** * @param {?} groupIdToken * @return {?} */ setGroupIdToken(groupIdToken) { if (typeof groupIdToken === 'string') { try { let /** @type {?} */ decoded = jwt_decode(groupIdToken); this.group = new Group({ uid: decoded.uid, gid: decoded.gid, sid: decoded.sid, scopes: decoded.scopes.split(','), info: decoded.info, groupIdToken: groupIdToken, tabs: decoded.tabs }); this.changeEvent.next(this.group); console.log(this.group); } catch (/** @type {?} */ e) { console.error('Invalid JWT token', e); throw 'Invalid JWT token'; } } else { this.group = undefined; this.changeEvent.next(this.group); } } } GroupService$1.decorators = [ { type: Injectable }, ]; /** @nocollapse */ GroupService$1.ctorParameters = () => [ { type: HttpClient, }, { type: UserService, }, { type: TranslationService, }, { type: undefined, decorators: [{ type: Inject, args: [REST_SERVER_HOST,] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class GroupServiceModule { /** * @return {?} */ static forRoot() { return { NgModule: GroupServiceModule, providers: [GroupService$1] }; } } GroupServiceModule.decorators = [ { type: NgModule, args: [{ declarations: [GroupTranslationComponent], entryComponents: [GroupTranslationComponent] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class InfiniteScrollListConfigDefault { constructor() { this.debounce = 400; this.max_size_per_query = 10; } } const /** @type {?} */ INFINITE_SCROLL_LIST_CONFIG_TOKEN = new InjectionToken('InfiniteScrollListConfigInterface'); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class InfiniteScrollListModule { /** * @param {?=} options * @return {?} */ static forRoot(options = {}) { return { ngModule: InfiniteScrollListModule, providers: [] }; } } InfiniteScrollListModule.decorators = [ { type: NgModule, args: [{},] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class InfiniteScrollListService$1 { constructor() { /** * \@property disabled * you can mark the list as disable for example when there is no more to fetch. */ this.disabled = false; /** * \@property token * when promise or observable are pushed, the resolve or emitted value of them can become unwanted. * in this case, specify token when pushing them and change the token to something else * so infinite list will defy the return value. */ this.token = ''; this._list = []; this.listChangeEvent = new BehaviorSubject$1(this._list); } /** * @return {?} */ get list() { return this.listChangeEvent.asObservable(); } /** * @param {?} li * @param {?=} token * @return {?} */ push(li, token = '') { this.token = token; if (li instanceof Promise) { li.then((resolvedLi) => { if (token !== this.token) return; if (Array.isArray(resolvedLi)) resolvedLi.forEach(each => this._list.push(each)); else this._list.push(resolvedLi); // this.listChangeEvent.next(this._list); }); return li; } else if (li instanceof Observable) { let /** @type {?} */ subscription = li.subscribe((emittedLi) => { if (token !== this.token) return; if (Array.isArray(emittedLi)) emittedLi.forEach(each => this._list.push(each)); else this._list.push(emittedLi); // this.listChangeEvent.next(this._list); subscription.unsubscribe(); }); return li.toPromise(); } else if (Array.isArray(li)) { li.forEach(each => this._list.push(each)); // this.listChangeEvent.next(this._list); return Promise.resolve(li); } else { this._list.push(li); // this.listChangeEvent.next(this._list); return Promise.resolve(li); } } /** * @return {?} */ empty() { this._list.splice(0, this._list.length); } /** * @param {?} key * @return {?} */ getMaxId(key) { let /** @type {?} */ item = maxBy(this._list, key); return item ? item[key] : undefined; } /** * @param {?} key * @return {?} */ getMinId(key) { let /** @type {?} */ item = minBy(this._list, key); return item ? item[key] : undefined; } /** * @param {?} condition * @return {?} */ find(condition) { return find(this.list, condition); } /** * @return {?} */ get size() { return this._list.length; } } InfiniteScrollListService$1.decorators = [ { type: Injectable }, ]; /** @nocollapse */ InfiniteScrollListService$1.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class LetterTranslationComponent { constructor() { } /** * @return {?} */ ngOnInit() { } } LetterTranslationComponent.decorators = [ { type: Component, args: [{ selector: 'letter', template: `<div hidden id="writing-letter" i18n-translation-text="@@writingLetter" translation-text="게시중입니다..."></div> ` },] }, ]; /** @nocollapse */ LetterTranslationComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class LetterService { /** * @param {?} http * @param {?} groupService * @param {?} fileService * @param {?} ltgService * @param {?} smsService * @param {?} translationService * @param {?} serverHost */ constructor(http, groupService, fileService, ltgService, smsService, translationService, serverHost) { this.http = http; this.groupService = groupService; this.fileService = fileService; this.ltgService = ltgService; this.smsService = smsService; this.translationService = translationService; this.serverHost = serverHost; this.translationService.injectComponent(LetterTranslationComponent); } /** * @param {?} letter * @return {?} */ _write(letter) { return this.http .post(this.serverHost + '/group/letter/write', letter, { headers: { Authorization: 'Bearer ' + this.groupService.token }, responseType: 'text' }) .toPromise(); } /** * @param {?} letter * @param {?=} method * @return {?} */ write(letter, method = 'push') { return this._write(letter) .then((letter_id) => (letter.letter_id = parseInt(letter_id))) .then(() => letter.files.length > 0 ? (/** @type {?} */ (this.fileService.multipleUpload(letter.files))) : true) .then(() => letter.files.length > 0 ? this.updateFiles({ letter_id: letter.letter_id, files: letter.files }) : true) .then(() => letter.mailmerge.length > 0 ? this.updateMailMerge({ letter_id: letter.letter_id, list: letter.mailmerge }) : true) .then(() => letter.sms_targets.length > 0 ? this.smsService.send({ msg: letter.sms_content || letter.content, targets: letter.sms_targets, selector_id: 'l' + letter.letter_id }) : true) .then(() => this.ltgService.issue({ letter_id: letter.letter_id, targets: letter.targets, method: method })); } /** * @param {?} params * @return {?} */ updateFiles(params) { if (!Array.isArray(params.files) || params.files.length === 0) return Promise.resolve(null); return this.http .post(this.serverHost + '/group/letter/updateFiles', params, { responseType: 'json', headers: { Authorization: 'Bearer ' + this.groupService.token } }) .toPromise(); } /** * @param {?} params * @return {?} */ updateMailMerge(params) { if (!this.groupService.token) return Promise.reject('group token missing.'); return this.http .post(this.serverHost + '/group/letter/updateMailMerge', params, { responseType: 'json', headers: { Authorization: 'Bearer ' + this.groupService.token } }) .toPromise(); } /** * @param {?} params * @return {?} */ remove(params) { return this.http .post(this.serverHost + '/group/letter/remove', params, { responseType: 'json', headers: { Authorization: 'Bearer ' + this.groupService.token } }) .toPromise(); } } LetterService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ LetterService.ctorParameters = () => [ { type: HttpClient, }, { type: GroupService, }, { type: FileService, }, { type: LetterToGroupService, }, { type: SmsService, }, { type: TranslationService, }, { type: undefined, decorators: [{ type: Inject, args: [REST_SERVER_HOST,] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class LetterServiceModule { /** * @return {?} */ static forRoot() { return { ngModule: LetterServiceModule, providers: [LetterService] }; } } LetterServiceModule.decorators = [ { type: NgModule, args: [{ declarations: [LetterTranslationComponent], entryComponents: [LetterTranslationComponent] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class Letter { /** * @param {?=} data */ constructor(data = {}) { this.letter_id = undefined; this.type = 'schoolnews'; this.title = ''; this.content = ''; this.targets = []; this.simplifiedTargets = []; this.parents = true; this.students = true; this.etc = true; this.fixed_for = undefined; this.files = []; this.mailmerge = []; this.sms_content = ''; this.sms_targets = []; this.questionnaire = undefined; this.survey_id = undefined; this.survey_id_g3 = undefined; for (let /** @type {?} */ key in data) { if (this.hasOwnProperty(key)) this[key] = data[key]; } } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class LetterToGroupService$1 { /** * @param {?} http * @param {?} groupService * @param {?} pubsubService * @param {?} serverHost */ constructor(http, groupService, pubsubService, serverHost) { this.http = http; this.groupService = groupService; this.pubsubService = pubsubService; this.serverHost = serverHost; this.infiniteScroll = new InfiniteScrollListService(); } /** * @param {?=} params * @return {?} */ loadMore(params = {}) { if (!this.groupService.token) return; let /** @type {?} */ httpParams = new HttpParams({ fromObject: mapValues(pickBy(params, identity), v => '' + v) }); return this.http .get(this.serverHost + '/group/ltg/get', { params: httpParams, headers: { Authorization: 'Bearer ' + this.groupService.token }, responseType: 'json' }) .toPromise(); } /** * @param {?=} params * @return {?} */ loadMoreFixedList(params = {}) { if (!this.groupService.token) return; let /** @type {?} */ httpParams = new HttpParams({ fromObject: mapValues(pickBy(params, identity), v => '' + v) }); return this.http .get(this.serverHost + '/group/ltg/fixed', { params: httpParams, headers: { Authorization: 'Bearer ' + this.groupService.token } }) .toPromise(); } /** * @param {?=} params * @return {?} */ loadMoreSurveyList(params = {}) { if (!this.groupService.token) return; let /** @type {?} */ httpParams = new HttpParams({ fromObject: mapValues(pickBy(params, identity), v => '' + v) }); return this.http .get(this.serverHost + '/group/ltg/withsurvey', { params: httpParams, headers: { Authorization: 'Bearer ' + this.groupService.token } }) .toPromise(); } /** * @param {?} params * @return {?} */ issue(params) { return this.http .post(this.serverHost + '/group/ltg/issue', params, { headers: { Authorization: 'Bearer ' + this.groupService.token }, responseType: 'json' }) .toPromise(); } /** * @param {?} ltg_id * @return {?} */ like(ltg_id) { return this.http .post(this.serverHost + '/group/ltg/like', { ltg_id: ltg_id }, { headers: { Authorization: 'Bearer ' + this.groupService.token } }) .toPromise(); } /** * @param {?} ltg_id * @return {?}