eiu-app-kit 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,88 +1,105 @@
1
- # eiu-app-kit
2
-
3
- Thư viện Angular dùng chung cho các SPA EIU: **launcher ứng dụng trên header**, **tin Redmine / feature news**, popup “Có gì mới”.
4
-
5
- ## Cài qua npm
6
-
7
- ```bash
8
- npm install eiu-app-kit
9
- ```
10
-
11
- Ứng dụng Angular 15+, cùng major với peer dependencies của package.
12
-
13
- ## Cấu hình `AppModule` (hoặc `bootstrapApplication` + `importProvidersFrom`)
14
-
15
- ```ts
16
- import { HttpClientModule } from '@angular/common/http';
17
- import {
18
- EIU_APP_API_BASE_URL,
19
- EIU_APP_LAUNCHER_MENU_LOADER
20
- } from 'eiu-app-kit';
21
- import { environment } from './environments/environment';
22
- // import { ProjectService } from '...';
23
-
24
- @NgModule({
25
- imports: [
26
- HttpClientModule,
27
- // ...
28
- ],
29
- providers: [
30
- { provide: EIU_APP_API_BASE_URL, useValue: environment.API_EIU_APP },
31
- {
32
- provide: EIU_APP_LAUNCHER_MENU_LOADER,
33
- useFactory: (project: ProjectService) => ({
34
- loadItems: () => project.getAllProject()
35
- }),
36
- deps: [ProjectService]
37
- }
38
- ]
39
- })
40
- export class AppModule {}
41
- ```
42
-
43
- Kiểu phần tử từ `loadItems()` phải khớp `EiuAppLauncherMenuItem` (`name_VI`, `imageUrl`, `link`, `sortOrder`).
44
-
45
- ## Module layout (ví dụ `ThemeModule`)
46
-
47
- ```ts
48
- import { EiuAppFeatureNewsModule, EiuAppLauncherModule } from 'eiu-app-kit';
49
-
50
- @NgModule({
51
- imports: [CommonModule, EiuAppFeatureNewsModule, EiuAppLauncherModule]
52
- })
53
- export class ThemeModule {}
54
- ```
55
-
56
- ## Template header / layout
57
-
58
- ```html
59
- <app-eiu-app-launcher (sidebarToggle)="onToggleMenuSidebar()"></app-eiu-app-launcher>
60
- <app-feature-news-dialog></app-feature-news-dialog>
61
- ```
62
-
63
- `sidebarToggle`: host tự xử lý (NgRx, v.v.).
64
-
65
- ## Feature news
66
-
67
- Inject `FeatureNewsService`:
68
-
69
- - `checkAndShowFeatureNews(userId, projectIdentifier)` — khi có tin mới.
70
- - `showLatestFeatureNewsManually(userId, projectIdentifier)` — mở thủ công.
71
-
72
- Hằng số mặc định project Redmine: `FEATURE_NEWS_REDMINE_PROJECT_IDENTIFIER`.
73
-
74
- Khi logout `localStorage.clear()`, cân nhắc giữ key prefix `FEATURE_NEWS_SEEN_STORAGE_KEY_PREFIX`.
75
-
76
- ## Monorepo (path mapping, không publish)
77
-
78
- Trong `tsconfig` của app:
79
-
80
- ```json
81
- "paths": {
82
- "eiu-app-kit": ["../projects/eiu-app-kit/src/public-api.ts"]
83
- }
84
- ```
85
-
86
- ## Public API
87
-
88
- Xem `src/public-api.ts`: modules, services, models, `EIU_APP_API_BASE_URL`, `EIU_APP_LAUNCHER_MENU_LOADER`.
1
+ # eiu-app-kit
2
+
3
+ Thư viện Angular dùng chung cho các SPA EIU: **launcher ứng dụng trên header**, **tin Redmine / feature news**, popup “Có gì mới”.
4
+
5
+ ## Cài qua npm
6
+
7
+ ```bash
8
+ npm install eiu-app-kit
9
+ ```
10
+
11
+ Ứng dụng Angular 15+, cùng major với peer dependencies của package.
12
+
13
+ ## Cấu hình `AppModule` (hoặc `bootstrapApplication` + `importProvidersFrom`)
14
+
15
+ ```ts
16
+ import { HttpClientModule } from '@angular/common/http';
17
+ import {
18
+ EIU_APP_API_BASE_URL,
19
+ EIU_APP_LAUNCHER_MENU_LOADER
20
+ } from 'eiu-app-kit';
21
+ import { environment } from './environments/environment';
22
+ // import { ProjectService } from '...';
23
+
24
+ @NgModule({
25
+ imports: [
26
+ HttpClientModule,
27
+ // ...
28
+ ],
29
+ providers: [
30
+ { provide: EIU_APP_API_BASE_URL, useValue: environment.API_EIU_APP },
31
+ {
32
+ provide: EIU_APP_LAUNCHER_MENU_LOADER,
33
+ useFactory: (project: ProjectService) => ({
34
+ loadItems: () => project.getAllProject()
35
+ }),
36
+ deps: [ProjectService]
37
+ }
38
+ ]
39
+ })
40
+ export class AppModule {}
41
+ ```
42
+
43
+ Kiểu phần tử từ `loadItems()` phải khớp `EiuAppLauncherMenuItem` (`name_VI`, `imageUrl`, `link`, `sortOrder`).
44
+
45
+ ## Module layout (ví dụ `ThemeModule`)
46
+
47
+ ```ts
48
+ import {
49
+ EiuAppFeatureNewsModule,
50
+ EiuAppLauncherModule,
51
+ EiuAppUserMenuModule
52
+ } from 'eiu-app-kit';
53
+
54
+ @NgModule({
55
+ imports: [CommonModule, EiuAppFeatureNewsModule, EiuAppLauncherModule, EiuAppUserMenuModule]
56
+ })
57
+ export class ThemeModule {}
58
+ ```
59
+
60
+ ## Template header / layout
61
+
62
+ ```html
63
+ <app-eiu-app-launcher (sidebarToggle)="onToggleMenuSidebar()"></app-eiu-app-launcher>
64
+ <app-eiu-user-menu
65
+ [profile]="{ fullName: user.fullName, email: user.email, picture: user.picture }"
66
+ (changePassword)="changePassword()"
67
+ (logout)="logout()"
68
+ ></app-eiu-user-menu>
69
+ <app-feature-news-dialog></app-feature-news-dialog>
70
+ ```
71
+
72
+ `sidebarToggle`: host tự xử (NgRx, v.v.).
73
+
74
+ ## User menu component
75
+
76
+ `app-eiu-user-menu` không phụ thuộc Keycloak, TokenService hay translate pipe.
77
+
78
+ - Host truyền dữ liệu qua `profile: EiuUserMenuProfile`.
79
+ - Host tự xử lý logic qua events `(changePassword)` và `(logout)`.
80
+ - Có thể đổi label bằng `changePasswordLabel`, `logoutLabel`.
81
+
82
+ ## Feature news
83
+
84
+ Inject `FeatureNewsService`:
85
+
86
+ - `checkAndShowFeatureNews(userId, projectIdentifier)` — khi có tin mới.
87
+ - `showLatestFeatureNewsManually(userId, projectIdentifier)` — mở thủ công.
88
+
89
+ Hằng số mặc định project Redmine: `FEATURE_NEWS_REDMINE_PROJECT_IDENTIFIER`.
90
+
91
+ Khi logout có `localStorage.clear()`, cân nhắc giữ key prefix `FEATURE_NEWS_SEEN_STORAGE_KEY_PREFIX`.
92
+
93
+ ## Monorepo (path mapping, không publish)
94
+
95
+ Trong `tsconfig` của app:
96
+
97
+ ```json
98
+ "paths": {
99
+ "eiu-app-kit": ["../projects/eiu-app-kit/src/public-api.ts"]
100
+ }
101
+ ```
102
+
103
+ ## Public API
104
+
105
+ Xem `src/public-api.ts`: modules, services, models, `EIU_APP_API_BASE_URL`, `EIU_APP_LAUNCHER_MENU_LOADER`.
@@ -0,0 +1,87 @@
1
+ import { Component, EventEmitter, HostListener, Input, Output, ViewChild } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@angular/common";
4
+ export class EiuAppUserMenuComponent {
5
+ constructor() {
6
+ /** Thông tin user — host bind từ service token / session. */
7
+ this.profile = null;
8
+ /** Ảnh mặc định khi `picture` lỗi hoặc trống (đường dẫn trong assets của host). */
9
+ this.fallbackAvatar = 'assets/img/icons/default-profile.png';
10
+ this.changePasswordLabel = 'Đổi mật khẩu';
11
+ this.logoutLabel = 'Đăng xuất';
12
+ /** Host xử lý (ví dụ redirect SSO đổi mật khẩu). */
13
+ this.changePassword = new EventEmitter();
14
+ /** Host xử lý (ví dụ Keycloak logout + clear storage). */
15
+ this.logout = new EventEmitter();
16
+ this.menuOpen = false;
17
+ }
18
+ onTriggerClick(event) {
19
+ event.preventDefault();
20
+ event.stopPropagation();
21
+ this.menuOpen = !this.menuOpen;
22
+ }
23
+ onChangePasswordClick(event) {
24
+ event.preventDefault();
25
+ this.changePassword.emit();
26
+ this.menuOpen = false;
27
+ }
28
+ onLogoutClick(event) {
29
+ event.preventDefault();
30
+ this.logout.emit();
31
+ this.menuOpen = false;
32
+ }
33
+ onAvatarError(event) {
34
+ const img = event.target;
35
+ if (img && img.src !== this._absoluteFallback()) {
36
+ img.src = this.fallbackAvatar;
37
+ }
38
+ }
39
+ onDocumentClick(event) {
40
+ if (!this.menuOpen) {
41
+ return;
42
+ }
43
+ const root = this._root?.nativeElement;
44
+ if (root && !root.contains(event.target)) {
45
+ this.menuOpen = false;
46
+ }
47
+ }
48
+ onEscape() {
49
+ this.menuOpen = false;
50
+ }
51
+ _absoluteFallback() {
52
+ try {
53
+ return new URL(this.fallbackAvatar, window.location.origin).href;
54
+ }
55
+ catch {
56
+ return this.fallbackAvatar;
57
+ }
58
+ }
59
+ }
60
+ EiuAppUserMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EiuAppUserMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
61
+ EiuAppUserMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: EiuAppUserMenuComponent, selector: "app-eiu-user-menu", inputs: { profile: "profile", fallbackAvatar: "fallbackAvatar", changePasswordLabel: "changePasswordLabel", logoutLabel: "logoutLabel" }, outputs: { changePassword: "changePassword", logout: "logout" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" } }, viewQueries: [{ propertyName: "_root", first: true, predicate: ["root"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"eiu-user-menu\" #root *ngIf=\"profile as p\">\r\n <div class=\"eiu-user-menu__shell\">\r\n <a\r\n class=\"nav-link eiu-user-menu__trigger\"\r\n href=\"#\"\r\n role=\"button\"\r\n [attr.aria-expanded]=\"menuOpen\"\r\n [attr.aria-haspopup]=\"true\"\r\n (click)=\"onTriggerClick($event)\"\r\n >\r\n <div class=\"eiu-user-menu__trigger-inner\">\r\n <img\r\n [src]=\"p.picture || fallbackAvatar\"\r\n [alt]=\"p.fullName\"\r\n width=\"25\"\r\n height=\"25\"\r\n class=\"eiu-user-menu__img eiu-user-menu__img--sm\"\r\n (error)=\"onAvatarError($event)\"\r\n />\r\n <span class=\"eiu-user-menu__name text-grey-8 text-capitalize\">{{ p.fullName }}</span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"eiu-user-menu__dropdown\" *ngIf=\"menuOpen\" role=\"menu\">\r\n <div class=\"eiu-user-menu__header bg-eiu-primary\">\r\n <img\r\n [src]=\"p.picture || fallbackAvatar\"\r\n [alt]=\"p.fullName\"\r\n width=\"90\"\r\n height=\"90\"\r\n class=\"eiu-user-menu__img eiu-user-menu__img--lg\"\r\n (error)=\"onAvatarError($event)\"\r\n />\r\n <p>\r\n <span>{{ p.fullName }}</span>\r\n <small *ngIf=\"p.email as email\">\r\n <span class=\"mr-2\">{{ email }}</span>\r\n </small>\r\n </p>\r\n </div>\r\n <div class=\"eiu-user-menu__footer\">\r\n <a\r\n href=\"#\"\r\n class=\"btn btn-default btn-flat float-left\"\r\n role=\"menuitem\"\r\n (click)=\"onChangePasswordClick($event)\"\r\n >\r\n <i class=\"fa fa-exchange-alt mr-1\"></i>\r\n {{ changePasswordLabel }}\r\n </a>\r\n <a\r\n href=\"#\"\r\n class=\"btn btn-default btn-flat float-right\"\r\n role=\"menuitem\"\r\n (click)=\"onLogoutClick($event)\"\r\n >\r\n <i class=\"fa fa-sign-out-alt mr-1\"></i>\r\n {{ logoutLabel }}\r\n </a>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:flex;justify-content:center;align-items:center}.eiu-user-menu{position:relative;border:none;width:auto;display:flex;justify-content:center;align-items:center}.eiu-user-menu__shell{position:relative;display:flex;align-items:center}.eiu-user-menu__trigger{padding:.5rem .75rem}.eiu-user-menu__dropdown{position:absolute;right:0;top:100%;z-index:1050;min-width:280px;margin-top:.25rem;background:#fff;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;box-shadow:0 .5rem 1rem #0000002d}.eiu-user-menu__img--sm{margin:0 3px;border-radius:50%;object-fit:cover;box-shadow:0 3px 6px #00000029,0 3px 6px #0000003b}.eiu-user-menu__img--lg{border-radius:50%;object-fit:cover;box-shadow:0 3px 6px #00000029,0 3px 6px #0000003b;border:3px solid rgba(255,255,255,.2)}.eiu-user-menu__header{display:flex;align-items:center;flex-direction:column;height:175px;padding:10px;text-align:center}.eiu-user-menu__header img{z-index:5;height:90px;width:90px}.eiu-user-menu__header p{z-index:5;font-size:17px;margin-top:10px}.eiu-user-menu__header p small{display:block;font-size:12px}.eiu-user-menu__footer{background-color:#f8f9fa;padding:10px}.eiu-user-menu__footer:after{display:block;clear:both;content:\"\"}.eiu-user-menu__footer .btn-default{color:#6c757d;font-size:13px}@media (min-width: 576px){.eiu-user-menu__footer .btn-default:hover{background-color:#f8f9fa}}.eiu-user-menu__trigger-inner{display:flex;flex-wrap:wrap;align-items:center}.eiu-user-menu__trigger-inner .eiu-user-menu__name{max-width:0 15px;margin:3px auto}.text-grey-8{color:#616161}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
62
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EiuAppUserMenuComponent, decorators: [{
63
+ type: Component,
64
+ args: [{ selector: 'app-eiu-user-menu', template: "<div class=\"eiu-user-menu\" #root *ngIf=\"profile as p\">\r\n <div class=\"eiu-user-menu__shell\">\r\n <a\r\n class=\"nav-link eiu-user-menu__trigger\"\r\n href=\"#\"\r\n role=\"button\"\r\n [attr.aria-expanded]=\"menuOpen\"\r\n [attr.aria-haspopup]=\"true\"\r\n (click)=\"onTriggerClick($event)\"\r\n >\r\n <div class=\"eiu-user-menu__trigger-inner\">\r\n <img\r\n [src]=\"p.picture || fallbackAvatar\"\r\n [alt]=\"p.fullName\"\r\n width=\"25\"\r\n height=\"25\"\r\n class=\"eiu-user-menu__img eiu-user-menu__img--sm\"\r\n (error)=\"onAvatarError($event)\"\r\n />\r\n <span class=\"eiu-user-menu__name text-grey-8 text-capitalize\">{{ p.fullName }}</span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"eiu-user-menu__dropdown\" *ngIf=\"menuOpen\" role=\"menu\">\r\n <div class=\"eiu-user-menu__header bg-eiu-primary\">\r\n <img\r\n [src]=\"p.picture || fallbackAvatar\"\r\n [alt]=\"p.fullName\"\r\n width=\"90\"\r\n height=\"90\"\r\n class=\"eiu-user-menu__img eiu-user-menu__img--lg\"\r\n (error)=\"onAvatarError($event)\"\r\n />\r\n <p>\r\n <span>{{ p.fullName }}</span>\r\n <small *ngIf=\"p.email as email\">\r\n <span class=\"mr-2\">{{ email }}</span>\r\n </small>\r\n </p>\r\n </div>\r\n <div class=\"eiu-user-menu__footer\">\r\n <a\r\n href=\"#\"\r\n class=\"btn btn-default btn-flat float-left\"\r\n role=\"menuitem\"\r\n (click)=\"onChangePasswordClick($event)\"\r\n >\r\n <i class=\"fa fa-exchange-alt mr-1\"></i>\r\n {{ changePasswordLabel }}\r\n </a>\r\n <a\r\n href=\"#\"\r\n class=\"btn btn-default btn-flat float-right\"\r\n role=\"menuitem\"\r\n (click)=\"onLogoutClick($event)\"\r\n >\r\n <i class=\"fa fa-sign-out-alt mr-1\"></i>\r\n {{ logoutLabel }}\r\n </a>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:flex;justify-content:center;align-items:center}.eiu-user-menu{position:relative;border:none;width:auto;display:flex;justify-content:center;align-items:center}.eiu-user-menu__shell{position:relative;display:flex;align-items:center}.eiu-user-menu__trigger{padding:.5rem .75rem}.eiu-user-menu__dropdown{position:absolute;right:0;top:100%;z-index:1050;min-width:280px;margin-top:.25rem;background:#fff;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;box-shadow:0 .5rem 1rem #0000002d}.eiu-user-menu__img--sm{margin:0 3px;border-radius:50%;object-fit:cover;box-shadow:0 3px 6px #00000029,0 3px 6px #0000003b}.eiu-user-menu__img--lg{border-radius:50%;object-fit:cover;box-shadow:0 3px 6px #00000029,0 3px 6px #0000003b;border:3px solid rgba(255,255,255,.2)}.eiu-user-menu__header{display:flex;align-items:center;flex-direction:column;height:175px;padding:10px;text-align:center}.eiu-user-menu__header img{z-index:5;height:90px;width:90px}.eiu-user-menu__header p{z-index:5;font-size:17px;margin-top:10px}.eiu-user-menu__header p small{display:block;font-size:12px}.eiu-user-menu__footer{background-color:#f8f9fa;padding:10px}.eiu-user-menu__footer:after{display:block;clear:both;content:\"\"}.eiu-user-menu__footer .btn-default{color:#6c757d;font-size:13px}@media (min-width: 576px){.eiu-user-menu__footer .btn-default:hover{background-color:#f8f9fa}}.eiu-user-menu__trigger-inner{display:flex;flex-wrap:wrap;align-items:center}.eiu-user-menu__trigger-inner .eiu-user-menu__name{max-width:0 15px;margin:3px auto}.text-grey-8{color:#616161}\n"] }]
65
+ }], propDecorators: { _root: [{
66
+ type: ViewChild,
67
+ args: ['root', { static: true }]
68
+ }], profile: [{
69
+ type: Input
70
+ }], fallbackAvatar: [{
71
+ type: Input
72
+ }], changePasswordLabel: [{
73
+ type: Input
74
+ }], logoutLabel: [{
75
+ type: Input
76
+ }], changePassword: [{
77
+ type: Output
78
+ }], logout: [{
79
+ type: Output
80
+ }], onDocumentClick: [{
81
+ type: HostListener,
82
+ args: ['document:click', ['$event']]
83
+ }], onEscape: [{
84
+ type: HostListener,
85
+ args: ['document:keydown.escape']
86
+ }] } });
87
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWl1LWFwcC11c2VyLW1lbnUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZWl1LWFwcC1raXQvc3JjL2xpYi91c2VyLW1lbnUvZWl1LWFwcC11c2VyLW1lbnUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZWl1LWFwcC1raXQvc3JjL2xpYi91c2VyLW1lbnUvZWl1LWFwcC11c2VyLW1lbnUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNKLFNBQVMsRUFFVCxZQUFZLEVBQ1osWUFBWSxFQUNaLEtBQUssRUFDTCxNQUFNLEVBQ04sU0FBUyxFQUNYLE1BQU0sZUFBZSxDQUFDOzs7QUFRdkIsTUFBTSxPQUFPLHVCQUF1QjtJQUxwQztRQVFHLDZEQUE2RDtRQUNwRCxZQUFPLEdBQThCLElBQUksQ0FBQztRQUVuRCxtRkFBbUY7UUFDMUUsbUJBQWMsR0FBRyxzQ0FBc0MsQ0FBQztRQUV4RCx3QkFBbUIsR0FBRyxjQUFjLENBQUM7UUFDckMsZ0JBQVcsR0FBRyxXQUFXLENBQUM7UUFFbkMsb0RBQW9EO1FBQ2pDLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUM3RCwwREFBMEQ7UUFDdkMsV0FBTSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFFckQsYUFBUSxHQUFHLEtBQUssQ0FBQztLQWtEbkI7SUFoREUsY0FBYyxDQUFDLEtBQVk7UUFDeEIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUNsQyxDQUFDO0lBRUQscUJBQXFCLENBQUMsS0FBWTtRQUMvQixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztJQUN6QixDQUFDO0lBRUQsYUFBYSxDQUFDLEtBQVk7UUFDdkIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFDekIsQ0FBQztJQUVELGFBQWEsQ0FBQyxLQUFZO1FBQ3ZCLE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUEwQixDQUFDO1FBQzdDLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEtBQUssSUFBSSxDQUFDLGlCQUFpQixFQUFFLEVBQUU7WUFDOUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1NBQ2hDO0lBQ0osQ0FBQztJQUdELGVBQWUsQ0FBQyxLQUFpQjtRQUM5QixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNqQixPQUFPO1NBQ1Q7UUFDRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLGFBQWEsQ0FBQztRQUN2QyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQWMsQ0FBQyxFQUFFO1lBQy9DLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1NBQ3hCO0lBQ0osQ0FBQztJQUdELFFBQVE7UUFDTCxJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztJQUN6QixDQUFDO0lBRU8saUJBQWlCO1FBQ3RCLElBQUk7WUFDRCxPQUFPLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUM7U0FDbkU7UUFBQyxNQUFNO1lBQ0wsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDO1NBQzdCO0lBQ0osQ0FBQzs7cUhBbEVTLHVCQUF1Qjt5R0FBdkIsdUJBQXVCLGdlQ2hCcEMsazFFQStEQTs0RkQvQ2EsdUJBQXVCO2tCQUxuQyxTQUFTOytCQUNHLG1CQUFtQjs4QkFLeUIsS0FBSztzQkFBMUQsU0FBUzt1QkFBQyxNQUFNLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUcxQixPQUFPO3NCQUFmLEtBQUs7Z0JBR0csY0FBYztzQkFBdEIsS0FBSztnQkFFRyxtQkFBbUI7c0JBQTNCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFHYSxjQUFjO3NCQUFoQyxNQUFNO2dCQUVZLE1BQU07c0JBQXhCLE1BQU07Z0JBOEJQLGVBQWU7c0JBRGQsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFZMUMsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLHlCQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgIENvbXBvbmVudCxcclxuICAgRWxlbWVudFJlZixcclxuICAgRXZlbnRFbWl0dGVyLFxyXG4gICBIb3N0TGlzdGVuZXIsXHJcbiAgIElucHV0LFxyXG4gICBPdXRwdXQsXHJcbiAgIFZpZXdDaGlsZFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBFaXVVc2VyTWVudVByb2ZpbGUgfSBmcm9tICcuL2VpdS11c2VyLW1lbnUubW9kZWwnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgIHNlbGVjdG9yOiAnYXBwLWVpdS11c2VyLW1lbnUnLFxyXG4gICB0ZW1wbGF0ZVVybDogJy4vZWl1LWFwcC11c2VyLW1lbnUuY29tcG9uZW50Lmh0bWwnLFxyXG4gICBzdHlsZVVybHM6IFsnLi9laXUtYXBwLXVzZXItbWVudS5jb21wb25lbnQuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBFaXVBcHBVc2VyTWVudUNvbXBvbmVudCB7XHJcbiAgIEBWaWV3Q2hpbGQoJ3Jvb3QnLCB7IHN0YXRpYzogdHJ1ZSB9KSBwcml2YXRlIHJlYWRvbmx5IF9yb290ITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XHJcblxyXG4gICAvKiogVGjDtG5nIHRpbiB1c2VyIOKAlCBob3N0IGJpbmQgdOG7qyBzZXJ2aWNlIHRva2VuIC8gc2Vzc2lvbi4gKi9cclxuICAgQElucHV0KCkgcHJvZmlsZTogRWl1VXNlck1lbnVQcm9maWxlIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gICAvKiog4bqibmggbeG6t2MgxJHhu4tuaCBraGkgYHBpY3R1cmVgIGzhu5dpIGhv4bq3YyB0cuG7kW5nICjEkcaw4budbmcgZOG6q24gdHJvbmcgYXNzZXRzIGPhu6dhIGhvc3QpLiAqL1xyXG4gICBASW5wdXQoKSBmYWxsYmFja0F2YXRhciA9ICdhc3NldHMvaW1nL2ljb25zL2RlZmF1bHQtcHJvZmlsZS5wbmcnO1xyXG5cclxuICAgQElucHV0KCkgY2hhbmdlUGFzc3dvcmRMYWJlbCA9ICfEkOG7lWkgbeG6rXQga2jhuql1JztcclxuICAgQElucHV0KCkgbG9nb3V0TGFiZWwgPSAnxJDEg25nIHh14bqldCc7XHJcblxyXG4gICAvKiogSG9zdCB44butIGzDvSAodsOtIGThu6UgcmVkaXJlY3QgU1NPIMSR4buVaSBt4bqtdCBraOG6qXUpLiAqL1xyXG4gICBAT3V0cHV0KCkgcmVhZG9ubHkgY2hhbmdlUGFzc3dvcmQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcbiAgIC8qKiBIb3N0IHjhu60gbMO9ICh2w60gZOG7pSBLZXljbG9hayBsb2dvdXQgKyBjbGVhciBzdG9yYWdlKS4gKi9cclxuICAgQE91dHB1dCgpIHJlYWRvbmx5IGxvZ291dCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcclxuXHJcbiAgIG1lbnVPcGVuID0gZmFsc2U7XHJcblxyXG4gICBvblRyaWdnZXJDbGljayhldmVudDogRXZlbnQpOiB2b2lkIHtcclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgIHRoaXMubWVudU9wZW4gPSAhdGhpcy5tZW51T3BlbjtcclxuICAgfVxyXG5cclxuICAgb25DaGFuZ2VQYXNzd29yZENsaWNrKGV2ZW50OiBFdmVudCk6IHZvaWQge1xyXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICB0aGlzLmNoYW5nZVBhc3N3b3JkLmVtaXQoKTtcclxuICAgICAgdGhpcy5tZW51T3BlbiA9IGZhbHNlO1xyXG4gICB9XHJcblxyXG4gICBvbkxvZ291dENsaWNrKGV2ZW50OiBFdmVudCk6IHZvaWQge1xyXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICB0aGlzLmxvZ291dC5lbWl0KCk7XHJcbiAgICAgIHRoaXMubWVudU9wZW4gPSBmYWxzZTtcclxuICAgfVxyXG5cclxuICAgb25BdmF0YXJFcnJvcihldmVudDogRXZlbnQpOiB2b2lkIHtcclxuICAgICAgY29uc3QgaW1nID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbWFnZUVsZW1lbnQ7XHJcbiAgICAgIGlmIChpbWcgJiYgaW1nLnNyYyAhPT0gdGhpcy5fYWJzb2x1dGVGYWxsYmFjaygpKSB7XHJcbiAgICAgICAgIGltZy5zcmMgPSB0aGlzLmZhbGxiYWNrQXZhdGFyO1xyXG4gICAgICB9XHJcbiAgIH1cclxuXHJcbiAgIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnXSlcclxuICAgb25Eb2N1bWVudENsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XHJcbiAgICAgIGlmICghdGhpcy5tZW51T3Blbikge1xyXG4gICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgY29uc3Qgcm9vdCA9IHRoaXMuX3Jvb3Q/Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICAgIGlmIChyb290ICYmICFyb290LmNvbnRhaW5zKGV2ZW50LnRhcmdldCBhcyBOb2RlKSkge1xyXG4gICAgICAgICB0aGlzLm1lbnVPcGVuID0gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgfVxyXG5cclxuICAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6a2V5ZG93bi5lc2NhcGUnKVxyXG4gICBvbkVzY2FwZSgpOiB2b2lkIHtcclxuICAgICAgdGhpcy5tZW51T3BlbiA9IGZhbHNlO1xyXG4gICB9XHJcblxyXG4gICBwcml2YXRlIF9hYnNvbHV0ZUZhbGxiYWNrKCk6IHN0cmluZyB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgIHJldHVybiBuZXcgVVJMKHRoaXMuZmFsbGJhY2tBdmF0YXIsIHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4pLmhyZWY7XHJcbiAgICAgIH0gY2F0Y2gge1xyXG4gICAgICAgICByZXR1cm4gdGhpcy5mYWxsYmFja0F2YXRhcjtcclxuICAgICAgfVxyXG4gICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImVpdS11c2VyLW1lbnVcIiAjcm9vdCAqbmdJZj1cInByb2ZpbGUgYXMgcFwiPlxyXG4gICA8ZGl2IGNsYXNzPVwiZWl1LXVzZXItbWVudV9fc2hlbGxcIj5cclxuICAgICAgPGFcclxuICAgICAgICAgY2xhc3M9XCJuYXYtbGluayBlaXUtdXNlci1tZW51X190cmlnZ2VyXCJcclxuICAgICAgICAgaHJlZj1cIiNcIlxyXG4gICAgICAgICByb2xlPVwiYnV0dG9uXCJcclxuICAgICAgICAgW2F0dHIuYXJpYS1leHBhbmRlZF09XCJtZW51T3BlblwiXHJcbiAgICAgICAgIFthdHRyLmFyaWEtaGFzcG9wdXBdPVwidHJ1ZVwiXHJcbiAgICAgICAgIChjbGljayk9XCJvblRyaWdnZXJDbGljaygkZXZlbnQpXCJcclxuICAgICAgPlxyXG4gICAgICAgICA8ZGl2IGNsYXNzPVwiZWl1LXVzZXItbWVudV9fdHJpZ2dlci1pbm5lclwiPlxyXG4gICAgICAgICAgICA8aW1nXHJcbiAgICAgICAgICAgICAgIFtzcmNdPVwicC5waWN0dXJlIHx8IGZhbGxiYWNrQXZhdGFyXCJcclxuICAgICAgICAgICAgICAgW2FsdF09XCJwLmZ1bGxOYW1lXCJcclxuICAgICAgICAgICAgICAgd2lkdGg9XCIyNVwiXHJcbiAgICAgICAgICAgICAgIGhlaWdodD1cIjI1XCJcclxuICAgICAgICAgICAgICAgY2xhc3M9XCJlaXUtdXNlci1tZW51X19pbWcgZWl1LXVzZXItbWVudV9faW1nLS1zbVwiXHJcbiAgICAgICAgICAgICAgIChlcnJvcik9XCJvbkF2YXRhckVycm9yKCRldmVudClcIlxyXG4gICAgICAgICAgICAvPlxyXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImVpdS11c2VyLW1lbnVfX25hbWUgdGV4dC1ncmV5LTggdGV4dC1jYXBpdGFsaXplXCI+e3sgcC5mdWxsTmFtZSB9fTwvc3Bhbj5cclxuICAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvYT5cclxuXHJcbiAgICAgIDxkaXYgY2xhc3M9XCJlaXUtdXNlci1tZW51X19kcm9wZG93blwiICpuZ0lmPVwibWVudU9wZW5cIiByb2xlPVwibWVudVwiPlxyXG4gICAgICAgICA8ZGl2IGNsYXNzPVwiZWl1LXVzZXItbWVudV9faGVhZGVyIGJnLWVpdS1wcmltYXJ5XCI+XHJcbiAgICAgICAgICAgIDxpbWdcclxuICAgICAgICAgICAgICAgW3NyY109XCJwLnBpY3R1cmUgfHwgZmFsbGJhY2tBdmF0YXJcIlxyXG4gICAgICAgICAgICAgICBbYWx0XT1cInAuZnVsbE5hbWVcIlxyXG4gICAgICAgICAgICAgICB3aWR0aD1cIjkwXCJcclxuICAgICAgICAgICAgICAgaGVpZ2h0PVwiOTBcIlxyXG4gICAgICAgICAgICAgICBjbGFzcz1cImVpdS11c2VyLW1lbnVfX2ltZyBlaXUtdXNlci1tZW51X19pbWctLWxnXCJcclxuICAgICAgICAgICAgICAgKGVycm9yKT1cIm9uQXZhdGFyRXJyb3IoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDxwPlxyXG4gICAgICAgICAgICAgICA8c3Bhbj57eyBwLmZ1bGxOYW1lIH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICA8c21hbGwgKm5nSWY9XCJwLmVtYWlsIGFzIGVtYWlsXCI+XHJcbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibXItMlwiPnt7IGVtYWlsIH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICA8L3NtYWxsPlxyXG4gICAgICAgICAgICA8L3A+XHJcbiAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICA8ZGl2IGNsYXNzPVwiZWl1LXVzZXItbWVudV9fZm9vdGVyXCI+XHJcbiAgICAgICAgICAgIDxhXHJcbiAgICAgICAgICAgICAgIGhyZWY9XCIjXCJcclxuICAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLWRlZmF1bHQgYnRuLWZsYXQgZmxvYXQtbGVmdFwiXHJcbiAgICAgICAgICAgICAgIHJvbGU9XCJtZW51aXRlbVwiXHJcbiAgICAgICAgICAgICAgIChjbGljayk9XCJvbkNoYW5nZVBhc3N3b3JkQ2xpY2soJGV2ZW50KVwiXHJcbiAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1leGNoYW5nZS1hbHQgbXItMVwiPjwvaT5cclxuICAgICAgICAgICAgICAge3sgY2hhbmdlUGFzc3dvcmRMYWJlbCB9fVxyXG4gICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgIDxhXHJcbiAgICAgICAgICAgICAgIGhyZWY9XCIjXCJcclxuICAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLWRlZmF1bHQgYnRuLWZsYXQgZmxvYXQtcmlnaHRcIlxyXG4gICAgICAgICAgICAgICByb2xlPVwibWVudWl0ZW1cIlxyXG4gICAgICAgICAgICAgICAoY2xpY2spPVwib25Mb2dvdXRDbGljaygkZXZlbnQpXCJcclxuICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLXNpZ24tb3V0LWFsdCBtci0xXCI+PC9pPlxyXG4gICAgICAgICAgICAgICB7eyBsb2dvdXRMYWJlbCB9fVxyXG4gICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuICAgPC9kaXY+XHJcbjwvZGl2PlxyXG4iXX0=
@@ -0,0 +1,22 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { NgModule } from '@angular/core';
3
+ import { EiuAppUserMenuComponent } from './eiu-app-user-menu.component';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * Menu user header (avatar, đổi mật khẩu, đăng xuất).
7
+ * Host cung cấp `[profile]` và xử lý `(changePassword)` / `(logout)`.
8
+ */
9
+ export class EiuAppUserMenuModule {
10
+ }
11
+ EiuAppUserMenuModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EiuAppUserMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
12
+ EiuAppUserMenuModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: EiuAppUserMenuModule, declarations: [EiuAppUserMenuComponent], imports: [CommonModule], exports: [EiuAppUserMenuComponent] });
13
+ EiuAppUserMenuModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EiuAppUserMenuModule, imports: [CommonModule] });
14
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EiuAppUserMenuModule, decorators: [{
15
+ type: NgModule,
16
+ args: [{
17
+ imports: [CommonModule],
18
+ declarations: [EiuAppUserMenuComponent],
19
+ exports: [EiuAppUserMenuComponent]
20
+ }]
21
+ }] });
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWl1LWFwcC11c2VyLW1lbnUubW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZWl1LWFwcC1raXQvc3JjL2xpYi91c2VyLW1lbnUvZWl1LWFwcC11c2VyLW1lbnUubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLCtCQUErQixDQUFDOztBQUV4RTs7O0dBR0c7QUFNSCxNQUFNLE9BQU8sb0JBQW9COztrSEFBcEIsb0JBQW9CO21IQUFwQixvQkFBb0IsaUJBSGYsdUJBQXVCLGFBRDVCLFlBQVksYUFFWix1QkFBdUI7bUhBRXZCLG9CQUFvQixZQUpwQixZQUFZOzRGQUlaLG9CQUFvQjtrQkFMaEMsUUFBUTttQkFBQztvQkFDUCxPQUFPLEVBQUUsQ0FBQyxZQUFZLENBQUM7b0JBQ3ZCLFlBQVksRUFBRSxDQUFDLHVCQUF1QixDQUFDO29CQUN2QyxPQUFPLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQztpQkFDcEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBFaXVBcHBVc2VyTWVudUNvbXBvbmVudCB9IGZyb20gJy4vZWl1LWFwcC11c2VyLW1lbnUuY29tcG9uZW50JztcclxuXHJcbi8qKlxyXG4gKiBNZW51IHVzZXIgaGVhZGVyIChhdmF0YXIsIMSR4buVaSBt4bqtdCBraOG6qXUsIMSRxINuZyB4deG6pXQpLlxyXG4gKiBIb3N0IGN1bmcgY+G6pXAgYFtwcm9maWxlXWAgdsOgIHjhu60gbMO9IGAoY2hhbmdlUGFzc3dvcmQpYCAvIGAobG9nb3V0KWAuXHJcbiAqL1xyXG5ATmdNb2R1bGUoe1xyXG4gICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcclxuICAgZGVjbGFyYXRpb25zOiBbRWl1QXBwVXNlck1lbnVDb21wb25lbnRdLFxyXG4gICBleHBvcnRzOiBbRWl1QXBwVXNlck1lbnVDb21wb25lbnRdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBFaXVBcHBVc2VyTWVudU1vZHVsZSB7fVxyXG4iXX0=
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWl1LXVzZXItbWVudS5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2VpdS1hcHAta2l0L3NyYy9saWIvdXNlci1tZW51L2VpdS11c2VyLW1lbnUubW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiBUaMO0bmcgdGluIHVzZXIgaGnhu4NuIHRo4buLIHRyw6puIG1lbnUgKGF2YXRhciwgdMOqbiwgZW1haWwpLlxyXG4gKiBIb3N0IG1hcCB04burIHRva2VuIC8gQVBJIGPhu6dhIOG7qW5nIGThu6VuZy5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRWl1VXNlck1lbnVQcm9maWxlIHtcclxuICAgLyoqIFVSTCDhuqNuaCDEkeG6oWkgZGnhu4duICh0deG7syBjaOG7jW4pLiAqL1xyXG4gICBwaWN0dXJlPzogc3RyaW5nIHwgbnVsbDtcclxuICAgLyoqIEjhu40gdMOqbiBoaeG7g24gdGjhu4suICovXHJcbiAgIGZ1bGxOYW1lOiBzdHJpbmc7XHJcbiAgIC8qKiBFbWFpbCAodHXhu7MgY2jhu41uKS4gKi9cclxuICAgZW1haWw/OiBzdHJpbmcgfCBudWxsO1xyXG59XHJcbiJdfQ==
@@ -6,6 +6,9 @@ export * from './lib/app-launcher/eiu-app-launcher-menu.model';
6
6
  export * from './lib/app-launcher/eiu-app-launcher-menu.token';
