inet-layout
Version:
iNet Layout ===
1 lines • 409 kB
Source Map (JSON)
{"version":3,"file":"inet-layout.mjs","sources":["../../../projects/inet-layout/src/lib/core/services/organization.service.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/navbar/navbar.component.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/navbar/navbar.component.html","../../../projects/inet-layout/src/lib/layout/bootstrap/userlog/userlog.service.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/userlog/time-ago.service.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/userlog/time-ago.pipe.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/userlog/userlogs/userlogs.component.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/userlog/userlogs/userlogs.component.html","../../../projects/inet-layout/src/lib/layout/bootstrap/abstract-side-nav.component.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/message-side-nav/message-side-nav.component.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/message-side-nav/message-side-nav.component.html","../../../projects/inet-layout/src/lib/layout/bootstrap/app-side-nav/app-side-nav.component.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/app-side-nav/app-side-nav.component.html","../../../projects/inet-layout/src/lib/layout/bootstrap/social-side-nav/social-side-nav.component.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/social-side-nav/social-side-nav.component.html","../../../projects/inet-layout/src/lib/layout/bootstrap/layout.component.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/layout.component.html","../../../projects/inet-layout/src/lib/layout/bootstrap/vertical-layout/vertical-layout.component.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/vertical-layout/vertical-layout.component.html","../../../projects/inet-layout/src/lib/layout/bootstrap/user-profile/must-match.validator.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/contact.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/user-profile/user-profile-info/user-profile-info.component.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/user-profile/user-profile-info/user-profile-info.component.html","../../../projects/inet-layout/src/lib/layout/bootstrap/user-profile/global-contact.service.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/user-profile/user-profile/user-profile.component.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/user-profile/user-profile/user-profile.component.html","../../../projects/inet-layout/src/lib/layout/bootstrap/common-toolbar/common-toolbar.component.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/common-toolbar/common-toolbar.component.html","../../../projects/inet-layout/src/lib/layout/bootstrap/profile/bootstrap-user-profile.component.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/profile/bootstrap-user-profile.component.html","../../../projects/inet-layout/src/lib/layout/bootstrap/bootstrap-layout-routing.module.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/user-profile/access-role/access-role.component.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/user-profile/access-role/access-role.component.html","../../../projects/inet-layout/src/lib/layout/bootstrap/user-profile/user-profile.module.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/userlog/userlog.module.ts","../../../projects/inet-layout/src/lib/core/route-reusable-strategy.ts","../../../projects/inet-layout/src/lib/core/store/state/settings.state.ts","../../../projects/inet-layout/src/lib/core/store/actions/settings.action.ts","../../../projects/inet-layout/src/lib/core/store/reducers/settings.reducer.ts","../../../projects/inet-layout/src/lib/core/model/cloud-config.ts","../../../projects/inet-layout/src/lib/core/services/local-storage.service.ts","../../../projects/inet-layout/src/lib/core/store/reducers/local-storage.reducer.ts","../../../projects/inet-layout/src/lib/core/store/reducers/app.reducers.ts","../../../projects/inet-layout/src/lib/core/store/selectors/settings.selector.ts","../../../projects/inet-layout/src/lib/core/store/effects/settings.effects.ts","../../../projects/inet-layout/src/lib/core/calista-core.module.ts","../../../projects/inet-layout/src/lib/layout/bootstrap/bootstrap-layout.module.ts","../../../projects/inet-layout/src/lib/layout/directive/menu.directive.ts","../../../projects/inet-layout/src/lib/layout/directive/toolbar.directive.ts","../../../projects/inet-layout/src/lib/layout/directive/navbar-item.directive.ts","../../../projects/inet-layout/src/lib/layout/directive/navbar-menu.directive.ts","../../../projects/inet-layout/src/lib/layout/directive/profile-item.directive.ts","../../../projects/inet-layout/src/lib/layout/directive/navbar-search.directive.ts","../../../projects/inet-layout/src/lib/layout/directive/logo.directive.ts","../../../projects/inet-layout/src/lib/layout/directive/action-menu.directive.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/plugin/plugin-utils.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/calista.interface.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/calista-menu.service.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/plugin/calista-plugin.service.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/navbar/calista-navbar.component.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/navbar/calista-navbar.component.html","../../../projects/inet-layout/src/lib/layout/calista-layout/plugin/plugin-view/plugin-view.component.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/plugin/plugin-view/plugin-view.component.html","../../../projects/inet-layout/src/lib/layout/calista-layout/plugin/app-plugin.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/plugin/document-viewer/document-viewer.component.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/plugin/document-viewer/document-viewer.component.html","../../../projects/inet-layout/src/lib/layout/calista-layout/plugin/plugin-sub/plugin-sub.component.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/plugin/plugin-sub/plugin-sub.component.html","../../../projects/inet-layout/src/lib/layout/calista-layout/abstract-calista-side-nav.component.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/workspace-side-nav/workspace-side-nav.component.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/workspace-side-nav/workspace-side-nav.component.html","../../../projects/inet-layout/src/lib/layout/calista-layout/calista-menu/calista-menu.component.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/calista-menu/calista-menu.component.html","../../../projects/inet-layout/src/lib/layout/calista-layout/calista-layout.component.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/calista-layout.component.html","../../../projects/inet-layout/src/lib/layout/calista-layout/profile/user-profile/must-match.validator.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/profile/profile.service.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/profile/user-profile/user-profile.component.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/profile/user-profile/user-profile.component.html","../../../projects/inet-layout/src/lib/layout/calista-layout/calista-layout-routing.module.ts","../../../projects/inet-layout/src/lib/core/translate/calista-trans-loader.ts","../../../projects/inet-layout/src/lib/core/services/cloud-translate.service.ts","../../../projects/inet-layout/src/lib/core/translate/cloud-translate.module.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/plugin/plugin.module.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/profile/profile.module.ts","../../../projects/inet-layout/src/lib/layout/calista-layout/calista-layout.module.ts","../../../projects/inet-layout/src/lib/layout/index.ts","../../../projects/inet-layout/src/public-api.ts","../../../projects/inet-layout/src/inet-layout.ts"],"sourcesContent":["import {Injectable} from '@angular/core';\nimport {CoreService, HttpClientService, iNet} from 'inet-core';\nimport {Observable} from \"rxjs\";\nimport {shareReplay, tap} from \"rxjs/operators\";\nimport {Organization, OrganizationInformation} from \"inet-ui\";\n\n@Injectable({\n providedIn: 'root'\n})\nexport class OrganizationService {\n private $orgCache?: Observable<Organization> | null;\n\n private url = {\n firm_load: iNet.getPUrl('cloud/firmorganid/load'),\n firm_update: iNet.getPUrl('cloud/firmprofile/update'),\n update_logo: iNet.getPUrl('cloud/firmprofile/logoupdate'),\n view_logo: iNet.getPUrl('plugin/firmlogo/view'),\n // For Essentials\n //load_info: iNet.getPUrl('gl/organ/profile/load'),\n load_info: iNet.getPUrl('cloud/firmprofile/load'),\n update_info: iNet.getPUrl('cloud/firmprofile/update'),\n search_org: iNet.getPUrl('plugin/organization/search'),\n view_org: iNet.getPUrl('plugin/firmprofile/view')\n //update_logo: iNet.getPUrl('gl/organ/profile/logo')\n };\n\n constructor(private http: HttpClientService, private coreService: CoreService) {\n }\n\n firmLoad(): Observable<OrganizationInformation> {\n this.http.showLoading();\n return this.http.getJSON(this.url.firm_load, {organId: iNet.getOrganId()})\n .pipe(tap((res: OrganizationInformation) => res))\n }\n\n // saveLogoOrganization(params: any): Observable<any> {\n // return this.http.postJSON(this.url.save_logo, params);\n // }\n\n firmUpdate(orgInfo: OrganizationInformation): Observable<any> {\n this.http.showLoading();\n return this.http.postJSON(this.url.firm_update, orgInfo);\n }\n\n updateLogo(data: FormData): Observable<any> {\n this.http.showLoading();\n return this.http.post(this.url.update_logo, data);\n }\n\n removeLogo(params: any): Observable<any> {\n this.http.showLoading();\n return this.http.postJSON(this.url.update_logo, params);\n }\n\n load(): Observable<Organization> {\n if (!this.$orgCache) {\n this.http.showLoading();\n this.$orgCache = this.http.getJSON(this.url.view_org)\n .pipe(shareReplay(1))\n }\n return this.$orgCache;\n }\n loadInfo(): Observable<any>{\n this.http.showLoading();\n return this.http.postJSON(this.url.load_info);\n }\n\n update(data: Organization): Observable<any> {\n this.http.showLoading();\n // Clone data for update\n const org: any = Object.assign(new Organization(), data);\n org.officeAddressStr = JSON.stringify(org.officeAddress);\n delete org.officeAddress;\n delete org.createdDate;\n delete org.createdBy;\n delete org.banks;\n delete org.busAces;\n this.$orgCache = null;\n return this.http.postJSON(this.url.update_info, org);\n }\n\n searchOrganization(params: any = {}): Observable<any> {\n return this.http.postJSON(this.url.search_org, params);\n }\n\n getLogoUrlByOrganization(orgInfo: Organization): string {\n /*\n if (!orgInfo.logo) {\n return iNet.BLANK_IMAGE_URL;\n }\n */\n return `${this.url.view_logo}?version=${orgInfo.modifiedDate}`;\n //return this.coreService.getFileUrl(orgInfo.logo + `?version=${orgInfo.modifiedDate}`);\n }\n\n getLogoUrl(): string {\n return this.url.view_logo;\n }\n\n viewInfo(): Observable<any>{\n this.http.showLoading();\n return this.http.postJSON(this.url.view_org);\n }\n}\n","import {\n Component,\n OnInit,\n EventEmitter,\n Output,\n TemplateRef,\n ElementRef,\n Input, ViewChild\n} from '@angular/core';\nimport {CoreService, iNet, SecurityService, UserProfileService} from 'inet-core';\nimport {TranslateService} from \"@ngx-translate/core\";\nimport {OrganizationService} from \"../../../core/services/organization.service\";\nimport {Router} from \"@angular/router\";\nimport {CloudTranslateService, NotifyMessageService} from \"inet-ui\";\nexport const BLANK_IMAGE_URL = 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==';\n@Component({\n selector: 'app-admin-navbar',\n templateUrl: './navbar.component.html',\n styleUrls: ['./navbar.component.scss'],\n standalone: false\n})\nexport class AdminNavbarComponent implements OnInit {\n\n @Input() navbarItemTpl!: TemplateRef<ElementRef>;\n @Input() profileItemTpl!: TemplateRef<ElementRef>;\n @Input() navbarMenuTpl!: TemplateRef<ElementRef>;\n @Input() titleMenuTpl!: TemplateRef<ElementRef>;\n @Input() hideToggler: boolean = false;\n @Input() hideTogglerButton: boolean = false;\n @Input() hideCompanyMenu: boolean = false;\n @Input() hideProfileMenu: boolean = false;\n @Input() hideSearch: boolean = false;\n @Input() applicationName?: string;\n @Input() homeRouterLink?: string;\n @Input() noteRouterLink?: string;\n @Input() messageCount: string = '';\n @Input() hideBrandName: boolean = true;\n @Input() hideLogo: boolean = false;\n @Output() onToggleMenu = new EventEmitter<void>();\n @Output() onToggleMessageSideNav = new EventEmitter<void>();\n @Output() onToggleUserLogSideNav = new EventEmitter<void>();\n @Output() onToggleAppSideNav = new EventEmitter<void>();\n @Output() onToggleChatSideNav = new EventEmitter<void>();\n @Output() onToggleSocialSideNav = new EventEmitter<void>();\n @Output() onToggleNoteSideNav = new EventEmitter<void>();\n @Output() onClickLogo = new EventEmitter<string>();\n @Input() visibleChatIcon: boolean = !!iNet.getPrefix();\n @Input() visibleMessageIcon: boolean = !!iNet.getPrefix();\n @Input() visibleUserLogIcon: boolean = !!iNet.getPrefix();\n @Input() visibleAppIcon: boolean = !!iNet.getPrefix();\n @Input() visibleNoteIcon: boolean = false;\n @Input() visibleSearch: boolean = false;\n @Input() visibleLogo: boolean = true;\n //externalUrl = 'javascript:;';\n avatarUrl: string = BLANK_IMAGE_URL;\n displayName = iNet.getDisplayName();\n @Input() brandName: string = '';\n\n @ViewChild('brandLink') brandLink!: ElementRef;\n langs: Array<string> = [];\n currentLanguage: string = 'en';\n\n logoUrl?: string;\n\n constructor(private coreService: CoreService,\n private router: Router,\n private userProfileService: UserProfileService,\n private orgService: OrganizationService,\n private cloudTranslateService: CloudTranslateService,\n private messageService: NotifyMessageService,\n public translate: TranslateService,\n private securityService : SecurityService) {\n }\n\n ngOnInit() {\n //this.brandName = !iNet.isEmpty(this.applicationName) ? `${this.applicationName} - ${this.orgName}` : this.orgName;\n //this.externalUrl = window.location.protocol + '\\/\\/' + window.location.host + '\\/' + iNet.firmPrefix;\n this.langs = this.translate.getLangs(); // Languages\n this.currentLanguage = this.cloudTranslateService.getCurrentLang();\n if(this.isUser()) {\n if (!!iNet.getPrefix()) {\n this.userProfileService.getFullName().then(fullname => {\n this.displayName = fullname || iNet.getDisplayName() || iNet.getUserName();\n });\n this.userProfileService.getAvatarUrl().then(url => {\n this.avatarUrl = url;\n });\n if(this.visibleMessageIcon){\n this.countMessage();\n }\n //Load logo for header\n this.logoUrl = this.orgService.getLogoUrl();\n }\n }\n }\n\n private isUser(): boolean {\n if(!iNet.getUserName()) {\n return false;\n }\n return this.securityService.hasRole('firmuser,firm_user,community');\n }\n logout() {\n if (this.coreService.getEnvironment()['production']) {\n this.coreService.logout();\n }\n }\n\n toggleMenu() {\n this.onToggleMenu.emit();\n }\n\n toggleMessageSideNav($event: any) {\n this.onToggleMessageSideNav.emit();\n }\n toggleUserLogSideNav($event: any) {\n this.onToggleUserLogSideNav.emit();\n }\n\n\n toggleAppSideNav($event: any) {\n this.onToggleAppSideNav.emit();\n }\n\n // toggleSocialSideNav($event) {\n // this.onToggleSocialSideNav.emit();\n // }\n\n toggleChatSideNav($event: any) {\n this.onToggleChatSideNav.emit();\n }\n\n toggleNoteNav($event: any) {\n this.onToggleNoteSideNav.emit()\n }\n\n changeLanguage(lang: string) {\n this.translate.use(lang).subscribe(\n (v: any) => {\n this.currentLanguage = lang;\n this.cloudTranslateService.setCurrentLang(lang);\n if (this.coreService.getEnvironment()['production']) {\n this.coreService.updateLanguage(lang, function () {\n window.location.reload();\n });\n } else {\n window.location.reload();\n }\n }\n );\n }\n\n updateImageUrl($event: any) {\n this.avatarUrl = UserProfileService.DEFAULT_AVATAR_URL;\n }\n\n updateBlankImage($event: any) {\n if ($event) {\n this.logoUrl = BLANK_IMAGE_URL;\n }\n }\n\n countMessage(){\n this.messageService.count().then((count: number) => {\n //console.log('count')\n this.messageCount = (count && count > 0) ? count.toString() : '';\n });\n }\n\n setMessageCount(v: string) {\n this.messageCount = v;\n }\n clickLogo($event: any) {\n this.onClickLogo.emit(this.homeRouterLink);\n }\n}\n","<nav class=\"navbar navbar-expand-md\">\n <div *ngIf=\"visibleLogo\" class=\"navbar-header logo-area p-1\" (click)=\"clickLogo($event)\" [routerLink]=\"homeRouterLink\">\n <ng-container>\n <img *ngIf=\"!hideLogo && logoUrl\" alt=\"Logo\" class=\"logo\" [title]=\"brandName\" [src]=\"logoUrl\"\n (error)=\"updateBlankImage($event)\">\n <a *ngIf=\"!hideBrandName\" #brandLink class=\"navbar-brand\">{{brandName}}</a>\n </ng-container>\n </div>\n <ng-template [ngTemplateOutlet]=\"navbarMenuTpl\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"titleMenuTpl\"></ng-template>\n <div class=\"navbar-collapse collapse in\" id=\"navbar-collapse\" aria-expanded=\"true\">\n <ul class=\"navbar-nav navbar-right ml-auto d-flex align-items-center\">\n <ng-template [ngTemplateOutlet]=\"navbarItemTpl\"></ng-template>\n <li *ngIf=\"visibleNoteIcon\" class=\"nav-item\"><a href=\"javascript:;\" (click)=\"toggleNoteNav($event)\"><i\n class=\"fa fa-pencil-square-o\" aria-hidden=\"true\"></i></a>\n </li>\n\n <div *ngIf=\"visibleSearch\" class=\"search-input-group\">\n <div class=\"input-group input-group-sm\">\n <div class=\"input-group-prepend\">\n <span class=\"input-group-text border-radius-left\">\n <i class=\"fa fa-search\" aria-hidden=\"true\" ></i>\n </span>\n </div>\n <input type=\"text\"\n class=\"form-control text-white border-radius-right\">\n </div>\n </div>\n <li *ngIf=\"visibleMessageIcon\" class=\"nav-item\" [ngClass]=\"{'icon-animated-heartbeat': messageCount}\">\n <a href=\"javascript:;\" (click)=\"toggleMessageSideNav($event)\">\n <i class=\"fa fa-bell rotate-15\"></i><span class=\"number\">{{messageCount}}</span>\n </a>\n </li>\n <li *ngIf=\"visibleUserLogIcon\" class=\"nav-item\">\n <a href=\"javascript:;\" (click)=\"toggleUserLogSideNav($event)\">\n <i class=\"fa fa-history\"></i>\n </a>\n </li>\n <li *ngIf=\"visibleAppIcon\" class=\"nav-item\"><a href=\"javascript:;\" (click)=\"toggleAppSideNav($event)\"><i\n class=\"fa fa-th-large\"></i></a></li>\n <li id=\"user-profile\" class=\"light-blue user-profile\">\n <a *ngIf=\"displayName\" class=\"dropdown-toggle\" href=\"javascript:;\" data-toggle=\"dropdown\">\n <img [src]=\"avatarUrl\" [alt]=\"displayName\" class=\"nav-user-photo\" (error)=\"updateImageUrl($event)\">\n <!--span class=\"user-info\" [title]=\"displayName\"><small>{{'COMMON.WELCOME' | translate}},</small>{{displayName}}</span-->\n </a>\n <div class=\"dropdown-menu\">\n <a *ngIf=\"!hideProfileMenu\" class=\"dropdown-item\" href=\"javascript:;\" routerLink=\"user-profile\">\n <i class=\"fa fa-user\"></i> {{'COMMON.MENU.USER_PROFILE' | translate}}\n </a>\n <ng-template [ngTemplateOutlet]=\"profileItemTpl\"></ng-template>\n <a class=\"dropdown-submenu pull-left\">\n <a class=\"dropdown-item dropdown-toggle\" href=\"#\">\n <i class=\"fa fa-language\"></i> {{'COMMON.MENU.LANGUAGE' | translate}}\n <small class=\"text-lowercase\">({{ currentLanguage | translate }})</small>\n </a>\n <div class=\"dropdown-menu\">\n <a class=\"dropdown-item\" href=\"javascript:;\" *ngFor=\"let lang of langs\"\n (click)=\"changeLanguage(lang)\" [ngClass]=\"{'active': currentLanguage===lang}\">\n <i class=\"fa\"\n [ngClass]=\"{'fa-check': currentLanguage===lang}\"></i> {{ lang | translate }}\n </a>\n </div>\n <div class=\"dropdown-divider\"></div>\n </a>\n <a class=\"dropdown-item\" href=\"javascript:;\" (click)=\"logout()\">\n <i class=\"fa fa-sign-out\"></i> {{'COMMON.MENU.LOGOUT' | translate}}\n </a>\n </div>\n </li>\n </ul>\n </div>\n</nav>\n","import { Injectable } from '@angular/core';\nimport {HttpClientService} from \"inet-core\";\nimport {Observable} from \"rxjs\";\ndeclare let iNet: any;\n@Injectable({\n providedIn: 'root'\n})\nexport class UserlogService {\n private url = {\n list_user_log: iNet.getPUrl('plugin/memberaccess'),\n };\n constructor(private http: HttpClientService) { }\n\n loadData(params: any = {}): Observable<any>{\n this.http.showLoading();\n return this.http.getJSON(this.url.list_user_log, params);\n }\n}\n","import {Injectable} from '@angular/core';\nimport {Observable, of, timer} from 'rxjs';\nimport {delay, expand, skip} from 'rxjs/operators';\n\nexport const MINUTE = 60;\nexport const HOUR = MINUTE * 60;\nexport const DAY = HOUR * 24;\n/*\nexport const WEEK = DAY * 7;\nexport const MONTH = DAY * 30;\nexport const YEAR = DAY * 365;\n\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TimeAgoService {\n\n constructor() {\n }\n\n tick(then: number): Observable<any> {\n return of(0)\n .pipe(\n delay(60000),\n expand(() => {\n const now = Date.now();\n const seconds = Math.round(Math.abs(now - then) / 1000);\n //console.log('[tick]', new Date(), seconds);\n const period =\n seconds < MINUTE\n ? 1000\n : seconds < HOUR\n ? 1000 * MINUTE\n : seconds < DAY\n ? 1000 * HOUR\n : 0;\n //console.log('[period]',period);\n return period ? timer(period) : of(0);\n }),\n skip(1)\n );\n }\n}\n\n","import {ChangeDetectorRef, OnDestroy, Pipe, PipeTransform} from '@angular/core';\nimport { format, register } from 'timeago.js';\nimport {TimeAgoService} from \"./time-ago.service\";\nimport {Subject, Subscription} from \"rxjs\";\nimport {filter} from \"rxjs/operators\";\nimport {CloudTranslateService} from \"inet-ui\";\nregister('vi', (number: any, index: any, total_sec: any): [string, string] => {\n // number: the timeago / timein number;\n // index: the index of array below;\n // total_sec: total seconds between date to be formatted and today's date;\n // @ts-ignore\n return [\n ['vừa xong', 'một lúc'],\n ['%s giây trước', '%s giây nữa'],\n ['1 phút trước', '1 phút nữa'],\n ['%s phút trước', '%s phút nữa'],\n ['1 giờ trước', '1 giờ nữa'],\n ['%s giờ trước', '%s giờ nữa'],\n ['1 ngày trước', '1 ngày nữa'],\n ['%s ngày trước', '%s ngày nữa'],\n ['1 tuần trước', '1 tuần nữa'],\n ['%s tuần trước', '%s tuần nữa'],\n ['1 tháng trước', '1 tháng nữa'],\n ['%s tháng trước', '%s tháng nữa'],\n ['1 năm trước', '1 năm nữa'],\n ['%s năm trước', '%s năm nữa']\n ][index];\n});\n\n@Pipe({\n name: 'timeAgo',\n pure: false,\n standalone: false\n})\nexport class TimeAgoPipe implements PipeTransform, OnDestroy {\n private clockSubscription!: Subscription;\n private date!: number;\n private value!: string;\n private live: boolean = true;\n private locale!: string;\n stateChanges = new Subject<void>();\n\n constructor(cd: ChangeDetectorRef,\n private timeService: TimeAgoService,\n private cloudTranslateService: CloudTranslateService) {\n\n this.stateChanges.subscribe(() => {\n this.value = format(this.date, this.locale);\n cd.markForCheck();\n });\n }\n\n transform(date: any, live?: boolean): string {\n this.date = date;\n if(live){\n this.live = live;\n }\n this.locale = this.cloudTranslateService.getCurrentLang() || 'vi';\n if (this.date) {\n if (this.clockSubscription) {\n this.clockSubscription.unsubscribe();\n // this.clockSubscription = undefined;\n }\n this.clockSubscription = this.timeService.tick(this.date)\n .pipe(filter(() => this.live, this))\n .subscribe((v) => {\n this.stateChanges.next()\n\n });\n this.stateChanges.next();\n\n return format(this.date, this.locale);\n } else {\n //throw new SyntaxError(`Expected a valid date, received: ${date}`);\n return '';\n }\n }\n\n ngOnDestroy() {\n if (this.clockSubscription) {\n this.clockSubscription.unsubscribe();\n // this.clockSubscription = undefined;\n }\n this.stateChanges.complete();\n }\n}\n","import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';\nimport {UserlogService} from \"../userlog.service\";\nimport {MemberAccess} from \"../memberaccess\";\nimport {ErrorMessage} from \"inet-core\";\n\n\n@Component({\n selector: 'app-userlogs',\n templateUrl: './userlogs.component.html',\n styleUrls: ['./userlogs.component.scss'],\n standalone: false\n})\nexport class UserlogsComponent implements OnInit {\n @Input() opened: boolean = false;\n @Output() onClose = new EventEmitter<boolean>();\n memberAccess: MemberAccess[] = [];\n constructor(private userlogService: UserlogService) { }\n\n ngOnInit(): void {\n this.init();\n }\n init(){\n this.userlogService.loadData({pageSize : 20, pageNumber: 0}).subscribe((data) => {\n if(data.type !== ErrorMessage.TYPE){\n this.memberAccess = data?.items || [];\n }\n })\n }\n closeUserlog(){\n this.onClose.emit(true);\n }\n}\n","<div class=\"slide-nav \" [ngClass]=\"{'opened': opened}\">\n <div class=\" bg-white pt-2\">\n <div class=\"d-flex justify-content-between align-items-center w-100 mb-2 px-3\">\n <div style=\"font-size: 16px\" class=\"mb-0 header\">ACCESS HISTORY</div>\n <button class=\"btn btn-sm btn-light bg-white border-0\" (click)=\"closeUserlog()\">\n <i class=\"fa fa-times text-primary\" aria-hidden=\"true\"></i></button>\n </div>\n <div style=\"height: calc( 100vh - 95px );overflow: auto;\" class=\"mb-2\">\n <div class=\"mx-3\">\n <div *ngFor=\"let access of memberAccess\" class=\"rounded bg-user-log w-100 d-flex mb-3 row m-0 pt-2 f-12\">\n <div class=\" d-flex justify-content-between mb-2 row m-0 col-sm-12 px-2\">\n <div class=\"p-2 rounded bg-light-blue col-sm-4 d-flex align-items-center justify-content-center\">\n <p class=\"common-font text-primary text-center mb-0\"><i class=\"fa fa-history mr-1\" aria-hidden=\"true\"></i> {{access?.logtime | timeAgo}}\n </p>\n<!-- <p class=\"mb-0 common-font text-primary\">{{access?.logtime | date: 'dd/MM/yyy'}}</p>-->\n </div>\n <div class=\" common-font col-sm-8 \">\n <p class=\" mb-2\">Browser: <span class=\"text-primary ml-2\">{{access?.browser}}</span></p>\n <div class=\"mb-0 font-weight-bold d-flex align-items-center mb-0\"><i\n class=\"fa fa-adn fa-2x text-primary mr-2\"\n aria-hidden=\"true\"></i> {{access?.application }}</div>\n </div>\n\n </div>\n <div class=\" d-flex justify-content-between mb-2 row m-0 col-sm-12\">\n <div class=\" d-flex align-items-center common-font col-sm-4 p-0\">\n <div class=\"font-weight-bold d-flex align-items-center mb-0\"><i\n class=\"fa fa-laptop text-primary mr-2\" aria-hidden=\"true\"></i> <span\n class=\"font-weight-bold\">{{access?.deviceType }}</span></div>\n </div>\n <div class=\" common-font col-sm-8\">\n<!-- <p class=\"mb-2\">Url access: <span class=\"text-primary ml-2\">{{access?.serviceName}}</span>-->\n<!-- </p>-->\n <div class=\"font-weight-bold d-flex align-items-center mb-0\"><i\n class=\"fa fa-map-marker fa-2x text-primary mr-2\" aria-hidden=\"true\"></i> <span\n class=\"font-weight-bold\">{{access?.remoteAddress}}</span></div>\n </div>\n </div>\n </div>\n\n </div>\n </div>\n </div>\n</div>\n","import {\n Component,\n ElementRef,\n EventEmitter,\n HostListener,\n Input,\n OnChanges, OnDestroy,\n Output,\n SimpleChanges\n} from \"@angular/core\";\n\n@Component({\n selector: 'app-admin-side-nav',\n template: ``,\n standalone: false\n})\n\nexport class AbstractSideNavComponent implements OnChanges, OnDestroy {\n @Input() opened: boolean = false;\n @Output() onClose = new EventEmitter<boolean>();\n @Output() onClear = new EventEmitter<boolean>();\n @Output() onLoad = new EventEmitter<boolean>();\n private overflowCls = 'overflow-hidden';\n constructor(public elementRef: ElementRef) { }\n\n ngOnChanges(changes: SimpleChanges) {\n const currentValue = changes['opened'][\"currentValue\"];\n setTimeout(() => {\n if (currentValue) {\n this.open();\n } else if (changes['opened']['previousValue'] != currentValue) {\n this.close();\n }\n }, 1)\n }\n\n open() {\n if(!document.body.classList.contains(this.overflowCls)) {\n document.body.classList.add(this.overflowCls);\n }\n }\n\n close() {\n if(document.body.classList.contains(this.overflowCls)) {\n document.body.classList.remove(this.overflowCls);\n }\n this.opened = false;\n this.onClose.emit(this.opened);\n }\n\n // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method\n ngOnDestroy(): void {\n }\n\n @HostListener('document:click', ['$event'])\n clickOut(event: any) {\n if (!this.elementRef.nativeElement.contains(event.target)\n && this.opened && !event.target.closest('.nav-item') &&\n !event.target.closest('.search-input__icon')) {\n this.close();\n }\n }\n @HostListener('click', ['$event'])\n clickInside(event: any) {\n if(this.elementRef.nativeElement.contains(event.target)) {\n\n }\n }\n}\n","import {\n Component, SimpleChanges, ElementRef\n} from '@angular/core';\nimport {ResponseData, SecurityService} from \"inet-core\";\nimport {AbstractSideNavComponent} from \"../abstract-side-nav.component\";\nimport {NotifyMessage, NotifyMessageService} from \"inet-ui\";\ndeclare let iNet: any;\n\n@Component({\n selector: 'app-admin-message-side-nav',\n templateUrl: './message-side-nav.component.html',\n styleUrls: ['./message-side-nav.component.scss'],\n standalone: false\n})\nexport class MessageSideNavComponent extends AbstractSideNavComponent {\n // keyword: string;\n loaded = false;\n messages: NotifyMessage[] = [];\n totalMessage: number = 0;\n pageNumber= 0;\n pageSize = 10;\n constructor(private service: NotifyMessageService,\n public elementRef: ElementRef,\n private securityService : SecurityService) {\n super(elementRef);\n }\n\n ngOnChanges(changes: SimpleChanges) {\n const currentValue = changes['opened'][\"currentValue\"];\n setTimeout(() => {\n if (currentValue) {\n this.open();\n if (!this.loaded) {\n this.pageNumber = 0;\n this.listMessage({pageSize: this.pageSize, pageNumber: this.pageNumber, notifylist: true});\n }\n } else {\n this.close();\n }\n }, 10)\n\n }\n\n private isUser(): boolean {\n if(!iNet.username) {\n return false;\n }\n return this.securityService.hasRole('firmuser,firm_user');\n }\n\n listMessage(params: any) {\n if(this.isUser()) {\n this.service.getMessages(params).subscribe((response: ResponseData) => {\n this.messages = response.items as Array<NotifyMessage>;\n this.totalMessage = response.total;\n this.loaded = true;\n });\n }\n }\n\n loadMessageMore() {\n if(this.isUser()) {\n this.pageNumber += 1;\n this.service.getMessages({\n pageSize: this.pageSize,\n pageNumber: this.pageNumber,\n notifylist: true\n }).subscribe((response: ResponseData) => {\n this.messages = [...this.messages, ...response.items as Array<NotifyMessage>];\n });\n }\n }\n\n clearMessage(){\n if(this.isUser()) {\n this.service.clearAll().subscribe(response => {\n this.messages = [];\n this.totalMessage = 0;\n this.onClear.emit(true);\n })\n }\n }\n\n openMessage(msg: NotifyMessage) {\n if(this.isUser()) {\n if (!msg.read && msg.application && msg.activityID) {\n this.service.loadNotify(msg.application, msg.activityID).subscribe((message: NotifyMessage) => {\n msg.read = true;\n this.onLoad.emit(true);\n });\n }\n }\n }\n}\n","<div class=\"slide-nav\" [ngClass]=\"{'opened': opened}\">\n <div class=\"list-header\">\n <span class=\"font-weight-bold\"><i class=\"fa fa-bell\"></i> {{'COMMON.NOTIFICATION.TITLE' | translate}}</span>\n <button (click)=\"close()\" class=\"close\" type=\"button\"><i class=\"fa fa-times\"></i></button>\n </div>\n <ul class=\"list-box\">\n <li *ngFor=\"let item of messages\">\n <a href=\"javascript:;\" (click)=\"openMessage(item)\">\n <div class=\"list-item\">\n <div class=\"list-left\">\n <img *ngIf=\"item && item.sender\" userAvatar [usercode]=\"item.sender\" class=\"user-avatar mt-0 mr-2 rounded-circle\">\n </div>\n <div class=\"list-body\">\n <div class=\"media-body ml-2\">\n <p class=\"mb-1 message-item p-2\" [ngClass]=\"{'unread': !item.read}\">\n <b>{{item?.fullname}}</b> {{item?.message}}\n </p>\n <!--div class=\"px-2\">{{item.created | date}}</div-->\n </div>\n </div>\n </div>\n </a>\n </li>\n <li *ngIf=\"!messages?.length\">\n <div class=\"empty-msg-container\">\n <i>{{'COMMON.NOTIFICATION.EMPTY_MSG' | translate}}</i>\n </div>\n </li>\n <div *ngIf=\"messages.length && totalMessage!=messages.length\" class=\"mt-1 text-center\">\n <a (click)=\"loadMessageMore()\" href=\"javascript:;\">\n {{'COMMON.NOTIFICATION.LOAD_MORE' | translate}} {{totalMessage-messages.length}} {{'COMMON.NOTIFICATION.ITEMS' | translate}}\n </a>\n </div>\n </ul>\n <div class=\"list-footer\">\n <a *ngIf=\"messages?.length\" (click)=\"clearMessage()\" href=\"javascript:;\"><i class=\"fa fa-eraser text-danger\"></i> {{'COMMON.NOTIFICATION.CLEAR_ALL' | translate}}</a>\n </div>\n</div>\n","import {\n Component, ElementRef, OnDestroy, OnInit, SimpleChanges\n} from '@angular/core';\nimport {AbstractSideNavComponent} from \"../abstract-side-nav.component\";\nimport {Subscription} from \"rxjs\";\nimport {Router} from \"@angular/router\";\nimport {CoreService, SecurityService} from \"inet-core\";\nimport {SystemApplication} from \"inet-ui\";\n\ndeclare let iNet: any;\n\n@Component({\n selector: 'app-admin-app-side-nav',\n templateUrl: './app-side-nav.component.html',\n styles: [`\n iframe {\n width: 100%;\n border: none;\n overflow: hidden;\n }\n `],\n standalone: false\n})\nexport class AppSideNavComponent extends AbstractSideNavComponent implements OnInit, OnDestroy {\n //private loaded = false;\n private _router?: Subscription;\n applications: SystemApplication[] = [];\n widgetApps: SystemApplication[] = [];\n systemUrl: string = 'about:blank';\n SYSTEM_APPS = ['social', 'calendar'];\n\n constructor(\n private coreService: CoreService,\n private router: Router,\n public elementRef: ElementRef,\n private securityService : SecurityService) {\n super(elementRef);\n\n this.listApp();\n }\n\n ngOnInit() {\n window.addEventListener('message', (e) => {\n var __data = e.data || {};\n var __eventName = __data['eventName'];\n var __result: any = {};\n if (!iNet.isEmpty(__data.result)) {\n if (typeof (__data.result) === 'string') {\n __result = JSON.parse(__data.result);\n } else if (typeof (__data.result) === 'object') {\n __result = __data.result || {};\n }\n //console.log('[message]', __result);\n switch (__eventName) {\n case 'open':\n case 'openApp':\n this.openApp(__result['application']);\n this.close();\n break;\n case 'openUrl':\n window.location.href = iNet.getSSOUrl(__result['url']);\n break;\n case 'loaded':\n const iFrame: any = document.querySelectorAll(`iframe[src=\"${__result['src']}\"]`)[0];\n if (iFrame) {\n iFrame['height'] = __result['height'];\n iFrame['valid'] = true;\n }\n break;\n }\n }\n\n }, false);\n }\n\n ngOnDestroy(): void {\n this.close();\n if (this._router) {\n this._router.unsubscribe();\n }\n }\n\n ngOnChanges(changes: SimpleChanges) {\n const currentValue = changes['opened'][\"currentValue\"];\n setTimeout(() => {\n if (currentValue) {\n this.systemUrl = iNet.getPUrl('common/page/apps') + '?appname=system';\n this.open();\n } else {\n this.close();\n }\n }, 250)\n }\n\n private isUser(): boolean {\n if (!iNet.username) {\n return false;\n }\n return this.securityService.hasRole('firmuser,firm_user,community');\n }\n\n private listApp() {\n if(this.isUser()) {\n this.coreService.getSystemApplication().subscribe((apps: any = []) => {\n if (apps && apps.length > 0) {\n this.applications = apps\n .filter((app: SystemApplication) => (app.organId !== 'community' && app.firmContext))\n .map((application: SystemApplication) => {\n if (application.homepage && application.homepage.indexOf('http') < 0) {\n application.homepage = iNet.getPUrl(`${application.module}/${application.homepage}`);\n application.icon = `${this.coreService.getFileServerPath()}/images/${application.module}/${application.icon}`;\n }\n if (!!application.widget) {\n application.widget = `${iNet.getPUrl('common/page/apps')}?appname=${application.firmContext}`; //rebuild the widget url\n }\n return application;\n });\n this.widgetApps = this.applications.filter((app: SystemApplication) => (!!app.widget));\n }\n });\n }\n }\n\n openApp(app: string) {\n if (this.SYSTEM_APPS.includes(app)) { //system app\n this.router.navigate([app]);\n } else {\n const url = iNet.getSSOUrl(this.getUrlByContext(app));\n if (url) {\n window.location.href = url;\n }\n }\n }\n\n private getUrlByContext(content: string): string {\n const app: any = this.applications.find(({webContext}) => webContext === content);\n return app.homepage;\n }\n\n getLink(app?: any): string {\n return (app && app.widget) ? app.widget : 'about:blank';\n }\n}\n","<div class=\"slide-nav\" [ngClass]=\"{'opened': opened}\">\n <ul class=\"list-box list-app\" *ngIf=\"opened\">\n <iframe id=\"system-app-iframe\" [src]=\"systemUrl | safe\" scrolling=\"no\"></iframe>\n <iframe *ngFor=\"let widgetApp of widgetApps\" [src]=\"getLink(widgetApp) | safe\" scrolling=\"no\"></iframe>\n </ul>\n</div>\n","import {\n Component, ElementRef\n} from '@angular/core';\nimport {AbstractSideNavComponent} from \"../abstract-side-nav.component\";\n\n@Component({\n selector: 'app-admin-social-side-nav',\n templateUrl: './social-side-nav.component.html',\n styleUrls: ['./social-side-nav.component.css'],\n standalone: false\n})\nexport class SocialSideNavComponent extends AbstractSideNavComponent {\n constructor(public elementRef: ElementRef) {\n super(elementRef);\n }\n}\n","<div class=\"slide-nav\" [ngClass]=\"{'opened': opened}\">\n <div class=\"m-3\">\n Social component\n </div>\n</div>\n","import {\n AfterViewInit,\n Component,\n ContentChild,\n ElementRef, EventEmitter,\n Input,\n OnDestroy,\n OnInit,\n Output,\n TemplateRef, ViewChild\n} from '@angular/core';\nimport {NavigationEnd, Router} from \"@angular/router\";\nimport {AdminNavbarComponent} from \"./navbar/navbar.component\";\nimport {Subscription} from \"rxjs\";\nimport {filter} from \"rxjs/operators\";\nimport {SecurityService} from \"inet-core\";\n\ndeclare let iNet: any;\n\n@Component({\n selector: 'app-layout',\n templateUrl: './layout.component.html',\n standalone: false\n})\nexport class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {\n @Input('theme') themeClass: string = 'theme-silver';\n @ContentChild('menu') menu!: TemplateRef<ElementRef>;\n @ContentChild('navbarItem') navbarItemTpl!: TemplateRef<ElementRef>;\n @ContentChild('profileItem') profileItemTpl!: TemplateRef<ElementRef>;\n @ContentChild('navbarMenu') navbarMenu!: TemplateRef<ElementRef>;\n @ContentChild('toolbar') toolbar!: TemplateRef<ElementRef>;\n\n @Input('homeRouterLink') homeRouterLink: string = '';\n @Input() appName?: string;\n\n @Input() hideToggler: boolean = false;\n @Input() hideTogglerButton: boolean = true;\n @Input() visibleMenu: boolean = true;\n @Input() expandedMenu: boolean = false;\n @Input() expandedSlider: boolean = false;\n @Input() expandedMessageSlider: boolean = false;\n @Input() expandedUserLogSlider: boolean = false;\n @Input() expandedAppSlider: boolean = false;\n @Input() expandedSocialSlider: boolean = false;\n @Input() expandedChatSlider: boolean = false;\n @Input() hideSearch: boolean = false;\n @Input() hideCompanyMenu: boolean = false;\n @Input() hideProfileMenu: boolean = false;\n @Input() hideBrandName: boolean = true;\n @Input() hideLogo: boolean = false;\n @Input() visibleOverlay: boolean = false;\n @Input() fullScreenLayout: boolean = false;\n\n @Input() fullLayoutWithUrls: Array<string> = [];\n @Output() routeChange = new EventEmitter();\n @Output() onToggle = new EventEmitter<boolean>();\n @Output() onClickLogo = new EventEmitter<string>();\n @Input() visibleToolbar: boolean = false;\n\n @Input() visibleChatIcon: boolean = true;\n @Input() visibleMessageIcon: boolean = true;\n @Input() visibleUserLogIcon: boolean = true;\n @Input() visibleAppIcon: boolean = true;\n @Input() visibleNoteIcon: boolean = false;\n @Input() visibleSearch: boolean = false;\n\n private _router?: Subscription;\n @ViewChild(AdminNavbarComponent) navbarComponent!: AdminNavbarComponent;\n\n constructor(private router: Router,\n private securityService: SecurityService) {\n\n }\n\n ngOnInit() {\n if (window.localStorage) {\n this.expandedMenu = (window.localStorage.getItem('expandedMenu') === '1');\n }\n this.router.events.pipe(\n filter(event => event instanceof NavigationEnd),\n ).subscribe((e: NavigationEnd | any) => {\n this.onChangeUrl(e.url);\n });\n\n if (this.visibleChatIcon) {\n this.visibleChatIcon = this.isUser();\n }\n if (this.visibleMessageIcon) {\n this.visibleMessageIcon = this.isUser();\n }\n if (this.visibleAppIcon) {\n this.visibleAppIcon = this.isUser();\n }\n }\n\n private isUser(): boolean {\n if (!iNet.username) {\n return false;\n }\n return this.securityService.hasRole('firmuser,firm_user,community');\n }\n\n private onChangeUrl(url: string) {\n if (!this.fullScreenLayout) {\n let __visibleMenu = !!this.menu;\n if (__visibleMenu) {\n for (let i = 0; i < this.fullLayoutWithUrls.length; i++) {\n if ((url !== '/' && this.fullLayoutWithUrls[i] !== '/' && url.indexOf(this.fullLayoutWithUrls[i]) === 0)\n || (url === this.fullLayoutWithUrls[i])) {\n __visibleMenu = false;\n break;\n }\n }\n }\n this.visibleMenu = __visibleMenu;\n } else {\n this.visibleMenu = false;\n }\n this.hideToggler = !this.visibleMenu;\n this.routeChange.emit({\n url: url,\n visibleMenu: this.visibleMenu,\n hideToggler: this.hideToggler,\n expandedMenu: this.expandedMenu,\n layout: this\n });\n }\n\n ngAfterViewInit() {\n /*\n //Using jQuery to handle menu\n $(document).ready(function () {\n const $menu = $('#mainnav-menu');\n const activeCls = 'active';\n const $elements = $menu.find('li');\n\n $elements.on('hide.bs.collapse', (e: any) => {\n //console.log('[hide]', e.currentTarget);\n e.currentTarget.classList.remove(activeCls);\n });\n\n $elements.on('show.bs.collapse', (e: any) => {\n const $currentActive = $menu.find('li.active');\n $currentActive.find('a[data-toggle]').trigger(\"click\");\n //console.log('[show]', e.currentTarget);\n e.currentTarget.classList.add(activeCls);\n });\n });\n */\n }\n\n ngOnDestroy(): void {\n if (this._router) {\n this._router.unsubscribe();\n }\n }\n\n