@goat-bravos/intern-hub-layout 3.0.4 → 3.0.7
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { EventEmitter, Output, Input, Component, ViewChild } from '@angular/core';
|
|
2
|
+
import { EventEmitter, Output, Input, Component, ViewChild, ChangeDetectionStrategy } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
import * as i2 from '@angular/router';
|
|
@@ -75,6 +75,7 @@ class HeaderComponent {
|
|
|
75
75
|
dropdownIcon: 'dsi-arrow-down-solid',
|
|
76
76
|
logo: 'assets/FPT-IS-Logo.png',
|
|
77
77
|
};
|
|
78
|
+
paddingHeader = '12px 20px 12px 16px';
|
|
78
79
|
handleActionClick(item, event) {
|
|
79
80
|
if (item.method) {
|
|
80
81
|
event.preventDefault();
|
|
@@ -95,13 +96,15 @@ class HeaderComponent {
|
|
|
95
96
|
return icon;
|
|
96
97
|
}
|
|
97
98
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: HeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
98
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: HeaderComponent, isStandalone: true, selector: "app-header-component", inputs: { data: "data" }, ngImport: i0, template: "<header class=\"app-header\">\r\n <div class=\"header-left\">\r\n <img\r\n class=\"logo\"\r\n [src]=\"data.logo || 'assets/FPT-IS-Logo.png'\"\r\n alt=\"Logo\"\r\n />\r\n </div>\r\n\r\n <div class=\"header-right\">\r\n @for (item of data.headerItems; track $index) {\r\n <button\r\n class=\"header-btn\"\r\n [attr.aria-label]=\"item.content\"\r\n (click)=\"handleActionClick(item, $event)\"\r\n >\r\n <app-icon\r\n [iconData]=\"\r\n getIconData(\r\n item.icon,\r\n item.colorIcon,\r\n item.width || '16px',\r\n item.height || '16px'\r\n )\r\n \"\r\n ></app-icon>\r\n @if (item.badge) {\r\n <span class=\"badge\">{{ item.badge }}</span>\r\n }\r\n </button>\r\n }\r\n\r\n <div class=\"header-user\">\r\n <button class=\"user-btn\">\r\n @if (data.userIcon) {\r\n <app-icon\r\n [iconData]=\"\r\n getIconData(data.userIcon, data.userIconColor, '16px', '16px')\r\n \"\r\n ></app-icon>\r\n }\r\n <span class=\"user-name\">{{ data.userName }}</span>\r\n @if (data.dropdownIcon) {\r\n <app-icon\r\n [iconData]=\"\r\n getIconData(\r\n data.dropdownIcon,\r\n data.dropdownIconColor,\r\n '16px',\r\n '16px'\r\n )\r\n \"\r\n ></app-icon>\r\n }\r\n </button>\r\n </div>\r\n </div>\r\n</header>\r\n", styles: [":host{width:100%;display:flex;justify-content:center}.app-header{height:70px;width:1370px;display:flex;align-items:center;justify-content:space-between;
|
|
99
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: HeaderComponent, isStandalone: true, selector: "app-header-component", inputs: { data: "data", paddingHeader: "paddingHeader" }, ngImport: i0, template: "<header class=\"app-header\" [style.padding]=\"paddingHeader\">\r\n <div class=\"header-left\">\r\n <img\r\n class=\"logo\"\r\n [src]=\"data.logo || 'assets/FPT-IS-Logo.png'\"\r\n alt=\"Logo\"\r\n />\r\n </div>\r\n\r\n <div class=\"header-right\">\r\n @for (item of data.headerItems; track $index) {\r\n <button\r\n class=\"header-btn\"\r\n [attr.aria-label]=\"item.content\"\r\n (click)=\"handleActionClick(item, $event)\"\r\n >\r\n <app-icon\r\n [iconData]=\"\r\n getIconData(\r\n item.icon,\r\n item.colorIcon,\r\n item.width || '16px',\r\n item.height || '16px'\r\n )\r\n \"\r\n ></app-icon>\r\n @if (item.badge) {\r\n <span class=\"badge\">{{ item.badge }}</span>\r\n }\r\n </button>\r\n }\r\n\r\n <div class=\"header-user\">\r\n <button class=\"user-btn\">\r\n @if (data.userIcon) {\r\n <app-icon\r\n [iconData]=\"\r\n getIconData(data.userIcon, data.userIconColor, '16px', '16px')\r\n \"\r\n ></app-icon>\r\n }\r\n <span class=\"user-name\">{{ data.userName }}</span>\r\n @if (data.dropdownIcon) {\r\n <app-icon\r\n [iconData]=\"\r\n getIconData(\r\n data.dropdownIcon,\r\n data.dropdownIconColor,\r\n '16px',\r\n '16px'\r\n )\r\n \"\r\n ></app-icon>\r\n }\r\n </button>\r\n </div>\r\n </div>\r\n</header>\r\n", styles: [":host{width:100%;display:flex;justify-content:center}.app-header{height:70px;width:1370px;display:flex;align-items:center;justify-content:space-between;background-color:transparent;box-sizing:border-box}.header-left{display:flex;align-items:center}.header-left .logo{height:40px;width:auto;object-fit:contain;cursor:pointer}.header-right{display:flex;align-items:center;gap:12px}.header-btn{position:relative;width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:transparent;border-radius:28px;border:none;cursor:pointer;color:var(--brand-600);transition:all .2s ease-in-out}.header-btn:hover{background-color:var(--neutral-color-100);color:var(--primary-color)}.header-btn .badge{position:absolute;top:-4px;right:-4px;min-width:16px;height:16px;padding:12px 20px 12px 16px;display:flex;align-items:center;justify-content:center;background-color:var(-utility-500);color:var(--neutral-color-100);border-radius:8px;font-size:10px;font-weight:600;line-height:1}.header-user{margin-left:4px;padding-left:12px 20px 12px 16px}.user-btn{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 20px 12px 16px;background:transparent;border:none;border-radius:8px;cursor:pointer;transition:background-color .2s ease}.user-btn:hover{background-color:var(--neutral-color-100)}.user-btn .user-name{font-size:14px;font-weight:700;color:var(--brand-600);white-space:nowrap;max-width:150px;overflow:hidden;text-overflow:ellipsis}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IconComponent, selector: "app-icon", inputs: ["iconData", "icon", "colorIcon", "routerLink", "width", "height", "colorIconHover", "backgroundColorHover"], outputs: ["clicked"] }] });
|
|
99
100
|
}
|
|
100
101
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: HeaderComponent, decorators: [{
|
|
101
102
|
type: Component,
|
|
102
|
-
args: [{ selector: 'app-header-component', standalone: true, imports: [CommonModule, IconComponent], template: "<header class=\"app-header\">\r\n <div class=\"header-left\">\r\n <img\r\n class=\"logo\"\r\n [src]=\"data.logo || 'assets/FPT-IS-Logo.png'\"\r\n alt=\"Logo\"\r\n />\r\n </div>\r\n\r\n <div class=\"header-right\">\r\n @for (item of data.headerItems; track $index) {\r\n <button\r\n class=\"header-btn\"\r\n [attr.aria-label]=\"item.content\"\r\n (click)=\"handleActionClick(item, $event)\"\r\n >\r\n <app-icon\r\n [iconData]=\"\r\n getIconData(\r\n item.icon,\r\n item.colorIcon,\r\n item.width || '16px',\r\n item.height || '16px'\r\n )\r\n \"\r\n ></app-icon>\r\n @if (item.badge) {\r\n <span class=\"badge\">{{ item.badge }}</span>\r\n }\r\n </button>\r\n }\r\n\r\n <div class=\"header-user\">\r\n <button class=\"user-btn\">\r\n @if (data.userIcon) {\r\n <app-icon\r\n [iconData]=\"\r\n getIconData(data.userIcon, data.userIconColor, '16px', '16px')\r\n \"\r\n ></app-icon>\r\n }\r\n <span class=\"user-name\">{{ data.userName }}</span>\r\n @if (data.dropdownIcon) {\r\n <app-icon\r\n [iconData]=\"\r\n getIconData(\r\n data.dropdownIcon,\r\n data.dropdownIconColor,\r\n '16px',\r\n '16px'\r\n )\r\n \"\r\n ></app-icon>\r\n }\r\n </button>\r\n </div>\r\n </div>\r\n</header>\r\n", styles: [":host{width:100%;display:flex;justify-content:center}.app-header{height:70px;width:1370px;display:flex;align-items:center;justify-content:space-between;
|
|
103
|
+
args: [{ selector: 'app-header-component', standalone: true, imports: [CommonModule, IconComponent], template: "<header class=\"app-header\" [style.padding]=\"paddingHeader\">\r\n <div class=\"header-left\">\r\n <img\r\n class=\"logo\"\r\n [src]=\"data.logo || 'assets/FPT-IS-Logo.png'\"\r\n alt=\"Logo\"\r\n />\r\n </div>\r\n\r\n <div class=\"header-right\">\r\n @for (item of data.headerItems; track $index) {\r\n <button\r\n class=\"header-btn\"\r\n [attr.aria-label]=\"item.content\"\r\n (click)=\"handleActionClick(item, $event)\"\r\n >\r\n <app-icon\r\n [iconData]=\"\r\n getIconData(\r\n item.icon,\r\n item.colorIcon,\r\n item.width || '16px',\r\n item.height || '16px'\r\n )\r\n \"\r\n ></app-icon>\r\n @if (item.badge) {\r\n <span class=\"badge\">{{ item.badge }}</span>\r\n }\r\n </button>\r\n }\r\n\r\n <div class=\"header-user\">\r\n <button class=\"user-btn\">\r\n @if (data.userIcon) {\r\n <app-icon\r\n [iconData]=\"\r\n getIconData(data.userIcon, data.userIconColor, '16px', '16px')\r\n \"\r\n ></app-icon>\r\n }\r\n <span class=\"user-name\">{{ data.userName }}</span>\r\n @if (data.dropdownIcon) {\r\n <app-icon\r\n [iconData]=\"\r\n getIconData(\r\n data.dropdownIcon,\r\n data.dropdownIconColor,\r\n '16px',\r\n '16px'\r\n )\r\n \"\r\n ></app-icon>\r\n }\r\n </button>\r\n </div>\r\n </div>\r\n</header>\r\n", styles: [":host{width:100%;display:flex;justify-content:center}.app-header{height:70px;width:1370px;display:flex;align-items:center;justify-content:space-between;background-color:transparent;box-sizing:border-box}.header-left{display:flex;align-items:center}.header-left .logo{height:40px;width:auto;object-fit:contain;cursor:pointer}.header-right{display:flex;align-items:center;gap:12px}.header-btn{position:relative;width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:transparent;border-radius:28px;border:none;cursor:pointer;color:var(--brand-600);transition:all .2s ease-in-out}.header-btn:hover{background-color:var(--neutral-color-100);color:var(--primary-color)}.header-btn .badge{position:absolute;top:-4px;right:-4px;min-width:16px;height:16px;padding:12px 20px 12px 16px;display:flex;align-items:center;justify-content:center;background-color:var(-utility-500);color:var(--neutral-color-100);border-radius:8px;font-size:10px;font-weight:600;line-height:1}.header-user{margin-left:4px;padding-left:12px 20px 12px 16px}.user-btn{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 20px 12px 16px;background:transparent;border:none;border-radius:8px;cursor:pointer;transition:background-color .2s ease}.user-btn:hover{background-color:var(--neutral-color-100)}.user-btn .user-name{font-size:14px;font-weight:700;color:var(--brand-600);white-space:nowrap;max-width:150px;overflow:hidden;text-overflow:ellipsis}\n"] }]
|
|
103
104
|
}], propDecorators: { data: [{
|
|
104
105
|
type: Input
|
|
106
|
+
}], paddingHeader: [{
|
|
107
|
+
type: Input
|
|
105
108
|
}] } });
|
|
106
109
|
|
|
107
110
|
class FunctionalLabelComponent {
|
|
@@ -137,9 +140,7 @@ class FunctionalLabelComponent {
|
|
|
137
140
|
return this.borderRadius;
|
|
138
141
|
}
|
|
139
142
|
get currentColorContent() {
|
|
140
|
-
return this.
|
|
141
|
-
? this.colorContentHover || this.colorContent
|
|
142
|
-
: this.colorContent;
|
|
143
|
+
return this.colorContent;
|
|
143
144
|
}
|
|
144
145
|
get hasIconLeft() {
|
|
145
146
|
return !!this.iconLeft;
|
|
@@ -192,11 +193,11 @@ class FunctionalLabelComponent {
|
|
|
192
193
|
}
|
|
193
194
|
}
|
|
194
195
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FunctionalLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
195
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: FunctionalLabelComponent, isStandalone: true, selector: "app-functional-label", inputs: { iconLeft: "iconLeft", iconRight: "iconRight", colorIconLeft: "colorIconLeft", colorIconRight: "colorIconRight", widthIconLeft: "widthIconLeft", heightIconLeft: "heightIconLeft", widthIconRight: "widthIconRight", heightIconRight: "heightIconRight", colorIconLeftHover: "colorIconLeftHover", colorIconRightHover: "colorIconRightHover", colorContentHover: "colorContentHover", backgroundColorHover: "backgroundColorHover", borderRadiusHover: "borderRadiusHover", content: "content", fontSizeContent: "fontSizeContent", colorContent: "colorContent", widthContent: "widthContent", heightContent: "heightContent", backgroundColor: "backgroundColor", borderRadius: "borderRadius", width: "width", height: "height", routerLink: "routerLink", isSidebarExpanded: "isSidebarExpanded" }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<div\r\n class=\"functional-label\"\r\n (click)=\"handleClick($event)\"\r\n (keydown.enter)=\"handleClick($event)\"\r\n (keydown.space)=\"handleClick($event)\"\r\n [attr.tabindex]=\"routerLink ? null : 0\"\r\n [attr.role]=\"routerLink ? null : 'button'\"\r\n [style
|
|
196
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: FunctionalLabelComponent, isStandalone: true, selector: "app-functional-label", inputs: { iconLeft: "iconLeft", iconRight: "iconRight", colorIconLeft: "colorIconLeft", colorIconRight: "colorIconRight", widthIconLeft: "widthIconLeft", heightIconLeft: "heightIconLeft", widthIconRight: "widthIconRight", heightIconRight: "heightIconRight", colorIconLeftHover: "colorIconLeftHover", colorIconRightHover: "colorIconRightHover", colorContentHover: "colorContentHover", backgroundColorHover: "backgroundColorHover", borderRadiusHover: "borderRadiusHover", content: "content", fontSizeContent: "fontSizeContent", colorContent: "colorContent", widthContent: "widthContent", heightContent: "heightContent", backgroundColor: "backgroundColor", borderRadius: "borderRadius", width: "width", height: "height", routerLink: "routerLink", isSidebarExpanded: "isSidebarExpanded" }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<div\r\n class=\"functional-label\"\r\n (click)=\"handleClick($event)\"\r\n (keydown.enter)=\"handleClick($event)\"\r\n (keydown.space)=\"handleClick($event)\"\r\n [attr.tabindex]=\"routerLink ? null : 0\"\r\n [attr.role]=\"routerLink ? null : 'button'\"\r\n [style.--bg-color]=\"backgroundColor\"\r\n [style.--bg-hover-color]=\"backgroundColorHover || backgroundColor\"\r\n [style.border-radius]=\"borderRadius\"\r\n [style.width]=\"width\"\r\n [style.height]=\"height\"\r\n [style.--content-hover-color]=\"colorContentHover\"\r\n>\r\n @if (hasIconLeft && iconLeftData) {\r\n <app-icon\r\n [iconData]=\"iconLeftData\"\r\n [width]=\"widthIconLeft\"\r\n [height]=\"heightIconLeft\"\r\n ></app-icon>\r\n }\r\n\r\n <a\r\n [routerLink]=\"routerLink\"\r\n [style.width]=\"widthContent\"\r\n [style.height]=\"heightContent\"\r\n [style.font-size]=\"fontSizeContent\"\r\n [style.--content-color]=\"colorContent\"\r\n >\r\n {{ content }}\r\n </a>\r\n\r\n @if (hasIconRight && iconRightData) {\r\n <app-icon\r\n [iconData]=\"iconRightData\"\r\n [width]=\"widthIconRight\"\r\n [height]=\"heightIconRight\"\r\n ></app-icon>\r\n }\r\n</div>\r\n", styles: [":host{display:block;width:100%}.functional-label{display:flex;align-items:center;justify-content:center;height:40px;padding:0;cursor:pointer;box-sizing:border-box;transition:all .3s ease;background-color:var(--bg-color, transparent)}.functional-label:hover{background-color:var(--bg-hover-color, var(--bg-color, transparent))}.functional-label:hover a{color:var(--content-hover-color, var(--content-color))}.functional-label app-icon{display:flex;flex-shrink:0;justify-content:center;width:44px}.functional-label a{max-width:0;opacity:0;visibility:hidden;white-space:nowrap;overflow:hidden;text-decoration:none;color:var(--content-color, var(--neutral-color-400));transform:translate(-10px);transition:all .3s ease;display:flex;justify-content:flex-start;align-items:center}:host-context(.sidebar-wrapper.expanded) .functional-label{justify-content:flex-start;padding-left:8px}:host-context(.sidebar-wrapper.expanded) .functional-label a{opacity:1;visibility:visible;max-width:200px;transform:translate(0);flex:1;text-align:left}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: IconComponent, selector: "app-icon", inputs: ["iconData", "icon", "colorIcon", "routerLink", "width", "height", "colorIconHover", "backgroundColorHover"], outputs: ["clicked"] }] });
|
|
196
197
|
}
|
|
197
198
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FunctionalLabelComponent, decorators: [{
|
|
198
199
|
type: Component,
|
|
199
|
-
args: [{ selector: 'app-functional-label', standalone: true, imports: [CommonModule, RouterModule, IconComponent], template: "<div\r\n class=\"functional-label\"\r\n (click)=\"handleClick($event)\"\r\n (keydown.enter)=\"handleClick($event)\"\r\n (keydown.space)=\"handleClick($event)\"\r\n [attr.tabindex]=\"routerLink ? null : 0\"\r\n [attr.role]=\"routerLink ? null : 'button'\"\r\n [style
|
|
200
|
+
args: [{ selector: 'app-functional-label', standalone: true, imports: [CommonModule, RouterModule, IconComponent], template: "<div\r\n class=\"functional-label\"\r\n (click)=\"handleClick($event)\"\r\n (keydown.enter)=\"handleClick($event)\"\r\n (keydown.space)=\"handleClick($event)\"\r\n [attr.tabindex]=\"routerLink ? null : 0\"\r\n [attr.role]=\"routerLink ? null : 'button'\"\r\n [style.--bg-color]=\"backgroundColor\"\r\n [style.--bg-hover-color]=\"backgroundColorHover || backgroundColor\"\r\n [style.border-radius]=\"borderRadius\"\r\n [style.width]=\"width\"\r\n [style.height]=\"height\"\r\n [style.--content-hover-color]=\"colorContentHover\"\r\n>\r\n @if (hasIconLeft && iconLeftData) {\r\n <app-icon\r\n [iconData]=\"iconLeftData\"\r\n [width]=\"widthIconLeft\"\r\n [height]=\"heightIconLeft\"\r\n ></app-icon>\r\n }\r\n\r\n <a\r\n [routerLink]=\"routerLink\"\r\n [style.width]=\"widthContent\"\r\n [style.height]=\"heightContent\"\r\n [style.font-size]=\"fontSizeContent\"\r\n [style.--content-color]=\"colorContent\"\r\n >\r\n {{ content }}\r\n </a>\r\n\r\n @if (hasIconRight && iconRightData) {\r\n <app-icon\r\n [iconData]=\"iconRightData\"\r\n [width]=\"widthIconRight\"\r\n [height]=\"heightIconRight\"\r\n ></app-icon>\r\n }\r\n</div>\r\n", styles: [":host{display:block;width:100%}.functional-label{display:flex;align-items:center;justify-content:center;height:40px;padding:0;cursor:pointer;box-sizing:border-box;transition:all .3s ease;background-color:var(--bg-color, transparent)}.functional-label:hover{background-color:var(--bg-hover-color, var(--bg-color, transparent))}.functional-label:hover a{color:var(--content-hover-color, var(--content-color))}.functional-label app-icon{display:flex;flex-shrink:0;justify-content:center;width:44px}.functional-label a{max-width:0;opacity:0;visibility:hidden;white-space:nowrap;overflow:hidden;text-decoration:none;color:var(--content-color, var(--neutral-color-400));transform:translate(-10px);transition:all .3s ease;display:flex;justify-content:flex-start;align-items:center}:host-context(.sidebar-wrapper.expanded) .functional-label{justify-content:flex-start;padding-left:8px}:host-context(.sidebar-wrapper.expanded) .functional-label a{opacity:1;visibility:visible;max-width:200px;transform:translate(0);flex:1;text-align:left}\n"] }]
|
|
200
201
|
}], propDecorators: { iconLeft: [{
|
|
201
202
|
type: Input
|
|
202
203
|
}], iconRight: [{
|
|
@@ -380,11 +381,11 @@ class SidebarComponent {
|
|
|
380
381
|
console.log('Menu item clicked:', item, event);
|
|
381
382
|
}
|
|
382
383
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
383
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: SidebarComponent, isStandalone: true, selector: "app-sidebar", inputs: { data: "data", sidebarWidthCollapse: "sidebarWidthCollapse", sidebarWidthExpand: "sidebarWidthExpand", isSidebarExpanded: "isSidebarExpanded", leftIcon: "leftIcon", rightIcon: "rightIcon", toggleButtonIconData: "toggleButtonIconData", closeButtonIconData: "closeButtonIconData" }, outputs: { sidebarToggled: "sidebarToggled" }, ngImport: i0, template: "<div class=\"sidebar-wrapper\" [class.expanded]=\"isSidebarExpanded\">\r\n <div>\r\n <aside class=\"sidebar\">\r\n @for (item of data.menuItems; track $index) {\r\n <app-functional-label\r\n class=\"sidebar-item\"\r\n [isSidebarExpanded]=\"isSidebarExpanded\"\r\n [iconLeft]=\"item.iconLeft\"\r\n [iconRight]=\"item.iconRight\"\r\n [content]=\"item.content\"\r\n [routerLink]=\"item.url\"\r\n [colorIconLeft]=\"item.colorIconLeft\"\r\n [colorIconRight]=\"item.colorIconRight\"\r\n [colorContent]=\"item.colorContent\"\r\n [backgroundColor]=\"item.backgroundColor\"\r\n [borderRadius]=\"item.borderRadius\"\r\n (clicked)=\"onMenuItemClick(item, $event)\"\r\n [colorIconLeftHover]=\"item.colorIconLeftHover\"\r\n [colorIconRightHover]=\"item.colorIconRightHover\"\r\n [backgroundColorHover]=\"item.backgroundColorHover\"\r\n [width]=\"item.width\"\r\n [height]=\"item.height\"\r\n ></app-functional-label>\r\n }\r\n </aside>\r\n\r\n <!-- \u2705 Toggle button - ch\u1EC9 hi\u1EC7n khi KH\u00D4NG expanded -->\r\n @if (!isSidebarExpanded) {\r\n <app-button-container\r\n class=\"sidebar-toggle-button\"\r\n [leftIconData]=\"toggleButtonIconData\"\r\n [backgroundColor]=\"data.toggleButtonBackgroundColor || 'transparent'\"\r\n [borderRadius]=\"'8px'\"\r\n [size]=\"'sm'\"\r\n [width]=\"'36px'\"\r\n [height]=\"'36px'\"\r\n (buttonClick)=\"toggleSidebar()\"\r\n ></app-button-container>\r\n }\r\n\r\n <!-- \u2705 Close button - ch\u1EC9 hi\u1EC7n khi expanded -->\r\n @if (isSidebarExpanded) {\r\n <app-button-container\r\n class=\"sidebar-close-button\"\r\n [leftIconData]=\"closeButtonIconData\"\r\n [backgroundColor]=\"\r\n data.closeButtonBackgroundColor || 'var(--brand-400)'\r\n \"\r\n [color]=\"data.toggleButtonIconColor || 'var(--neutral-500)'\"\r\n [borderRadius]=\"'8px'\"\r\n [size]=\"'sm'\"\r\n (buttonClick)=\"toggleSidebar()\"\r\n [width]=\"'36px'\"\r\n [height]=\"'36px'\"\r\n [marginRight]=\"data.closeButtonMarginRight || '24px'\"\r\n [marginLeft]=\"data.closeButtonMarginLeft || 'auto'\"\r\n ></app-button-container>\r\n }\r\n </div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.sidebar-wrapper{width:59px;height:100%;transition:width .3s ease;background-color:transparent;position:relative;display:flex;flex-direction:column;border-radius:16px;overflow:hidden}.sidebar-wrapper.expanded{width:227px}.sidebar-wrapper.expanded .sidebar{width:227px;padding:16px 8px;background-color:var(--theme-neutral-light-100)}.sidebar-wrapper>div{height:100%;display:flex;flex-direction:column;position:relative;background-color:var(--brand-500);border-radius:16px}.sidebar{display:flex;flex-direction:column;gap:8px;flex:1;width:59px;padding:8px;box-sizing:border-box;overflow-y:auto;overflow-x:hidden;background-color:transparent;transition:width .3s ease,padding .3s ease,background-color .3s ease}.sidebar-wrapper.expanded>div{background-color:var(--theme-neutral-light-100)}.sidebar a{text-decoration:none}.sidebar-toggle-button{flex-shrink:0;margin-bottom:16px;margin-left:auto;margin-right:auto}.sidebar-toggle-button ::ng-deep .button-container{width:36px!important;height:36px!important;min-width:36px!important;min-height:36px!important;max-width:36px!important;max-height:36px!important;padding:0!important;border-radius:8px!important;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s ease}.sidebar-toggle-button ::ng-deep .button-container:active{transform:scale(.9)}.sidebar-close-button{flex-shrink:0;margin-bottom:16px}.sidebar-close-button ::ng-deep .button-container{width:36px!important;height:36px!important;min-width:36px!important;min-height:36px!important;max-width:36px!important;max-height:36px!important;padding:0!important;border-radius:8px!important;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s ease}.sidebar-close-button ::ng-deep .button-container:active{transform:scale(.9)}.sidebar::-webkit-scrollbar{width:4px}.sidebar::-webkit-scrollbar-track{background:transparent}.sidebar::-webkit-scrollbar-thumb{background:var(--neutral-300);border-radius:2px}.sidebar::-webkit-scrollbar-thumb:hover{background:var(--neutral-400)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: FunctionalLabelComponent, selector: "app-functional-label", inputs: ["iconLeft", "iconRight", "colorIconLeft", "colorIconRight", "widthIconLeft", "heightIconLeft", "widthIconRight", "heightIconRight", "colorIconLeftHover", "colorIconRightHover", "colorContentHover", "backgroundColorHover", "borderRadiusHover", "content", "fontSizeContent", "colorContent", "widthContent", "heightContent", "backgroundColor", "borderRadius", "width", "height", "routerLink", "isSidebarExpanded"], outputs: ["clicked"] }, { kind: "component", type: ButtonContainerComponent, selector: "app-button-container", inputs: ["buttonData", "size", "content", "fontSize", "leftIcon", "leftIconData", "rightIcon", "rightIconData", "color", "backgroundColor", "border", "borderRadius", "width", "height", "padding", "marginLeft", "marginRight"], outputs: ["buttonClick"] }] });
|
|
384
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: SidebarComponent, isStandalone: true, selector: "app-sidebar", inputs: { data: "data", sidebarWidthCollapse: "sidebarWidthCollapse", sidebarWidthExpand: "sidebarWidthExpand", isSidebarExpanded: "isSidebarExpanded", leftIcon: "leftIcon", rightIcon: "rightIcon", toggleButtonIconData: "toggleButtonIconData", closeButtonIconData: "closeButtonIconData" }, outputs: { sidebarToggled: "sidebarToggled" }, ngImport: i0, template: "<div class=\"sidebar-wrapper\" [class.expanded]=\"isSidebarExpanded\">\r\n <div>\r\n <aside class=\"sidebar\">\r\n @for (item of data.menuItems; track $index) {\r\n <app-functional-label\r\n class=\"sidebar-item\"\r\n [isSidebarExpanded]=\"isSidebarExpanded\"\r\n [iconLeft]=\"item.iconLeft\"\r\n [iconRight]=\"item.iconRight\"\r\n [content]=\"item.content\"\r\n [routerLink]=\"item.url\"\r\n [colorIconLeft]=\"item.colorIconLeft\"\r\n [colorIconRight]=\"item.colorIconRight\"\r\n [colorContent]=\"item.colorContent\"\r\n [colorContentHover]=\"item.colorContentHover\"\r\n [backgroundColor]=\"item.backgroundColor\"\r\n [borderRadius]=\"item.borderRadius\"\r\n (clicked)=\"onMenuItemClick(item, $event)\"\r\n [colorIconLeftHover]=\"item.colorIconLeftHover\"\r\n [colorIconRightHover]=\"item.colorIconRightHover\"\r\n [backgroundColorHover]=\"item.backgroundColorHover\"\r\n [width]=\"item.width\"\r\n [height]=\"item.height\"\r\n ></app-functional-label>\r\n }\r\n </aside>\r\n\r\n <!-- \u2705 Toggle button - ch\u1EC9 hi\u1EC7n khi KH\u00D4NG expanded -->\r\n @if (!isSidebarExpanded) {\r\n <app-button-container\r\n class=\"sidebar-toggle-button\"\r\n [leftIconData]=\"toggleButtonIconData\"\r\n [backgroundColor]=\"data.toggleButtonBackgroundColor || 'transparent'\"\r\n [borderRadius]=\"'8px'\"\r\n [size]=\"'sm'\"\r\n [width]=\"'36px'\"\r\n [height]=\"'36px'\"\r\n (buttonClick)=\"toggleSidebar()\"\r\n ></app-button-container>\r\n }\r\n\r\n <!-- \u2705 Close button - ch\u1EC9 hi\u1EC7n khi expanded -->\r\n @if (isSidebarExpanded) {\r\n <app-button-container\r\n class=\"sidebar-close-button\"\r\n [leftIconData]=\"closeButtonIconData\"\r\n [backgroundColor]=\"\r\n data.closeButtonBackgroundColor || 'var(--brand-400)'\r\n \"\r\n [color]=\"data.toggleButtonIconColor || 'var(--neutral-500)'\"\r\n [borderRadius]=\"'8px'\"\r\n [size]=\"'sm'\"\r\n (buttonClick)=\"toggleSidebar()\"\r\n [width]=\"'36px'\"\r\n [height]=\"'36px'\"\r\n [marginRight]=\"data.closeButtonMarginRight || '24px'\"\r\n [marginLeft]=\"data.closeButtonMarginLeft || 'auto'\"\r\n ></app-button-container>\r\n }\r\n </div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.sidebar-wrapper{width:59px;height:100%;transition:width .3s ease;background-color:transparent;position:relative;display:flex;flex-direction:column;border-radius:16px;overflow:hidden}.sidebar-wrapper.expanded{width:227px}.sidebar-wrapper.expanded .sidebar{width:227px;padding:16px 8px;background-color:var(--theme-neutral-light-100)}.sidebar-wrapper>div{height:100%;display:flex;flex-direction:column;position:relative;background-color:var(--brand-500);border-radius:16px}.sidebar{display:flex;flex-direction:column;gap:8px;flex:1;width:59px;padding:8px;box-sizing:border-box;overflow-y:auto;overflow-x:hidden;background-color:transparent;transition:width .3s ease,padding .3s ease,background-color .3s ease}.sidebar-wrapper.expanded>div{background-color:var(--theme-neutral-light-100)}.sidebar a{text-decoration:none}.sidebar-toggle-button{flex-shrink:0;margin-bottom:16px;margin-left:auto;margin-right:auto}.sidebar-toggle-button ::ng-deep .button-container{width:36px!important;height:36px!important;min-width:36px!important;min-height:36px!important;max-width:36px!important;max-height:36px!important;padding:0!important;border-radius:8px!important;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s ease}.sidebar-toggle-button ::ng-deep .button-container:active{transform:scale(.9)}.sidebar-close-button{flex-shrink:0;margin-bottom:16px}.sidebar-close-button ::ng-deep .button-container{width:36px!important;height:36px!important;min-width:36px!important;min-height:36px!important;max-width:36px!important;max-height:36px!important;padding:0!important;border-radius:8px!important;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s ease}.sidebar-close-button ::ng-deep .button-container:active{transform:scale(.9)}.sidebar::-webkit-scrollbar{width:4px}.sidebar::-webkit-scrollbar-track{background:transparent}.sidebar::-webkit-scrollbar-thumb{background:var(--neutral-300);border-radius:2px}.sidebar::-webkit-scrollbar-thumb:hover{background:var(--neutral-400)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: FunctionalLabelComponent, selector: "app-functional-label", inputs: ["iconLeft", "iconRight", "colorIconLeft", "colorIconRight", "widthIconLeft", "heightIconLeft", "widthIconRight", "heightIconRight", "colorIconLeftHover", "colorIconRightHover", "colorContentHover", "backgroundColorHover", "borderRadiusHover", "content", "fontSizeContent", "colorContent", "widthContent", "heightContent", "backgroundColor", "borderRadius", "width", "height", "routerLink", "isSidebarExpanded"], outputs: ["clicked"] }, { kind: "component", type: ButtonContainerComponent, selector: "app-button-container", inputs: ["buttonData", "size", "content", "fontSize", "leftIcon", "leftIconData", "rightIcon", "rightIconData", "color", "backgroundColor", "border", "borderRadius", "width", "height", "padding", "marginLeft", "marginRight"], outputs: ["buttonClick"] }] });
|
|
384
385
|
}
|
|
385
386
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SidebarComponent, decorators: [{
|
|
386
387
|
type: Component,
|
|
387
|
-
args: [{ selector: 'app-sidebar', standalone: true, imports: [CommonModule, FunctionalLabelComponent, ButtonContainerComponent], template: "<div class=\"sidebar-wrapper\" [class.expanded]=\"isSidebarExpanded\">\r\n <div>\r\n <aside class=\"sidebar\">\r\n @for (item of data.menuItems; track $index) {\r\n <app-functional-label\r\n class=\"sidebar-item\"\r\n [isSidebarExpanded]=\"isSidebarExpanded\"\r\n [iconLeft]=\"item.iconLeft\"\r\n [iconRight]=\"item.iconRight\"\r\n [content]=\"item.content\"\r\n [routerLink]=\"item.url\"\r\n [colorIconLeft]=\"item.colorIconLeft\"\r\n [colorIconRight]=\"item.colorIconRight\"\r\n [colorContent]=\"item.colorContent\"\r\n [backgroundColor]=\"item.backgroundColor\"\r\n [borderRadius]=\"item.borderRadius\"\r\n (clicked)=\"onMenuItemClick(item, $event)\"\r\n [colorIconLeftHover]=\"item.colorIconLeftHover\"\r\n [colorIconRightHover]=\"item.colorIconRightHover\"\r\n [backgroundColorHover]=\"item.backgroundColorHover\"\r\n [width]=\"item.width\"\r\n [height]=\"item.height\"\r\n ></app-functional-label>\r\n }\r\n </aside>\r\n\r\n <!-- \u2705 Toggle button - ch\u1EC9 hi\u1EC7n khi KH\u00D4NG expanded -->\r\n @if (!isSidebarExpanded) {\r\n <app-button-container\r\n class=\"sidebar-toggle-button\"\r\n [leftIconData]=\"toggleButtonIconData\"\r\n [backgroundColor]=\"data.toggleButtonBackgroundColor || 'transparent'\"\r\n [borderRadius]=\"'8px'\"\r\n [size]=\"'sm'\"\r\n [width]=\"'36px'\"\r\n [height]=\"'36px'\"\r\n (buttonClick)=\"toggleSidebar()\"\r\n ></app-button-container>\r\n }\r\n\r\n <!-- \u2705 Close button - ch\u1EC9 hi\u1EC7n khi expanded -->\r\n @if (isSidebarExpanded) {\r\n <app-button-container\r\n class=\"sidebar-close-button\"\r\n [leftIconData]=\"closeButtonIconData\"\r\n [backgroundColor]=\"\r\n data.closeButtonBackgroundColor || 'var(--brand-400)'\r\n \"\r\n [color]=\"data.toggleButtonIconColor || 'var(--neutral-500)'\"\r\n [borderRadius]=\"'8px'\"\r\n [size]=\"'sm'\"\r\n (buttonClick)=\"toggleSidebar()\"\r\n [width]=\"'36px'\"\r\n [height]=\"'36px'\"\r\n [marginRight]=\"data.closeButtonMarginRight || '24px'\"\r\n [marginLeft]=\"data.closeButtonMarginLeft || 'auto'\"\r\n ></app-button-container>\r\n }\r\n </div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.sidebar-wrapper{width:59px;height:100%;transition:width .3s ease;background-color:transparent;position:relative;display:flex;flex-direction:column;border-radius:16px;overflow:hidden}.sidebar-wrapper.expanded{width:227px}.sidebar-wrapper.expanded .sidebar{width:227px;padding:16px 8px;background-color:var(--theme-neutral-light-100)}.sidebar-wrapper>div{height:100%;display:flex;flex-direction:column;position:relative;background-color:var(--brand-500);border-radius:16px}.sidebar{display:flex;flex-direction:column;gap:8px;flex:1;width:59px;padding:8px;box-sizing:border-box;overflow-y:auto;overflow-x:hidden;background-color:transparent;transition:width .3s ease,padding .3s ease,background-color .3s ease}.sidebar-wrapper.expanded>div{background-color:var(--theme-neutral-light-100)}.sidebar a{text-decoration:none}.sidebar-toggle-button{flex-shrink:0;margin-bottom:16px;margin-left:auto;margin-right:auto}.sidebar-toggle-button ::ng-deep .button-container{width:36px!important;height:36px!important;min-width:36px!important;min-height:36px!important;max-width:36px!important;max-height:36px!important;padding:0!important;border-radius:8px!important;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s ease}.sidebar-toggle-button ::ng-deep .button-container:active{transform:scale(.9)}.sidebar-close-button{flex-shrink:0;margin-bottom:16px}.sidebar-close-button ::ng-deep .button-container{width:36px!important;height:36px!important;min-width:36px!important;min-height:36px!important;max-width:36px!important;max-height:36px!important;padding:0!important;border-radius:8px!important;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s ease}.sidebar-close-button ::ng-deep .button-container:active{transform:scale(.9)}.sidebar::-webkit-scrollbar{width:4px}.sidebar::-webkit-scrollbar-track{background:transparent}.sidebar::-webkit-scrollbar-thumb{background:var(--neutral-300);border-radius:2px}.sidebar::-webkit-scrollbar-thumb:hover{background:var(--neutral-400)}\n"] }]
|
|
388
|
+
args: [{ selector: 'app-sidebar', standalone: true, imports: [CommonModule, FunctionalLabelComponent, ButtonContainerComponent], template: "<div class=\"sidebar-wrapper\" [class.expanded]=\"isSidebarExpanded\">\r\n <div>\r\n <aside class=\"sidebar\">\r\n @for (item of data.menuItems; track $index) {\r\n <app-functional-label\r\n class=\"sidebar-item\"\r\n [isSidebarExpanded]=\"isSidebarExpanded\"\r\n [iconLeft]=\"item.iconLeft\"\r\n [iconRight]=\"item.iconRight\"\r\n [content]=\"item.content\"\r\n [routerLink]=\"item.url\"\r\n [colorIconLeft]=\"item.colorIconLeft\"\r\n [colorIconRight]=\"item.colorIconRight\"\r\n [colorContent]=\"item.colorContent\"\r\n [colorContentHover]=\"item.colorContentHover\"\r\n [backgroundColor]=\"item.backgroundColor\"\r\n [borderRadius]=\"item.borderRadius\"\r\n (clicked)=\"onMenuItemClick(item, $event)\"\r\n [colorIconLeftHover]=\"item.colorIconLeftHover\"\r\n [colorIconRightHover]=\"item.colorIconRightHover\"\r\n [backgroundColorHover]=\"item.backgroundColorHover\"\r\n [width]=\"item.width\"\r\n [height]=\"item.height\"\r\n ></app-functional-label>\r\n }\r\n </aside>\r\n\r\n <!-- \u2705 Toggle button - ch\u1EC9 hi\u1EC7n khi KH\u00D4NG expanded -->\r\n @if (!isSidebarExpanded) {\r\n <app-button-container\r\n class=\"sidebar-toggle-button\"\r\n [leftIconData]=\"toggleButtonIconData\"\r\n [backgroundColor]=\"data.toggleButtonBackgroundColor || 'transparent'\"\r\n [borderRadius]=\"'8px'\"\r\n [size]=\"'sm'\"\r\n [width]=\"'36px'\"\r\n [height]=\"'36px'\"\r\n (buttonClick)=\"toggleSidebar()\"\r\n ></app-button-container>\r\n }\r\n\r\n <!-- \u2705 Close button - ch\u1EC9 hi\u1EC7n khi expanded -->\r\n @if (isSidebarExpanded) {\r\n <app-button-container\r\n class=\"sidebar-close-button\"\r\n [leftIconData]=\"closeButtonIconData\"\r\n [backgroundColor]=\"\r\n data.closeButtonBackgroundColor || 'var(--brand-400)'\r\n \"\r\n [color]=\"data.toggleButtonIconColor || 'var(--neutral-500)'\"\r\n [borderRadius]=\"'8px'\"\r\n [size]=\"'sm'\"\r\n (buttonClick)=\"toggleSidebar()\"\r\n [width]=\"'36px'\"\r\n [height]=\"'36px'\"\r\n [marginRight]=\"data.closeButtonMarginRight || '24px'\"\r\n [marginLeft]=\"data.closeButtonMarginLeft || 'auto'\"\r\n ></app-button-container>\r\n }\r\n </div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.sidebar-wrapper{width:59px;height:100%;transition:width .3s ease;background-color:transparent;position:relative;display:flex;flex-direction:column;border-radius:16px;overflow:hidden}.sidebar-wrapper.expanded{width:227px}.sidebar-wrapper.expanded .sidebar{width:227px;padding:16px 8px;background-color:var(--theme-neutral-light-100)}.sidebar-wrapper>div{height:100%;display:flex;flex-direction:column;position:relative;background-color:var(--brand-500);border-radius:16px}.sidebar{display:flex;flex-direction:column;gap:8px;flex:1;width:59px;padding:8px;box-sizing:border-box;overflow-y:auto;overflow-x:hidden;background-color:transparent;transition:width .3s ease,padding .3s ease,background-color .3s ease}.sidebar-wrapper.expanded>div{background-color:var(--theme-neutral-light-100)}.sidebar a{text-decoration:none}.sidebar-toggle-button{flex-shrink:0;margin-bottom:16px;margin-left:auto;margin-right:auto}.sidebar-toggle-button ::ng-deep .button-container{width:36px!important;height:36px!important;min-width:36px!important;min-height:36px!important;max-width:36px!important;max-height:36px!important;padding:0!important;border-radius:8px!important;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s ease}.sidebar-toggle-button ::ng-deep .button-container:active{transform:scale(.9)}.sidebar-close-button{flex-shrink:0;margin-bottom:16px}.sidebar-close-button ::ng-deep .button-container{width:36px!important;height:36px!important;min-width:36px!important;min-height:36px!important;max-width:36px!important;max-height:36px!important;padding:0!important;border-radius:8px!important;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s ease}.sidebar-close-button ::ng-deep .button-container:active{transform:scale(.9)}.sidebar::-webkit-scrollbar{width:4px}.sidebar::-webkit-scrollbar-track{background:transparent}.sidebar::-webkit-scrollbar-thumb{background:var(--neutral-300);border-radius:2px}.sidebar::-webkit-scrollbar-thumb:hover{background:var(--neutral-400)}\n"] }]
|
|
388
389
|
}], propDecorators: { data: [{
|
|
389
390
|
type: Input
|
|
390
391
|
}], sidebarWidthCollapse: [{
|
|
@@ -451,8 +452,12 @@ class InputTextComponent {
|
|
|
451
452
|
borderRadius = '8px';
|
|
452
453
|
padding = '8px 12px';
|
|
453
454
|
height = '36px';
|
|
454
|
-
|
|
455
|
-
|
|
455
|
+
fontSizeContent = '14px';
|
|
456
|
+
fontWeightContent = '500';
|
|
457
|
+
colorContent = 'var(--neutral-color-875)';
|
|
458
|
+
fontSizeLabel = '14px';
|
|
459
|
+
fontWeightLabel = '500';
|
|
460
|
+
colorLabel = 'var(--neutral-color-875)';
|
|
456
461
|
backgroundColor = 'var(--neutral-color-10)';
|
|
457
462
|
valueChange = new EventEmitter();
|
|
458
463
|
iconClick = new EventEmitter();
|
|
@@ -486,11 +491,11 @@ class InputTextComponent {
|
|
|
486
491
|
this.valueChange.emit(this._value);
|
|
487
492
|
}
|
|
488
493
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: InputTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
489
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: InputTextComponent, isStandalone: true, selector: "app-input-text", inputs: { headerInput: "headerInput", placeholder: "placeholder", readonly: "readonly", required: "required", width: "width", maxLength: "maxLength", showLimit: "showLimit", icon: "icon", widthIcon: "widthIcon", heightIcon: "heightIcon", typeInput: "typeInput", showLabel: "showLabel", placeholderColor: "placeholderColor", border: "border", borderRadius: "borderRadius", padding: "padding", height: "height",
|
|
494
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: InputTextComponent, isStandalone: true, selector: "app-input-text", inputs: { headerInput: "headerInput", placeholder: "placeholder", readonly: "readonly", required: "required", width: "width", maxLength: "maxLength", showLimit: "showLimit", icon: "icon", widthIcon: "widthIcon", heightIcon: "heightIcon", typeInput: "typeInput", showLabel: "showLabel", placeholderColor: "placeholderColor", border: "border", borderRadius: "borderRadius", padding: "padding", height: "height", fontSizeContent: "fontSizeContent", fontWeightContent: "fontWeightContent", colorContent: "colorContent", fontSizeLabel: "fontSizeLabel", fontWeightLabel: "fontWeightLabel", colorLabel: "colorLabel", backgroundColor: "backgroundColor", value: "value" }, outputs: { valueChange: "valueChange", iconClick: "iconClick" }, ngImport: i0, template: "<div class=\"input-form\">\r\n <div class=\"input-form-content\">\r\n <label class=\"input-form-label\">\r\n @if (showLabel) {\r\n <span\r\n class=\"label-text\"\r\n [class.hidden]=\"!headerInput\"\r\n [style.font-size]=\"fontSizeLabel || null\"\r\n [style.font-weight]=\"fontWeightLabel || null\"\r\n [style.color]=\"colorLabel || null\"\r\n >\r\n {{ headerInput }}\r\n @if (required) {\r\n <span class=\"required-mark\">*</span>\r\n }\r\n </span>\r\n }\r\n <div class=\"input-field-wrapper\">\r\n <input\r\n [type]=\"typeInput\"\r\n class=\"input-form-field\"\r\n [placeholder]=\"placeholder\"\r\n [readonly]=\"readonly\"\r\n [required]=\"required\"\r\n [style.width]=\"width\"\r\n [style.height]=\"height\"\r\n [style.padding]=\"padding\"\r\n [style.border]=\"border || null\"\r\n [style.border-radius]=\"borderRadius\"\r\n [style.background-color]=\"backgroundColor\"\r\n [style.--placeholder-color]=\"placeholderColor || null\"\r\n [style.font-size]=\"fontSizeContent || null\"\r\n [style.font-weight]=\"fontWeightContent || null\"\r\n [style.color]=\"colorContent || null\"\r\n [value]=\"value\"\r\n (input)=\"onInput($event)\"\r\n [attr.maxlength]=\"maxLength > 0 ? maxLength : null\"\r\n />\r\n @if (icon) {\r\n <button\r\n type=\"button\"\r\n class=\"input-icon-button\"\r\n [class.clickable]=\"iconClick.observed\"\r\n (click)=\"onIconClick()\"\r\n [attr.aria-label]=\"icon\"\r\n [disabled]=\"!iconClick.observed\"\r\n >\r\n <i\r\n [class]=\"icon\"\r\n [style.width]=\"widthIcon\"\r\n [style.height]=\"heightIcon\"\r\n class=\"input-icon\"\r\n ></i>\r\n </button>\r\n }\r\n </div>\r\n </label>\r\n </div>\r\n <div class=\"limit\" [class.hidden]=\"!(maxLength > 0 && showLimit)\">\r\n <span>{{ limit }}</span>\r\n </div>\r\n</div>\r\n", styles: [".input-form{display:flex;flex-direction:column;justify-content:space-between;gap:4px}.hidden{display:none}.input-form-label{display:block;font-size:var(--font-sm);font-weight:700;color:var(--neutral-color-700)}.label-text{display:block;margin-bottom:4px;height:20px}.required-mark{color:var(--utility-600);margin-left:2px}.input-form-field{padding:8px 12px;border:1px solid var(--border-color, var(--neutral-color-200));border-radius:var(--radius-md);font-size:var(--font-sm);color:var(--neutral-color-875);height:36px;width:100%;box-sizing:border-box;background-color:var(--neutral-color-10);transition:border-color .2s ease,box-shadow .2s ease}.input-form-field::placeholder{color:var(--placeholder-color, var(--neutral-color-300));opacity:1}.input-form-field:hover{border-color:var(--border-color-hover, var(--neutral-color-400))}.input-form-field:focus{outline:none;border-color:var(--brand-500);box-shadow:0 0 0 2px rgba(var(--brand-500-rgb, 39, 64, 180),.15)}.input-form-field:read-only{background-color:var(--neutral-color-25);cursor:not-allowed}.input-form-field[type=password]{font-family:Verdana,sans-serif;font-size:16px;letter-spacing:3px}.input-form-field[type=password]::placeholder{font-family:inherit;font-size:var(--font-sm);letter-spacing:normal}.input-field-wrapper:has(.input-icon-button) .input-form-field{padding-right:36px}.input-field-wrapper{position:relative;display:flex;align-items:center}.input-icon-button{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;padding:0;margin:0;display:flex;align-items:center;justify-content:center;color:var(--neutral-color-500);transition:color .2s ease;outline:none}.input-icon-button.clickable{cursor:pointer}.input-icon-button.clickable:hover .input-icon{color:var(--brand-500)}.input-icon-button:disabled{cursor:default;pointer-events:none}.input-icon{font-size:14px!important;width:14px;height:14px;display:flex;align-items:center;justify-content:center;transition:color .2s ease}.input-icon:before{font-size:14px!important}.limit{display:flex;justify-content:flex-end}.limit span{font-size:var(--font-xs, 12px);color:var(--neutral-color-500)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
|
|
490
495
|
}
|
|
491
496
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: InputTextComponent, decorators: [{
|
|
492
497
|
type: Component,
|
|
493
|
-
args: [{ selector: 'app-input-text', standalone: true, imports: [CommonModule, FormsModule], template: "<div class=\"input-form\">\r\n <div class=\"input-form-content\">\r\n <label class=\"input-form-label\">\r\n @if (showLabel) {\r\n <span
|
|
498
|
+
args: [{ selector: 'app-input-text', standalone: true, imports: [CommonModule, FormsModule], template: "<div class=\"input-form\">\r\n <div class=\"input-form-content\">\r\n <label class=\"input-form-label\">\r\n @if (showLabel) {\r\n <span\r\n class=\"label-text\"\r\n [class.hidden]=\"!headerInput\"\r\n [style.font-size]=\"fontSizeLabel || null\"\r\n [style.font-weight]=\"fontWeightLabel || null\"\r\n [style.color]=\"colorLabel || null\"\r\n >\r\n {{ headerInput }}\r\n @if (required) {\r\n <span class=\"required-mark\">*</span>\r\n }\r\n </span>\r\n }\r\n <div class=\"input-field-wrapper\">\r\n <input\r\n [type]=\"typeInput\"\r\n class=\"input-form-field\"\r\n [placeholder]=\"placeholder\"\r\n [readonly]=\"readonly\"\r\n [required]=\"required\"\r\n [style.width]=\"width\"\r\n [style.height]=\"height\"\r\n [style.padding]=\"padding\"\r\n [style.border]=\"border || null\"\r\n [style.border-radius]=\"borderRadius\"\r\n [style.background-color]=\"backgroundColor\"\r\n [style.--placeholder-color]=\"placeholderColor || null\"\r\n [style.font-size]=\"fontSizeContent || null\"\r\n [style.font-weight]=\"fontWeightContent || null\"\r\n [style.color]=\"colorContent || null\"\r\n [value]=\"value\"\r\n (input)=\"onInput($event)\"\r\n [attr.maxlength]=\"maxLength > 0 ? maxLength : null\"\r\n />\r\n @if (icon) {\r\n <button\r\n type=\"button\"\r\n class=\"input-icon-button\"\r\n [class.clickable]=\"iconClick.observed\"\r\n (click)=\"onIconClick()\"\r\n [attr.aria-label]=\"icon\"\r\n [disabled]=\"!iconClick.observed\"\r\n >\r\n <i\r\n [class]=\"icon\"\r\n [style.width]=\"widthIcon\"\r\n [style.height]=\"heightIcon\"\r\n class=\"input-icon\"\r\n ></i>\r\n </button>\r\n }\r\n </div>\r\n </label>\r\n </div>\r\n <div class=\"limit\" [class.hidden]=\"!(maxLength > 0 && showLimit)\">\r\n <span>{{ limit }}</span>\r\n </div>\r\n</div>\r\n", styles: [".input-form{display:flex;flex-direction:column;justify-content:space-between;gap:4px}.hidden{display:none}.input-form-label{display:block;font-size:var(--font-sm);font-weight:700;color:var(--neutral-color-700)}.label-text{display:block;margin-bottom:4px;height:20px}.required-mark{color:var(--utility-600);margin-left:2px}.input-form-field{padding:8px 12px;border:1px solid var(--border-color, var(--neutral-color-200));border-radius:var(--radius-md);font-size:var(--font-sm);color:var(--neutral-color-875);height:36px;width:100%;box-sizing:border-box;background-color:var(--neutral-color-10);transition:border-color .2s ease,box-shadow .2s ease}.input-form-field::placeholder{color:var(--placeholder-color, var(--neutral-color-300));opacity:1}.input-form-field:hover{border-color:var(--border-color-hover, var(--neutral-color-400))}.input-form-field:focus{outline:none;border-color:var(--brand-500);box-shadow:0 0 0 2px rgba(var(--brand-500-rgb, 39, 64, 180),.15)}.input-form-field:read-only{background-color:var(--neutral-color-25);cursor:not-allowed}.input-form-field[type=password]{font-family:Verdana,sans-serif;font-size:16px;letter-spacing:3px}.input-form-field[type=password]::placeholder{font-family:inherit;font-size:var(--font-sm);letter-spacing:normal}.input-field-wrapper:has(.input-icon-button) .input-form-field{padding-right:36px}.input-field-wrapper{position:relative;display:flex;align-items:center}.input-icon-button{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;padding:0;margin:0;display:flex;align-items:center;justify-content:center;color:var(--neutral-color-500);transition:color .2s ease;outline:none}.input-icon-button.clickable{cursor:pointer}.input-icon-button.clickable:hover .input-icon{color:var(--brand-500)}.input-icon-button:disabled{cursor:default;pointer-events:none}.input-icon{font-size:14px!important;width:14px;height:14px;display:flex;align-items:center;justify-content:center;transition:color .2s ease}.input-icon:before{font-size:14px!important}.limit{display:flex;justify-content:flex-end}.limit span{font-size:var(--font-xs, 12px);color:var(--neutral-color-500)}\n"] }]
|
|
494
499
|
}], propDecorators: { headerInput: [{
|
|
495
500
|
type: Input
|
|
496
501
|
}], placeholder: [{
|
|
@@ -525,9 +530,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
525
530
|
type: Input
|
|
526
531
|
}], height: [{
|
|
527
532
|
type: Input
|
|
528
|
-
}],
|
|
533
|
+
}], fontSizeContent: [{
|
|
534
|
+
type: Input
|
|
535
|
+
}], fontWeightContent: [{
|
|
529
536
|
type: Input
|
|
530
|
-
}],
|
|
537
|
+
}], colorContent: [{
|
|
538
|
+
type: Input
|
|
539
|
+
}], fontSizeLabel: [{
|
|
540
|
+
type: Input
|
|
541
|
+
}], fontWeightLabel: [{
|
|
542
|
+
type: Input
|
|
543
|
+
}], colorLabel: [{
|
|
531
544
|
type: Input
|
|
532
545
|
}], backgroundColor: [{
|
|
533
546
|
type: Input
|
|
@@ -883,6 +896,237 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
883
896
|
type: Output
|
|
884
897
|
}] } });
|
|
885
898
|
|
|
899
|
+
class ModalComponent {
|
|
900
|
+
title = '';
|
|
901
|
+
width = '800px';
|
|
902
|
+
minHeight = '300px';
|
|
903
|
+
isOpen = false;
|
|
904
|
+
theme = 'default';
|
|
905
|
+
close = new EventEmitter();
|
|
906
|
+
onOverlayClick(event) {
|
|
907
|
+
if (event.target === event.currentTarget) {
|
|
908
|
+
this.close.emit();
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
onCloseClick() {
|
|
912
|
+
this.close.emit();
|
|
913
|
+
}
|
|
914
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
915
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: ModalComponent, isStandalone: true, selector: "app-modal", inputs: { title: "title", width: "width", minHeight: "minHeight", isOpen: "isOpen", theme: "theme" }, outputs: { close: "close" }, ngImport: i0, template: "<div class=\"modal-overlay\" *ngIf=\"isOpen\" (click)=\"onOverlayClick($event)\">\n <div\n class=\"modal-container\"\n [class.theme-white]=\"theme === 'white'\"\n [style.width]=\"width\"\n [style.min-height]=\"minHeight\"\n >\n <div class=\"modal-header\">\n <span class=\"modal-title\">{{ title }}</span>\n <button class=\"modal-close-btn\" (click)=\"onCloseClick()\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M18 6L6 18M6 6L18 18\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n <div class=\"modal-body\">\n <ng-content select=\"[modal-body]\"></ng-content>\n </div>\n <div class=\"modal-footer\">\n <ng-content select=\"[modal-footer]\"></ng-content>\n </div>\n </div>\n</div>\n", styles: [".modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.modal-container{background-color:var(--brand-100);border-radius:20px;display:flex;flex-direction:column;max-height:90vh;overflow:hidden}.modal-container.theme-white{background-color:var(--neutral-color-10)}.modal-header{display:flex;align-items:center;justify-content:space-between;min-height:56px;padding:0 20px;border-bottom:1px solid var(--neutral-color-300);box-sizing:border-box}.modal-title{font-weight:500;font-size:17px;line-height:24px;letter-spacing:-.3px;color:var(--brand-600)}.theme-white .modal-title{color:#fff}.modal-close-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;cursor:pointer;border-radius:8px;color:var(--neutral-color-500);transition:background-color .2s ease,color .2s ease}.modal-close-btn:hover{background-color:var(--neutral-color-100);color:var(--neutral-color-700)}.modal-body{flex:1;padding:20px;display:flex;flex-direction:column;overflow-y:auto}.modal-body ::ng-deep [modal-body]{display:flex;flex-direction:column;gap:16px}.modal-footer{min-height:56px;padding:0 20px 16px;display:flex;flex-direction:row;align-items:center;justify-content:flex-end;gap:16px;border-top:1px solid var(--neutral-color-300);box-sizing:border-box}.modal-footer ::ng-deep [modal-footer]{display:flex;flex-direction:row;align-items:center;gap:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
916
|
+
}
|
|
917
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ModalComponent, decorators: [{
|
|
918
|
+
type: Component,
|
|
919
|
+
args: [{ selector: 'app-modal', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"modal-overlay\" *ngIf=\"isOpen\" (click)=\"onOverlayClick($event)\">\n <div\n class=\"modal-container\"\n [class.theme-white]=\"theme === 'white'\"\n [style.width]=\"width\"\n [style.min-height]=\"minHeight\"\n >\n <div class=\"modal-header\">\n <span class=\"modal-title\">{{ title }}</span>\n <button class=\"modal-close-btn\" (click)=\"onCloseClick()\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M18 6L6 18M6 6L18 18\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n <div class=\"modal-body\">\n <ng-content select=\"[modal-body]\"></ng-content>\n </div>\n <div class=\"modal-footer\">\n <ng-content select=\"[modal-footer]\"></ng-content>\n </div>\n </div>\n</div>\n", styles: [".modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.modal-container{background-color:var(--brand-100);border-radius:20px;display:flex;flex-direction:column;max-height:90vh;overflow:hidden}.modal-container.theme-white{background-color:var(--neutral-color-10)}.modal-header{display:flex;align-items:center;justify-content:space-between;min-height:56px;padding:0 20px;border-bottom:1px solid var(--neutral-color-300);box-sizing:border-box}.modal-title{font-weight:500;font-size:17px;line-height:24px;letter-spacing:-.3px;color:var(--brand-600)}.theme-white .modal-title{color:#fff}.modal-close-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;cursor:pointer;border-radius:8px;color:var(--neutral-color-500);transition:background-color .2s ease,color .2s ease}.modal-close-btn:hover{background-color:var(--neutral-color-100);color:var(--neutral-color-700)}.modal-body{flex:1;padding:20px;display:flex;flex-direction:column;overflow-y:auto}.modal-body ::ng-deep [modal-body]{display:flex;flex-direction:column;gap:16px}.modal-footer{min-height:56px;padding:0 20px 16px;display:flex;flex-direction:row;align-items:center;justify-content:flex-end;gap:16px;border-top:1px solid var(--neutral-color-300);box-sizing:border-box}.modal-footer ::ng-deep [modal-footer]{display:flex;flex-direction:row;align-items:center;gap:16px}\n"] }]
|
|
920
|
+
}], propDecorators: { title: [{
|
|
921
|
+
type: Input
|
|
922
|
+
}], width: [{
|
|
923
|
+
type: Input
|
|
924
|
+
}], minHeight: [{
|
|
925
|
+
type: Input
|
|
926
|
+
}], isOpen: [{
|
|
927
|
+
type: Input
|
|
928
|
+
}], theme: [{
|
|
929
|
+
type: Input
|
|
930
|
+
}], close: [{
|
|
931
|
+
type: Output
|
|
932
|
+
}] } });
|
|
933
|
+
|
|
934
|
+
class AvatarUploadButtonComponent {
|
|
935
|
+
label = '';
|
|
936
|
+
required = false;
|
|
937
|
+
showTooltip = false;
|
|
938
|
+
tooltipText = '';
|
|
939
|
+
buttonText = 'Tải file lên';
|
|
940
|
+
acceptFormats = '.png,.jpeg,.jpg';
|
|
941
|
+
helperText = 'Định dạng .png, .jpeg, .jpg';
|
|
942
|
+
fileChange = new EventEmitter();
|
|
943
|
+
fileInput;
|
|
944
|
+
uploadedFile = null;
|
|
945
|
+
onButtonClick() {
|
|
946
|
+
this.fileInput.nativeElement.click();
|
|
947
|
+
}
|
|
948
|
+
onFileChange(event) {
|
|
949
|
+
const input = event.target;
|
|
950
|
+
if (input.files && input.files.length > 0) {
|
|
951
|
+
const file = input.files[0];
|
|
952
|
+
this.uploadedFile = this.createAvatarUploadedFile(file);
|
|
953
|
+
this.fileChange.emit(this.uploadedFile);
|
|
954
|
+
}
|
|
955
|
+
input.value = '';
|
|
956
|
+
}
|
|
957
|
+
onRemove() {
|
|
958
|
+
if (this.uploadedFile?.previewUrl) {
|
|
959
|
+
URL.revokeObjectURL(this.uploadedFile.previewUrl);
|
|
960
|
+
}
|
|
961
|
+
this.uploadedFile = null;
|
|
962
|
+
this.fileChange.emit(null);
|
|
963
|
+
}
|
|
964
|
+
createAvatarUploadedFile(file) {
|
|
965
|
+
const isImage = file.type.startsWith('image/');
|
|
966
|
+
return {
|
|
967
|
+
id: this.generateId(),
|
|
968
|
+
file: file,
|
|
969
|
+
fileName: file.name,
|
|
970
|
+
previewUrl: isImage ? URL.createObjectURL(file) : null,
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
generateId() {
|
|
974
|
+
return Math.random().toString(36).substring(2, 9);
|
|
975
|
+
}
|
|
976
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AvatarUploadButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
977
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: AvatarUploadButtonComponent, isStandalone: true, selector: "app-avatar-upload-button", inputs: { label: "label", required: "required", showTooltip: "showTooltip", tooltipText: "tooltipText", buttonText: "buttonText", acceptFormats: "acceptFormats", helperText: "helperText" }, outputs: { fileChange: "fileChange" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div class=\"avatar-upload-wrapper\">\n <div class=\"label-row\" *ngIf=\"label\">\n <span class=\"label-text\">{{ label }}</span>\n <span class=\"required-mark\" *ngIf=\"required\">*</span>\n <button type=\"button\" class=\"tooltip-icon\" *ngIf=\"showTooltip\" [title]=\"tooltipText\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n <path d=\"M8 7V11\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n <circle cx=\"8\" cy=\"5\" r=\"0.75\" fill=\"currentColor\" />\n </svg>\n </button>\n </div>\n\n <button type=\"button\" class=\"upload-button\" (click)=\"onButtonClick()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M10 4V13M10 4L6 8M10 4L14 8\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M3 13V15C3 15.5523 3.44772 16 4 16H16C16.5523 16 17 15.5523 17 15V13\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <span>{{ buttonText }}</span>\n </button>\n\n <input\n #fileInput\n type=\"file\"\n class=\"file-input\"\n [accept]=\"acceptFormats\"\n (change)=\"onFileChange($event)\"\n />\n\n <span class=\"helper-text\" *ngIf=\"helperText && !uploadedFile\">{{ helperText }}</span>\n\n <!-- Uploaded File Preview -->\n <div class=\"file-preview\" *ngIf=\"uploadedFile\">\n <img\n *ngIf=\"uploadedFile.previewUrl\"\n [src]=\"uploadedFile.previewUrl\"\n [alt]=\"uploadedFile.fileName\"\n class=\"preview-image\"\n />\n <span class=\"file-name\">{{ uploadedFile.fileName }}</span>\n <button type=\"button\" class=\"remove-btn\" (click)=\"onRemove()\" title=\"X\u00F3a\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 4L12 12M12 4L4 12\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n</div>\n", styles: [".avatar-upload-wrapper{display:flex;flex-direction:column;gap:6px}.label-row{display:flex;align-items:center;gap:4px}.label-text{font-size:14px;font-weight:500;line-height:20px;color:var(--neutral-color-700)}.required-mark{font-size:14px;font-weight:500;color:red}.tooltip-icon{display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;color:var(--neutral-color-400);cursor:pointer;transition:color .2s ease}.tooltip-icon:hover{color:var(--neutral-color-600)}.upload-button{display:flex;align-items:center;justify-content:center;gap:8px;padding:10px 16px;width:fit-content;min-width:120px;height:40px;background-color:var(--neutral-color-10);border:1px dashed var(--brand-600);border-radius:8px;cursor:pointer;transition:background-color .2s ease,border-color .2s ease;font-size:14px;font-weight:500;line-height:20px;color:var(--brand-600)}.upload-button:hover{background-color:var(--brand-100);border-color:var(--brand-700)}.upload-button:active{background-color:var(--brand-200)}.file-input{display:none}.helper-text{font-size:12px;font-weight:400;line-height:16px;color:var(--neutral-color-500)}.file-preview{display:flex;align-items:center;gap:8px}.preview-image{display:block;width:48px;height:48px;border-radius:4px;object-fit:contain}.file-name{font-size:14px;font-weight:400;line-height:20px;color:var(--neutral-color-700)}.remove-btn{display:flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;background:transparent;color:var(--neutral-color-500);cursor:pointer;transition:color .2s ease}.remove-btn:hover{color:var(--error-500)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
978
|
+
}
|
|
979
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AvatarUploadButtonComponent, decorators: [{
|
|
980
|
+
type: Component,
|
|
981
|
+
args: [{ selector: 'app-avatar-upload-button', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"avatar-upload-wrapper\">\n <div class=\"label-row\" *ngIf=\"label\">\n <span class=\"label-text\">{{ label }}</span>\n <span class=\"required-mark\" *ngIf=\"required\">*</span>\n <button type=\"button\" class=\"tooltip-icon\" *ngIf=\"showTooltip\" [title]=\"tooltipText\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n <path d=\"M8 7V11\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n <circle cx=\"8\" cy=\"5\" r=\"0.75\" fill=\"currentColor\" />\n </svg>\n </button>\n </div>\n\n <button type=\"button\" class=\"upload-button\" (click)=\"onButtonClick()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M10 4V13M10 4L6 8M10 4L14 8\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M3 13V15C3 15.5523 3.44772 16 4 16H16C16.5523 16 17 15.5523 17 15V13\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <span>{{ buttonText }}</span>\n </button>\n\n <input\n #fileInput\n type=\"file\"\n class=\"file-input\"\n [accept]=\"acceptFormats\"\n (change)=\"onFileChange($event)\"\n />\n\n <span class=\"helper-text\" *ngIf=\"helperText && !uploadedFile\">{{ helperText }}</span>\n\n <!-- Uploaded File Preview -->\n <div class=\"file-preview\" *ngIf=\"uploadedFile\">\n <img\n *ngIf=\"uploadedFile.previewUrl\"\n [src]=\"uploadedFile.previewUrl\"\n [alt]=\"uploadedFile.fileName\"\n class=\"preview-image\"\n />\n <span class=\"file-name\">{{ uploadedFile.fileName }}</span>\n <button type=\"button\" class=\"remove-btn\" (click)=\"onRemove()\" title=\"X\u00F3a\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 4L12 12M12 4L4 12\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n</div>\n", styles: [".avatar-upload-wrapper{display:flex;flex-direction:column;gap:6px}.label-row{display:flex;align-items:center;gap:4px}.label-text{font-size:14px;font-weight:500;line-height:20px;color:var(--neutral-color-700)}.required-mark{font-size:14px;font-weight:500;color:red}.tooltip-icon{display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;color:var(--neutral-color-400);cursor:pointer;transition:color .2s ease}.tooltip-icon:hover{color:var(--neutral-color-600)}.upload-button{display:flex;align-items:center;justify-content:center;gap:8px;padding:10px 16px;width:fit-content;min-width:120px;height:40px;background-color:var(--neutral-color-10);border:1px dashed var(--brand-600);border-radius:8px;cursor:pointer;transition:background-color .2s ease,border-color .2s ease;font-size:14px;font-weight:500;line-height:20px;color:var(--brand-600)}.upload-button:hover{background-color:var(--brand-100);border-color:var(--brand-700)}.upload-button:active{background-color:var(--brand-200)}.file-input{display:none}.helper-text{font-size:12px;font-weight:400;line-height:16px;color:var(--neutral-color-500)}.file-preview{display:flex;align-items:center;gap:8px}.preview-image{display:block;width:48px;height:48px;border-radius:4px;object-fit:contain}.file-name{font-size:14px;font-weight:400;line-height:20px;color:var(--neutral-color-700)}.remove-btn{display:flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;background:transparent;color:var(--neutral-color-500);cursor:pointer;transition:color .2s ease}.remove-btn:hover{color:var(--error-500)}\n"] }]
|
|
982
|
+
}], propDecorators: { label: [{
|
|
983
|
+
type: Input
|
|
984
|
+
}], required: [{
|
|
985
|
+
type: Input
|
|
986
|
+
}], showTooltip: [{
|
|
987
|
+
type: Input
|
|
988
|
+
}], tooltipText: [{
|
|
989
|
+
type: Input
|
|
990
|
+
}], buttonText: [{
|
|
991
|
+
type: Input
|
|
992
|
+
}], acceptFormats: [{
|
|
993
|
+
type: Input
|
|
994
|
+
}], helperText: [{
|
|
995
|
+
type: Input
|
|
996
|
+
}], fileChange: [{
|
|
997
|
+
type: Output
|
|
998
|
+
}], fileInput: [{
|
|
999
|
+
type: ViewChild,
|
|
1000
|
+
args: ['fileInput']
|
|
1001
|
+
}] } });
|
|
1002
|
+
|
|
1003
|
+
class FileUploadDropzoneComponent {
|
|
1004
|
+
label = 'Thêm file bài học';
|
|
1005
|
+
buttonText = 'Tải lên';
|
|
1006
|
+
maxSize = '10MB';
|
|
1007
|
+
acceptFormats = '.docx,.xlsx,.png,.jpg,.jpeg,.pdf';
|
|
1008
|
+
helperText = '';
|
|
1009
|
+
filesChange = new EventEmitter();
|
|
1010
|
+
fileDownload = new EventEmitter();
|
|
1011
|
+
fileDelete = new EventEmitter();
|
|
1012
|
+
fileInput;
|
|
1013
|
+
uploadedFiles = [];
|
|
1014
|
+
isDragging = false;
|
|
1015
|
+
get displayHelperText() {
|
|
1016
|
+
if (this.helperText)
|
|
1017
|
+
return this.helperText;
|
|
1018
|
+
return `Dung lượng tối đa ${this.maxSize}(${this.acceptFormats.replace(/\./g, '').split(',').join(', ')}...)`;
|
|
1019
|
+
}
|
|
1020
|
+
onButtonClick() {
|
|
1021
|
+
this.fileInput.nativeElement.click();
|
|
1022
|
+
}
|
|
1023
|
+
onFileChange(event) {
|
|
1024
|
+
const input = event.target;
|
|
1025
|
+
if (input.files && input.files.length > 0) {
|
|
1026
|
+
this.addFiles(Array.from(input.files));
|
|
1027
|
+
}
|
|
1028
|
+
input.value = '';
|
|
1029
|
+
}
|
|
1030
|
+
onDragOver(event) {
|
|
1031
|
+
event.preventDefault();
|
|
1032
|
+
event.stopPropagation();
|
|
1033
|
+
this.isDragging = true;
|
|
1034
|
+
}
|
|
1035
|
+
onDragLeave(event) {
|
|
1036
|
+
event.preventDefault();
|
|
1037
|
+
event.stopPropagation();
|
|
1038
|
+
this.isDragging = false;
|
|
1039
|
+
}
|
|
1040
|
+
onDrop(event) {
|
|
1041
|
+
event.preventDefault();
|
|
1042
|
+
event.stopPropagation();
|
|
1043
|
+
this.isDragging = false;
|
|
1044
|
+
const files = event.dataTransfer?.files;
|
|
1045
|
+
if (files && files.length > 0) {
|
|
1046
|
+
this.addFiles(Array.from(files));
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
onDownload(file) {
|
|
1050
|
+
this.fileDownload.emit(file);
|
|
1051
|
+
}
|
|
1052
|
+
onDelete(file) {
|
|
1053
|
+
this.uploadedFiles = this.uploadedFiles.filter((f) => f.id !== file.id);
|
|
1054
|
+
this.fileDelete.emit(file);
|
|
1055
|
+
this.filesChange.emit(this.uploadedFiles);
|
|
1056
|
+
}
|
|
1057
|
+
getIconType(file) {
|
|
1058
|
+
const ext = file.fileName.split('.').pop()?.toLowerCase() || '';
|
|
1059
|
+
if (ext === 'pdf')
|
|
1060
|
+
return 'pdf';
|
|
1061
|
+
if (['doc', 'docx'].includes(ext))
|
|
1062
|
+
return 'doc';
|
|
1063
|
+
if (['xls', 'xlsx'].includes(ext))
|
|
1064
|
+
return 'xls';
|
|
1065
|
+
if (['png', 'jpg', 'jpeg', 'gif', 'webp'].includes(ext))
|
|
1066
|
+
return 'image';
|
|
1067
|
+
return 'file';
|
|
1068
|
+
}
|
|
1069
|
+
addFiles(files) {
|
|
1070
|
+
const newFiles = files.map((file) => this.createUploadedFile(file));
|
|
1071
|
+
this.uploadedFiles = [...this.uploadedFiles, ...newFiles];
|
|
1072
|
+
this.filesChange.emit(this.uploadedFiles);
|
|
1073
|
+
}
|
|
1074
|
+
createUploadedFile(file) {
|
|
1075
|
+
return {
|
|
1076
|
+
id: this.generateId(),
|
|
1077
|
+
file: file,
|
|
1078
|
+
fileName: file.name,
|
|
1079
|
+
fileSize: this.formatFileSize(file.size),
|
|
1080
|
+
dateTime: this.formatDateTime(new Date()),
|
|
1081
|
+
fileType: file.name.split('.').pop()?.toLowerCase() || '',
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
generateId() {
|
|
1085
|
+
return Math.random().toString(36).substring(2, 9);
|
|
1086
|
+
}
|
|
1087
|
+
formatFileSize(bytes) {
|
|
1088
|
+
if (bytes === 0)
|
|
1089
|
+
return '0 Bytes';
|
|
1090
|
+
const k = 1024;
|
|
1091
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
1092
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
1093
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + sizes[i];
|
|
1094
|
+
}
|
|
1095
|
+
formatDateTime(date) {
|
|
1096
|
+
const day = date.getDate().toString().padStart(2, '0');
|
|
1097
|
+
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
1098
|
+
const year = date.getFullYear();
|
|
1099
|
+
const hours = date.getHours().toString().padStart(2, '0');
|
|
1100
|
+
const minutes = date.getMinutes().toString().padStart(2, '0');
|
|
1101
|
+
return `${day}/${month}/${year} ${hours}:${minutes}`;
|
|
1102
|
+
}
|
|
1103
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FileUploadDropzoneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1104
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: FileUploadDropzoneComponent, isStandalone: true, selector: "app-file-upload-dropzone", inputs: { label: "label", buttonText: "buttonText", maxSize: "maxSize", acceptFormats: "acceptFormats", helperText: "helperText" }, outputs: { filesChange: "filesChange", fileDownload: "fileDownload", fileDelete: "fileDelete" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div class=\"file-upload-dropzone\">\n <label class=\"dropzone-label\">{{ label }}</label>\n\n <div\n class=\"dropzone-area\"\n [class.dragging]=\"isDragging\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n (click)=\"onButtonClick()\"\n >\n <div class=\"dropzone-content\">\n <svg\n class=\"upload-icon\"\n width=\"40\"\n height=\"40\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 16V8M12 8L9 11M12 8L15 11\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M9 22H15C18.866 22 22 18.866 22 15C22 12.0667 20.2333 9.56667 17.6667 8.46667C17.8778 7.98889 18 7.46667 18 6.93333C18 4.41111 15.5778 2.44444 12.8333 3.04444C11.0111 1.15556 8.11111 0.911111 6 2.48889C3.51111 4.35556 3.22222 8.02222 5.11111 10.2444C3.24444 11.2222 2 13.1778 2 15.4444C2 18.9778 5.02222 22 9 22Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n\n <button type=\"button\" class=\"upload-btn\" (click)=\"$event.stopPropagation(); onButtonClick()\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 16V8M12 8L9 11M12 8L15 11\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n {{ buttonText }}\n </button>\n\n <span class=\"helper-text\">{{ displayHelperText }}</span>\n </div>\n </div>\n\n <input\n #fileInput\n type=\"file\"\n [accept]=\"acceptFormats\"\n (change)=\"onFileChange($event)\"\n multiple\n hidden\n />\n\n <!-- Attachment List -->\n <div class=\"attachment-list\" *ngIf=\"uploadedFiles.length > 0\">\n <div class=\"attachment-item\" *ngFor=\"let file of uploadedFiles\">\n <div class=\"file-icon\" [ngClass]=\"getIconType(file)\">\n <ng-container [ngSwitch]=\"getIconType(file)\">\n <svg\n *ngSwitchCase=\"'pdf'\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" fill=\"#FEE2E2\" />\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" stroke=\"#EF4444\" stroke-width=\"1\" />\n <text x=\"12\" y=\"14\" text-anchor=\"middle\" fill=\"#EF4444\" font-size=\"6\" font-weight=\"600\">\n PDF\n </text>\n </svg>\n <svg\n *ngSwitchCase=\"'doc'\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" fill=\"#DBEAFE\" />\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" stroke=\"#3B82F6\" stroke-width=\"1\" />\n <text x=\"12\" y=\"14\" text-anchor=\"middle\" fill=\"#3B82F6\" font-size=\"6\" font-weight=\"600\">\n DOC\n </text>\n </svg>\n <svg\n *ngSwitchCase=\"'xls'\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" fill=\"#D1FAE5\" />\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" stroke=\"#10B981\" stroke-width=\"1\" />\n <text x=\"12\" y=\"14\" text-anchor=\"middle\" fill=\"#10B981\" font-size=\"6\" font-weight=\"600\">\n XLS\n </text>\n </svg>\n <svg\n *ngSwitchCase=\"'image'\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" fill=\"#FEF3C7\" />\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" stroke=\"#F59E0B\" stroke-width=\"1\" />\n <text x=\"12\" y=\"14\" text-anchor=\"middle\" fill=\"#F59E0B\" font-size=\"6\" font-weight=\"600\">\n IMG\n </text>\n </svg>\n <svg\n *ngSwitchDefault\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" fill=\"#F3F4F6\" />\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" stroke=\"#9CA3AF\" stroke-width=\"1\" />\n <text x=\"12\" y=\"14\" text-anchor=\"middle\" fill=\"#9CA3AF\" font-size=\"6\" font-weight=\"600\">\n FILE\n </text>\n </svg>\n </ng-container>\n </div>\n\n <div class=\"file-info\">\n <span class=\"file-name\">{{ file.fileName }}</span>\n <div class=\"file-meta\">\n <span class=\"file-size\">{{ file.fileSize }}</span>\n <span class=\"separator\">\u2022</span>\n <span class=\"file-date\">{{ file.dateTime }}</span>\n </div>\n </div>\n\n <div class=\"file-actions\">\n <button class=\"action-btn download-btn\" (click)=\"onDownload(file)\" title=\"T\u1EA3i xu\u1ED1ng\">\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M10 3V13M10 13L6 9M10 13L14 9\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M3 15V16C3 16.5523 3.44772 17 4 17H16C16.5523 17 17 16.5523 17 16V15\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <button class=\"action-btn delete-btn\" (click)=\"onDelete(file)\" title=\"X\u00F3a\">\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 5H16M7 5V4C7 3.44772 7.44772 3 8 3H12C12.5523 3 13 3.44772 13 4V5M8 9V14M12 9V14M5 5L6 16C6 16.5523 6.44772 17 7 17H13C13.5523 17 14 16.5523 14 16L15 5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n </div>\n</div>\n", styles: [".file-upload-dropzone{display:flex;flex-direction:column;gap:8px;width:100%}.dropzone-label{font-weight:500;font-size:14px;line-height:20px;color:var(--neutral-color-900)}.dropzone-area{display:flex;align-items:center;justify-content:center;min-height:180px;padding:32px 20px;border:1px dashed var(--brand-600);border-radius:8px;background-color:var(--neutral-color-10);cursor:pointer}.dropzone-area.dragging{border-width:2px}.dropzone-content{display:flex;flex-direction:column;align-items:center;gap:12px}.upload-icon{color:var(--brand-600)}.upload-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:8px 16px;border:1px solid var(--brand-600);border-radius:6px;background-color:var(--neutral-color-10);color:var(--brand-600);font-weight:500;font-size:14px;line-height:20px;cursor:pointer;transition:all .2s ease}.upload-btn:hover{background-color:var(--brand-100);border-color:var(--brand-700)}.upload-btn svg{flex-shrink:0}.helper-text{font-size:13px;line-height:18px;color:var(--neutral-color-500)}.attachment-list{display:flex;flex-direction:column;gap:8px;margin-top:16px}.attachment-item{display:flex;align-items:center;gap:12px;padding:12px 16px;background-color:var(--neutral-color-10);border:1px solid var(--neutral-color-200);border-radius:8px}.file-icon{display:flex;align-items:center;justify-content:center;width:40px;height:40px;flex-shrink:0}.file-icon svg{width:32px;height:40px}.file-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.file-name{font-size:14px;font-weight:500;line-height:20px;color:var(--neutral-color-900);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-meta{display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;color:var(--neutral-color-500)}.separator{color:var(--neutral-color-400)}.file-actions{display:flex;align-items:center;gap:4px;flex-shrink:0}.action-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px solid var(--neutral-color-200);border-radius:6px;background-color:var(--neutral-color-10);cursor:pointer;transition:all .2s ease}.action-btn.download-btn{color:var(--neutral-color-600)}.action-btn.download-btn:hover{background-color:var(--brand-100);border-color:var(--brand-600);color:var(--brand-600)}.action-btn.delete-btn{color:var(--neutral-color-600)}.action-btn.delete-btn:hover{background-color:var(--error-100);border-color:var(--error-500);color:var(--error-500)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1105
|
+
}
|
|
1106
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FileUploadDropzoneComponent, decorators: [{
|
|
1107
|
+
type: Component,
|
|
1108
|
+
args: [{ selector: 'app-file-upload-dropzone', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"file-upload-dropzone\">\n <label class=\"dropzone-label\">{{ label }}</label>\n\n <div\n class=\"dropzone-area\"\n [class.dragging]=\"isDragging\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n (click)=\"onButtonClick()\"\n >\n <div class=\"dropzone-content\">\n <svg\n class=\"upload-icon\"\n width=\"40\"\n height=\"40\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 16V8M12 8L9 11M12 8L15 11\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M9 22H15C18.866 22 22 18.866 22 15C22 12.0667 20.2333 9.56667 17.6667 8.46667C17.8778 7.98889 18 7.46667 18 6.93333C18 4.41111 15.5778 2.44444 12.8333 3.04444C11.0111 1.15556 8.11111 0.911111 6 2.48889C3.51111 4.35556 3.22222 8.02222 5.11111 10.2444C3.24444 11.2222 2 13.1778 2 15.4444C2 18.9778 5.02222 22 9 22Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n\n <button type=\"button\" class=\"upload-btn\" (click)=\"$event.stopPropagation(); onButtonClick()\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 16V8M12 8L9 11M12 8L15 11\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n {{ buttonText }}\n </button>\n\n <span class=\"helper-text\">{{ displayHelperText }}</span>\n </div>\n </div>\n\n <input\n #fileInput\n type=\"file\"\n [accept]=\"acceptFormats\"\n (change)=\"onFileChange($event)\"\n multiple\n hidden\n />\n\n <!-- Attachment List -->\n <div class=\"attachment-list\" *ngIf=\"uploadedFiles.length > 0\">\n <div class=\"attachment-item\" *ngFor=\"let file of uploadedFiles\">\n <div class=\"file-icon\" [ngClass]=\"getIconType(file)\">\n <ng-container [ngSwitch]=\"getIconType(file)\">\n <svg\n *ngSwitchCase=\"'pdf'\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" fill=\"#FEE2E2\" />\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" stroke=\"#EF4444\" stroke-width=\"1\" />\n <text x=\"12\" y=\"14\" text-anchor=\"middle\" fill=\"#EF4444\" font-size=\"6\" font-weight=\"600\">\n PDF\n </text>\n </svg>\n <svg\n *ngSwitchCase=\"'doc'\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" fill=\"#DBEAFE\" />\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" stroke=\"#3B82F6\" stroke-width=\"1\" />\n <text x=\"12\" y=\"14\" text-anchor=\"middle\" fill=\"#3B82F6\" font-size=\"6\" font-weight=\"600\">\n DOC\n </text>\n </svg>\n <svg\n *ngSwitchCase=\"'xls'\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" fill=\"#D1FAE5\" />\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" stroke=\"#10B981\" stroke-width=\"1\" />\n <text x=\"12\" y=\"14\" text-anchor=\"middle\" fill=\"#10B981\" font-size=\"6\" font-weight=\"600\">\n XLS\n </text>\n </svg>\n <svg\n *ngSwitchCase=\"'image'\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" fill=\"#FEF3C7\" />\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" stroke=\"#F59E0B\" stroke-width=\"1\" />\n <text x=\"12\" y=\"14\" text-anchor=\"middle\" fill=\"#F59E0B\" font-size=\"6\" font-weight=\"600\">\n IMG\n </text>\n </svg>\n <svg\n *ngSwitchDefault\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" fill=\"#F3F4F6\" />\n <rect x=\"3\" y=\"2\" width=\"18\" height=\"20\" rx=\"2\" stroke=\"#9CA3AF\" stroke-width=\"1\" />\n <text x=\"12\" y=\"14\" text-anchor=\"middle\" fill=\"#9CA3AF\" font-size=\"6\" font-weight=\"600\">\n FILE\n </text>\n </svg>\n </ng-container>\n </div>\n\n <div class=\"file-info\">\n <span class=\"file-name\">{{ file.fileName }}</span>\n <div class=\"file-meta\">\n <span class=\"file-size\">{{ file.fileSize }}</span>\n <span class=\"separator\">\u2022</span>\n <span class=\"file-date\">{{ file.dateTime }}</span>\n </div>\n </div>\n\n <div class=\"file-actions\">\n <button class=\"action-btn download-btn\" (click)=\"onDownload(file)\" title=\"T\u1EA3i xu\u1ED1ng\">\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M10 3V13M10 13L6 9M10 13L14 9\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M3 15V16C3 16.5523 3.44772 17 4 17H16C16.5523 17 17 16.5523 17 16V15\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <button class=\"action-btn delete-btn\" (click)=\"onDelete(file)\" title=\"X\u00F3a\">\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 5H16M7 5V4C7 3.44772 7.44772 3 8 3H12C12.5523 3 13 3.44772 13 4V5M8 9V14M12 9V14M5 5L6 16C6 16.5523 6.44772 17 7 17H13C13.5523 17 14 16.5523 14 16L15 5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n </div>\n</div>\n", styles: [".file-upload-dropzone{display:flex;flex-direction:column;gap:8px;width:100%}.dropzone-label{font-weight:500;font-size:14px;line-height:20px;color:var(--neutral-color-900)}.dropzone-area{display:flex;align-items:center;justify-content:center;min-height:180px;padding:32px 20px;border:1px dashed var(--brand-600);border-radius:8px;background-color:var(--neutral-color-10);cursor:pointer}.dropzone-area.dragging{border-width:2px}.dropzone-content{display:flex;flex-direction:column;align-items:center;gap:12px}.upload-icon{color:var(--brand-600)}.upload-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:8px 16px;border:1px solid var(--brand-600);border-radius:6px;background-color:var(--neutral-color-10);color:var(--brand-600);font-weight:500;font-size:14px;line-height:20px;cursor:pointer;transition:all .2s ease}.upload-btn:hover{background-color:var(--brand-100);border-color:var(--brand-700)}.upload-btn svg{flex-shrink:0}.helper-text{font-size:13px;line-height:18px;color:var(--neutral-color-500)}.attachment-list{display:flex;flex-direction:column;gap:8px;margin-top:16px}.attachment-item{display:flex;align-items:center;gap:12px;padding:12px 16px;background-color:var(--neutral-color-10);border:1px solid var(--neutral-color-200);border-radius:8px}.file-icon{display:flex;align-items:center;justify-content:center;width:40px;height:40px;flex-shrink:0}.file-icon svg{width:32px;height:40px}.file-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.file-name{font-size:14px;font-weight:500;line-height:20px;color:var(--neutral-color-900);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-meta{display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;color:var(--neutral-color-500)}.separator{color:var(--neutral-color-400)}.file-actions{display:flex;align-items:center;gap:4px;flex-shrink:0}.action-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px solid var(--neutral-color-200);border-radius:6px;background-color:var(--neutral-color-10);cursor:pointer;transition:all .2s ease}.action-btn.download-btn{color:var(--neutral-color-600)}.action-btn.download-btn:hover{background-color:var(--brand-100);border-color:var(--brand-600);color:var(--brand-600)}.action-btn.delete-btn{color:var(--neutral-color-600)}.action-btn.delete-btn:hover{background-color:var(--error-100);border-color:var(--error-500);color:var(--error-500)}\n"] }]
|
|
1109
|
+
}], propDecorators: { label: [{
|
|
1110
|
+
type: Input
|
|
1111
|
+
}], buttonText: [{
|
|
1112
|
+
type: Input
|
|
1113
|
+
}], maxSize: [{
|
|
1114
|
+
type: Input
|
|
1115
|
+
}], acceptFormats: [{
|
|
1116
|
+
type: Input
|
|
1117
|
+
}], helperText: [{
|
|
1118
|
+
type: Input
|
|
1119
|
+
}], filesChange: [{
|
|
1120
|
+
type: Output
|
|
1121
|
+
}], fileDownload: [{
|
|
1122
|
+
type: Output
|
|
1123
|
+
}], fileDelete: [{
|
|
1124
|
+
type: Output
|
|
1125
|
+
}], fileInput: [{
|
|
1126
|
+
type: ViewChild,
|
|
1127
|
+
args: ['fileInput']
|
|
1128
|
+
}] } });
|
|
1129
|
+
|
|
886
1130
|
/*
|
|
887
1131
|
* Public API Surface of intern-hub-layout
|
|
888
1132
|
*/
|
|
@@ -892,5 +1136,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
892
1136
|
* Generated bundle index. Do not edit.
|
|
893
1137
|
*/
|
|
894
1138
|
|
|
895
|
-
export { ApprovalListComponent, ApprovalListItemComponent, BUTTON_SIZE_MAP, ButtonContainerComponent, FunctionalLabelComponent, HeaderComponent, IconComponent, InputCalendarComponent, InputStepperComponent, InputTextComponent, LabelButtonComponent, PopUpConfirmComponent, SidebarComponent, TableBodyComponent, TableHeaderComponent };
|
|
1139
|
+
export { ApprovalListComponent, ApprovalListItemComponent, AvatarUploadButtonComponent, BUTTON_SIZE_MAP, ButtonContainerComponent, FileUploadDropzoneComponent, FunctionalLabelComponent, HeaderComponent, IconComponent, InputCalendarComponent, InputStepperComponent, InputTextComponent, LabelButtonComponent, ModalComponent, PopUpConfirmComponent, SidebarComponent, TableBodyComponent, TableHeaderComponent };
|
|
896
1140
|
//# sourceMappingURL=goat-bravos-intern-hub-layout.mjs.map
|