7
7
  export * from './lib/app-launcher/eiu-app-launcher.component';
8
8
  export * from './lib/app-launcher/eiu-app-launcher.module';
9
+ export * from './lib/user-menu/eiu-user-menu.model';
10
+ export * from './lib/user-menu/eiu-app-user-menu.component';
11
+ export * from './lib/user-menu/eiu-app-user-menu.module';
9
12
  export * from './lib/sidebar-shared/sidebar-shared.model';
10
13
  export * from './lib/sidebar-shared/logo/eiu-sidebar-logo.component';
11
14
  export * from './lib/sidebar-shared/contact/eiu-contact-support.component';
@@ -20,4 +23,4 @@ export * from './lib/feature-news/feature-news-dialog.service';
20
23
  export * from './lib/feature-news/feature-news.service';
21
24
  export * from './lib/feature-news/feature-news-dialog.component';
22
25
  export * from './lib/feature-news/eiu-app-feature-news.module';
23
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2VpdS1hcHAta2l0L3NyYy9wdWJsaWMtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLGdEQUFnRCxDQUFDO0FBQy9ELGNBQWMsZ0RBQWdELENBQUM7QUFDL0QsY0FBYywrQ0FBK0MsQ0FBQztBQUM5RCxjQUFjLDRDQUE0QyxDQUFDO0FBQzNELGNBQWMsMkNBQTJDLENBQUM7QUFDMUQsY0FBYyxzREFBc0QsQ0FBQztBQUNyRSxjQUFjLDREQUE0RCxDQUFDO0FBQzNFLGNBQWMsZ0RBQWdELENBQUM7QUFDL0QsY0FBYyx1Q0FBdUMsQ0FBQztBQUN0RCxjQUFjLG9DQUFvQyxDQUFDO0FBQ25ELGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYyxrREFBa0QsQ0FBQztBQUNqRSxjQUFjLDhDQUE4QyxDQUFDO0FBQzdELGNBQWMscUNBQXFDLENBQUM7QUFDcEQsY0FBYyxnREFBZ0QsQ0FBQztBQUMvRCxjQUFjLHlDQUF5QyxDQUFDO0FBQ3hELGNBQWMsa0RBQWtELENBQUM7QUFDakUsY0FBYyxnREFBZ0QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBFSVUgQXBwIEtpdCDigJQgdMOhaSBz4butIGThu6VuZyBnaeG7r2EgY8OhYyBBbmd1bGFyIGFwcCAoZmVhdHVyZSBuZXdzIFJlZG1pbmUsIGxhdW5jaGVyIGhlYWRlciwg4oCmKVxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vbGliL2VpdS1hcHAta2l0LnRva2Vucyc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9hcHAtbGF1bmNoZXIvZWl1LWFwcC1sYXVuY2hlci1tZW51Lm1vZGVsJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2FwcC1sYXVuY2hlci9laXUtYXBwLWxhdW5jaGVyLW1lbnUudG9rZW4nO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvYXBwLWxhdW5jaGVyL2VpdS1hcHAtbGF1bmNoZXIuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2FwcC1sYXVuY2hlci9laXUtYXBwLWxhdW5jaGVyLm1vZHVsZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9zaWRlYmFyLXNoYXJlZC9zaWRlYmFyLXNoYXJlZC5tb2RlbCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9zaWRlYmFyLXNoYXJlZC9sb2dvL2VpdS1zaWRlYmFyLWxvZ28uY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3NpZGViYXItc2hhcmVkL2NvbnRhY3QvZWl1LWNvbnRhY3Qtc3VwcG9ydC5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvc2lkZWJhci1zaGFyZWQvZWl1LXNpZGViYXItc2hhcmVkLm1vZHVsZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9mb290ZXIvZWl1LWFwcC1mb290ZXIuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2Zvb3Rlci9laXUtYXBwLWZvb3Rlci5tb2R1bGUnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvZmVhdHVyZS1uZXdzL2NvbnN0YW50cyc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9mZWF0dXJlLW5ld3MvbW9kZWxzL29wZXJhdGlvbi1yZXN1bHQubW9kZWwnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvZmVhdHVyZS1uZXdzL21vZGVscy9yZWRtaW5lLW5ld3MubW9kZWwnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvZmVhdHVyZS1uZXdzL25ld3MtYXBpLnNlcnZpY2UnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvZmVhdHVyZS1uZXdzL2ZlYXR1cmUtbmV3cy1kaWFsb2cuc2VydmljZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9mZWF0dXJlLW5ld3MvZmVhdHVyZS1uZXdzLnNlcnZpY2UnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvZmVhdHVyZS1uZXdzL2ZlYXR1cmUtbmV3cy1kaWFsb2cuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2ZlYXR1cmUtbmV3cy9laXUtYXBwLWZlYXR1cmUtbmV3cy5tb2R1bGUnO1xuIl19
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2VpdS1hcHAta2l0L3NyYy9wdWJsaWMtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLGdEQUFnRCxDQUFDO0FBQy9ELGNBQWMsZ0RBQWdELENBQUM7QUFDL0QsY0FBYywrQ0FBK0MsQ0FBQztBQUM5RCxjQUFjLDRDQUE0QyxDQUFDO0FBQzNELGNBQWMscUNBQXFDLENBQUM7QUFDcEQsY0FBYyw2Q0FBNkMsQ0FBQztBQUM1RCxjQUFjLDBDQUEwQyxDQUFDO0FBQ3pELGNBQWMsMkNBQTJDLENBQUM7QUFDMUQsY0FBYyxzREFBc0QsQ0FBQztBQUNyRSxjQUFjLDREQUE0RCxDQUFDO0FBQzNFLGNBQWMsZ0RBQWdELENBQUM7QUFDL0QsY0FBYyx1Q0FBdUMsQ0FBQztBQUN0RCxjQUFjLG9DQUFvQyxDQUFDO0FBQ25ELGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYyxrREFBa0QsQ0FBQztBQUNqRSxjQUFjLDhDQUE4QyxDQUFDO0FBQzdELGNBQWMscUNBQXFDLENBQUM7QUFDcEQsY0FBYyxnREFBZ0QsQ0FBQztBQUMvRCxjQUFjLHlDQUF5QyxDQUFDO0FBQ3hELGNBQWMsa0RBQWtELENBQUM7QUFDakUsY0FBYyxnREFBZ0QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXHJcbiAqIEVJVSBBcHAgS2l0IOKAlCB0w6FpIHPhu60gZOG7pW5nIGdp4buvYSBjw6FjIEFuZ3VsYXIgYXBwIChmZWF0dXJlIG5ld3MgUmVkbWluZSwgbGF1bmNoZXIgaGVhZGVyLCDigKYpXHJcbiAqL1xyXG5cclxuZXhwb3J0ICogZnJvbSAnLi9saWIvZWl1LWFwcC1raXQudG9rZW5zJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvYXBwLWxhdW5jaGVyL2VpdS1hcHAtbGF1bmNoZXItbWVudS5tb2RlbCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL2FwcC1sYXVuY2hlci9laXUtYXBwLWxhdW5jaGVyLW1lbnUudG9rZW4nO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9hcHAtbGF1bmNoZXIvZWl1LWFwcC1sYXVuY2hlci5jb21wb25lbnQnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9hcHAtbGF1bmNoZXIvZWl1LWFwcC1sYXVuY2hlci5tb2R1bGUnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi91c2VyLW1lbnUvZWl1LXVzZXItbWVudS5tb2RlbCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL3VzZXItbWVudS9laXUtYXBwLXVzZXItbWVudS5jb21wb25lbnQnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi91c2VyLW1lbnUvZWl1LWFwcC11c2VyLW1lbnUubW9kdWxlJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvc2lkZWJhci1zaGFyZWQvc2lkZWJhci1zaGFyZWQubW9kZWwnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9zaWRlYmFyLXNoYXJlZC9sb2dvL2VpdS1zaWRlYmFyLWxvZ28uY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvc2lkZWJhci1zaGFyZWQvY29udGFjdC9laXUtY29udGFjdC1zdXBwb3J0LmNvbXBvbmVudCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL3NpZGViYXItc2hhcmVkL2VpdS1zaWRlYmFyLXNoYXJlZC5tb2R1bGUnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9mb290ZXIvZWl1LWFwcC1mb290ZXIuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvZm9vdGVyL2VpdS1hcHAtZm9vdGVyLm1vZHVsZSc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL2ZlYXR1cmUtbmV3cy9jb25zdGFudHMnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9mZWF0dXJlLW5ld3MvbW9kZWxzL29wZXJhdGlvbi1yZXN1bHQubW9kZWwnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9mZWF0dXJlLW5ld3MvbW9kZWxzL3JlZG1pbmUtbmV3cy5tb2RlbCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL2ZlYXR1cmUtbmV3cy9uZXdzLWFwaS5zZXJ2aWNlJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvZmVhdHVyZS1uZXdzL2ZlYXR1cmUtbmV3cy1kaWFsb2cuc2VydmljZSc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL2ZlYXR1cmUtbmV3cy9mZWF0dXJlLW5ld3Muc2VydmljZSc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL2ZlYXR1cmUtbmV3cy9mZWF0dXJlLW5ld3MtZGlhbG9nLmNvbXBvbmVudCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL2ZlYXR1cmUtbmV3cy9laXUtYXBwLWZlYXR1cmUtbmV3cy5tb2R1bGUnO1xyXG4iXX0=
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, EventEmitter, Component, Inject, Output, Input, HostListener, NgModule, inject, Injectable } from '@angular/core';
2
+ import { InjectionToken, EventEmitter, Component, Inject, Output, Input, HostListener, NgModule, ViewChild, inject, Injectable } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i1$1 from '@angular/router';
@@ -125,6 +125,109 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
125
125
  }]
126
126
  }] });
127
127
 
128
+ class EiuAppUserMenuComponent {
129
+ constructor() {
130
+ /** Thông tin user — host bind từ service token / session. */
131
+ this.profile = null;
132
+ /** Ảnh mặc định khi `picture` lỗi hoặc trống (đường dẫn trong assets của host). */
133
+ this.fallbackAvatar = 'assets/img/icons/default-profile.png';
134
+ this.changePasswordLabel = 'Đổi mật khẩu';
135
+ this.logoutLabel = 'Đăng xuất';
136
+ /** Host xử lý (ví dụ redirect SSO đổi mật khẩu). */
137
+ this.changePassword = new EventEmitter();
138
+ /** Host xử lý (ví dụ Keycloak logout + clear storage). */
139
+ this.logout = new EventEmitter();
140
+ this.menuOpen = false;
141
+ }
142
+ onTriggerClick(event) {
143
+ event.preventDefault();
144
+ event.stopPropagation();
145
+ this.menuOpen = !this.menuOpen;
146
+ }
147
+ onChangePasswordClick(event) {
148
+ event.preventDefault();
149
+ this.changePassword.emit();
150
+ this.menuOpen = false;
151
+ }
152
+ onLogoutClick(event) {
153
+ event.preventDefault();
154
+ this.logout.emit();
155
+ this.menuOpen = false;
156
+ }
157
+ onAvatarError(event) {
158
+ const img = event.target;
159
+ if (img && img.src !== this._absoluteFallback()) {
160
+ img.src = this.fallbackAvatar;
161
+ }
162
+ }
163
+ onDocumentClick(event) {
164
+ var _a;
165
+ if (!this.menuOpen) {
166
+ return;
167
+ }
168
+ const root = (_a = this._root) === null || _a === void 0 ? void 0 : _a.nativeElement;
169
+ if (root && !root.contains(event.target)) {
170
+ this.menuOpen = false;
171
+ }
172
+ }
173
+ onEscape() {
174
+ this.menuOpen = false;
175
+ }
176
+ _absoluteFallback() {
177
+ try {
178
+ return new URL(this.fallbackAvatar, window.location.origin).href;
179
+ }
180
+ catch (_a) {
181
+ return this.fallbackAvatar;
182
+ }
183
+ }
184
+ }
185
+ EiuAppUserMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EiuAppUserMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
186
+ EiuAppUserMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: EiuAppUserMenuComponent, selector: "app-eiu-user-menu", inputs: { profile: "profile", fallbackAvatar: "fallbackAvatar", changePasswordLabel: "changePasswordLabel", logoutLabel: "logoutLabel" }, outputs: { changePassword: "changePassword", logout: "logout" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" } }, viewQueries: [{ propertyName: "_root", first: true, predicate: ["root"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"eiu-user-menu\" #root *ngIf=\"profile as p\">\r\n <div class=\"eiu-user-menu__shell\">\r\n <a\r\n class=\"nav-link eiu-user-menu__trigger\"\r\n href=\"#\"\r\n role=\"button\"\r\n [attr.aria-expanded]=\"menuOpen\"\r\n [attr.aria-haspopup]=\"true\"\r\n (click)=\"onTriggerClick($event)\"\r\n >\r\n <div class=\"eiu-user-menu__trigger-inner\">\r\n <img\r\n [src]=\"p.picture || fallbackAvatar\"\r\n [alt]=\"p.fullName\"\r\n width=\"25\"\r\n height=\"25\"\r\n class=\"eiu-user-menu__img eiu-user-menu__img--sm\"\r\n (error)=\"onAvatarError($event)\"\r\n />\r\n <span class=\"eiu-user-menu__name text-grey-8 text-capitalize\">{{ p.fullName }}</span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"eiu-user-menu__dropdown\" *ngIf=\"menuOpen\" role=\"menu\">\r\n <div class=\"eiu-user-menu__header bg-eiu-primary\">\r\n <img\r\n [src]=\"p.picture || fallbackAvatar\"\r\n [alt]=\"p.fullName\"\r\n width=\"90\"\r\n height=\"90\"\r\n class=\"eiu-user-menu__img eiu-user-menu__img--lg\"\r\n (error)=\"onAvatarError($event)\"\r\n />\r\n <p>\r\n <span>{{ p.fullName }}</span>\r\n <small *ngIf=\"p.email as email\">\r\n <span class=\"mr-2\">{{ email }}</span>\r\n </small>\r\n </p>\r\n </div>\r\n <div class=\"eiu-user-menu__footer\">\r\n <a\r\n href=\"#\"\r\n class=\"btn btn-default btn-flat float-left\"\r\n role=\"menuitem\"\r\n (click)=\"onChangePasswordClick($event)\"\r\n >\r\n <i class=\"fa fa-exchange-alt mr-1\"></i>\r\n {{ changePasswordLabel }}\r\n </a>\r\n <a\r\n href=\"#\"\r\n class=\"btn btn-default btn-flat float-right\"\r\n role=\"menuitem\"\r\n (click)=\"onLogoutClick($event)\"\r\n >\r\n <i class=\"fa fa-sign-out-alt mr-1\"></i>\r\n {{ logoutLabel }}\r\n </a>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:flex;justify-content:center;align-items:center}.eiu-user-menu{position:relative;border:none;width:auto;display:flex;justify-content:center;align-items:center}.eiu-user-menu__shell{position:relative;display:flex;align-items:center}.eiu-user-menu__trigger{padding:.5rem .75rem}.eiu-user-menu__dropdown{position:absolute;right:0;top:100%;z-index:1050;min-width:280px;margin-top:.25rem;background:#fff;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;box-shadow:0 .5rem 1rem #0000002d}.eiu-user-menu__img--sm{margin:0 3px;border-radius:50%;object-fit:cover;box-shadow:0 3px 6px #00000029,0 3px 6px #0000003b}.eiu-user-menu__img--lg{border-radius:50%;object-fit:cover;box-shadow:0 3px 6px #00000029,0 3px 6px #0000003b;border:3px solid rgba(255,255,255,.2)}.eiu-user-menu__header{display:flex;align-items:center;flex-direction:column;height:175px;padding:10px;text-align:center}.eiu-user-menu__header img{z-index:5;height:90px;width:90px}.eiu-user-menu__header p{z-index:5;font-size:17px;margin-top:10px}.eiu-user-menu__header p small{display:block;font-size:12px}.eiu-user-menu__footer{background-color:#f8f9fa;padding:10px}.eiu-user-menu__footer:after{display:block;clear:both;content:\"\"}.eiu-user-menu__footer .btn-default{color:#6c757d;font-size:13px}@media (min-width: 576px){.eiu-user-menu__footer .btn-default:hover{background-color:#f8f9fa}}.eiu-user-menu__trigger-inner{display:flex;flex-wrap:wrap;align-items:center}.eiu-user-menu__trigger-inner .eiu-user-menu__name{max-width:0 15px;margin:3px auto}.text-grey-8{color:#616161}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
187
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EiuAppUserMenuComponent, decorators: [{
188
+ type: Component,
189
+ args: [{ selector: 'app-eiu-user-menu', template: "<div class=\"eiu-user-menu\" #root *ngIf=\"profile as p\">\r\n <div class=\"eiu-user-menu__shell\">\r\n <a\r\n class=\"nav-link eiu-user-menu__trigger\"\r\n href=\"#\"\r\n role=\"button\"\r\n [attr.aria-expanded]=\"menuOpen\"\r\n [attr.aria-haspopup]=\"true\"\r\n (click)=\"onTriggerClick($event)\"\r\n >\r\n <div class=\"eiu-user-menu__trigger-inner\">\r\n <img\r\n [src]=\"p.picture || fallbackAvatar\"\r\n [alt]=\"p.fullName\"\r\n width=\"25\"\r\n height=\"25\"\r\n class=\"eiu-user-menu__img eiu-user-menu__img--sm\"\r\n (error)=\"onAvatarError($event)\"\r\n />\r\n <span class=\"eiu-user-menu__name text-grey-8 text-capitalize\">{{ p.fullName }}</span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"eiu-user-menu__dropdown\" *ngIf=\"menuOpen\" role=\"menu\">\r\n <div class=\"eiu-user-menu__header bg-eiu-primary\">\r\n <img\r\n [src]=\"p.picture || fallbackAvatar\"\r\n [alt]=\"p.fullName\"\r\n width=\"90\"\r\n height=\"90\"\r\n class=\"eiu-user-menu__img eiu-user-menu__img--lg\"\r\n (error)=\"onAvatarError($event)\"\r\n />\r\n <p>\r\n <span>{{ p.fullName }}</span>\r\n <small *ngIf=\"p.email as email\">\r\n <span class=\"mr-2\">{{ email }}</span>\r\n </small>\r\n </p>\r\n </div>\r\n <div class=\"eiu-user-menu__footer\">\r\n <a\r\n href=\"#\"\r\n class=\"btn btn-default btn-flat float-left\"\r\n role=\"menuitem\"\r\n (click)=\"onChangePasswordClick($event)\"\r\n >\r\n <i class=\"fa fa-exchange-alt mr-1\"></i>\r\n {{ changePasswordLabel }}\r\n </a>\r\n <a\r\n href=\"#\"\r\n class=\"btn btn-default btn-flat float-right\"\r\n role=\"menuitem\"\r\n (click)=\"onLogoutClick($event)\"\r\n >\r\n <i class=\"fa fa-sign-out-alt mr-1\"></i>\r\n {{ logoutLabel }}\r\n </a>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:flex;justify-content:center;align-items:center}.eiu-user-menu{position:relative;border:none;width:auto;display:flex;justify-content:center;align-items:center}.eiu-user-menu__shell{position:relative;display:flex;align-items:center}.eiu-user-menu__trigger{padding:.5rem .75rem}.eiu-user-menu__dropdown{position:absolute;right:0;top:100%;z-index:1050;min-width:280px;margin-top:.25rem;background:#fff;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;box-shadow:0 .5rem 1rem #0000002d}.eiu-user-menu__img--sm{margin:0 3px;border-radius:50%;object-fit:cover;box-shadow:0 3px 6px #00000029,0 3px 6px #0000003b}.eiu-user-menu__img--lg{border-radius:50%;object-fit:cover;box-shadow:0 3px 6px #00000029,0 3px 6px #0000003b;border:3px solid rgba(255,255,255,.2)}.eiu-user-menu__header{display:flex;align-items:center;flex-direction:column;height:175px;padding:10px;text-align:center}.eiu-user-menu__header img{z-index:5;height:90px;width:90px}.eiu-user-menu__header p{z-index:5;font-size:17px;margin-top:10px}.eiu-user-menu__header p small{display:block;font-size:12px}.eiu-user-menu__footer{background-color:#f8f9fa;padding:10px}.eiu-user-menu__footer:after{display:block;clear:both;content:\"\"}.eiu-user-menu__footer .btn-default{color:#6c757d;font-size:13px}@media (min-width: 576px){.eiu-user-menu__footer .btn-default:hover{background-color:#f8f9fa}}.eiu-user-menu__trigger-inner{display:flex;flex-wrap:wrap;align-items:center}.eiu-user-menu__trigger-inner .eiu-user-menu__name{max-width:0 15px;margin:3px auto}.text-grey-8{color:#616161}\n"] }]
190
+ }], propDecorators: { _root: [{
191
+ type: ViewChild,
192
+ args: ['root', { static: true }]
193
+ }], profile: [{
194
+ type: Input
195
+ }], fallbackAvatar: [{
196
+ type: Input
197
+ }], changePasswordLabel: [{
198
+ type: Input
199
+ }], logoutLabel: [{
200
+ type: Input
201
+ }], changePassword: [{
202
+ type: Output
203
+ }], logout: [{
204
+ type: Output
205
+ }], onDocumentClick: [{
206
+ type: HostListener,
207
+ args: ['document:click', ['$event']]
208
+ }], onEscape: [{
209
+ type: HostListener,
210
+ args: ['document:keydown.escape']
211
+ }] } });
212
+
213
+ /**
214
+ * Menu user header (avatar, đổi mật khẩu, đăng xuất).
215
+ * Host cung cấp `[profile]` và xử lý `(changePassword)` / `(logout)`.
216
+ */
217
+ class EiuAppUserMenuModule {
218
+ }
219
+ EiuAppUserMenuModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EiuAppUserMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
220
+ EiuAppUserMenuModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: EiuAppUserMenuModule, declarations: [EiuAppUserMenuComponent], imports: [CommonModule], exports: [EiuAppUserMenuComponent] });
221
+ EiuAppUserMenuModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EiuAppUserMenuModule, imports: [CommonModule] });
222
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EiuAppUserMenuModule, decorators: [{
223
+ type: NgModule,
224
+ args: [{
225
+ imports: [CommonModule],
226
+ declarations: [EiuAppUserMenuComponent],
227
+ exports: [EiuAppUserMenuComponent]
228
+ }]
229
+ }] });
230
+
128
231
  class EiuSidebarLogoComponent {
129
232
  constructor() {
130
233
  this.imageUrl = '';
@@ -414,5 +517,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
414
517
  * Generated bundle index. Do not edit.
415
518
  */
416
519
 
417
- export { EIU_APP_API_BASE_URL, EIU_APP_LAUNCHER_MENU_LOADER, EiuAppFeatureNewsModule, EiuAppFooterComponent, EiuAppFooterModule, EiuAppLauncherComponent, EiuAppLauncherModule, EiuContactSupportComponent, EiuSidebarLogoComponent, EiuSidebarSharedModule, FEATURE_NEWS_REDMINE_PROJECT_IDENTIFIER, FEATURE_NEWS_SEEN_STORAGE_KEY_PREFIX, FeatureNewsDialogComponent, FeatureNewsDialogService, FeatureNewsService, NewsApiService };
520
+ export { EIU_APP_API_BASE_URL, EIU_APP_LAUNCHER_MENU_LOADER, EiuAppFeatureNewsModule, EiuAppFooterComponent, EiuAppFooterModule, EiuAppLauncherComponent, EiuAppLauncherModule, EiuAppUserMenuComponent, EiuAppUserMenuModule, EiuContactSupportComponent, EiuSidebarLogoComponent, EiuSidebarSharedModule, FEATURE_NEWS_REDMINE_PROJECT_IDENTIFIER, FEATURE_NEWS_SEEN_STORAGE_KEY_PREFIX, FeatureNewsDialogComponent, FeatureNewsDialogService, FeatureNewsService, NewsApiService };
418
521
  //# sourceMappingURL=eiu-app-kit.mjs.map