@ramonbsales/noah-angular 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ramonbsales-noah-angular.mjs +47 -47
- package/fesm2022/ramonbsales-noah-angular.mjs.map +1 -1
- package/package.json +5 -5
- package/types/ramonbsales-noah-angular.d.ts +754 -0
- package/index.d.ts +0 -5
- package/lib/components/breadcrumb/breadcrumb.component.d.ts +0 -9
- package/lib/components/button/button.component.d.ts +0 -16
- package/lib/components/checkbox/checkbox.component.d.ts +0 -24
- package/lib/components/dropdown/dropdown.component.d.ts +0 -37
- package/lib/components/input/input.component.d.ts +0 -37
- package/lib/components/table/table.component.d.ts +0 -40
- package/lib/components/toggle/toggle.component.d.ts +0 -15
- package/lib/interceptors/auth.interceptor.d.ts +0 -15
- package/lib/interceptors/index.d.ts +0 -1
- package/lib/pages/login/login.component.d.ts +0 -82
- package/lib/services/index.d.ts +0 -3
- package/lib/services/local-storage/auth-storage.service.d.ts +0 -65
- package/lib/services/local-storage/local-storage.service.d.ts +0 -82
- package/lib/services/login/login.service.d.ts +0 -96
- package/lib/shared-components.component.d.ts +0 -5
- package/lib/shared-components.service.d.ts +0 -6
- package/lib/sidebar/sidebar.component.d.ts +0 -83
- package/lib/types/auth.types.d.ts +0 -104
- package/lib/types/sidebar.types.d.ts +0 -52
- package/public-api.d.ts +0 -16
|
@@ -11,10 +11,10 @@ import { map, takeUntil, switchMap, catchError } from 'rxjs/operators';
|
|
|
11
11
|
|
|
12
12
|
class SharedComponentsService {
|
|
13
13
|
constructor() { }
|
|
14
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
15
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
14
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SharedComponentsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
15
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SharedComponentsService, providedIn: 'root' });
|
|
16
16
|
}
|
|
17
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
17
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SharedComponentsService, decorators: [{
|
|
18
18
|
type: Injectable,
|
|
19
19
|
args: [{
|
|
20
20
|
providedIn: 'root'
|
|
@@ -22,14 +22,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
22
22
|
}], ctorParameters: () => [] });
|
|
23
23
|
|
|
24
24
|
class SharedComponentsComponent {
|
|
25
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
26
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
25
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SharedComponentsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
26
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: SharedComponentsComponent, isStandalone: true, selector: "lib-shared-components", ngImport: i0, template: `
|
|
27
27
|
<p>
|
|
28
28
|
shared-components works!
|
|
29
29
|
</p>
|
|
30
30
|
`, isInline: true, styles: [""] });
|
|
31
31
|
}
|
|
32
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
32
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SharedComponentsComponent, decorators: [{
|
|
33
33
|
type: Component,
|
|
34
34
|
args: [{ selector: 'lib-shared-components', imports: [], template: `
|
|
35
35
|
<p>
|
|
@@ -108,8 +108,8 @@ class DropdownComponent {
|
|
|
108
108
|
setDisabledState(isDisabled) {
|
|
109
109
|
this.disabled = isDisabled;
|
|
110
110
|
}
|
|
111
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
112
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
111
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
112
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: DropdownComponent, isStandalone: true, selector: "lib-dropdown", inputs: { label: "label", placeholder: "placeholder", options: "options", disabled: "disabled", required: "required", errorMessage: "errorMessage", selectedOption: "selectedOption", hideLabel: "hideLabel" }, outputs: { valueChange: "valueChange" }, providers: [
|
|
113
113
|
{
|
|
114
114
|
provide: NG_VALUE_ACCESSOR,
|
|
115
115
|
useExisting: forwardRef(() => DropdownComponent),
|
|
@@ -117,7 +117,7 @@ class DropdownComponent {
|
|
|
117
117
|
}
|
|
118
118
|
], usesOnChanges: true, ngImport: i0, template: "<label *ngIf=\"!hideLabel\" for=\"\">{{label}}</label>\n<div class=\"dropdown\" tabindex=\"0\" (blur)=\"isOpen = false\">\n <button class=\"btn btn-light w-100 text-start d-flex justify-content-between align-items-center\" type=\"button\"\n (click)=\"toggleDropdown()\" [attr.aria-expanded]=\"isOpen\" [disabled]=\"disabled\">\n <span class=\"select-option-text\" *ngIf=\"hasValue()\">{{ getSelectedLabel() }}</span>\n <span class=\"placeholder-text\" *ngIf=\"!hasValue()\">{{ getSelectedLabel() }}</span>\n <span class=\"material-icons\">\n unfold_more\n </span>\n </button>\n <ul class=\"dropdown-menu w-100 show\" *ngIf=\"isOpen\">\n <li *ngFor=\"let option of options\">\n <a class=\"dropdown-item\" (click)=\"selectOption(option)\">{{ option.label }}</a>\n </li>\n </ul>\n</div>", styles: ["label{font-family:DM Sans,sans-serif;font-weight:600;font-size:.875rem;line-height:2.5}.dropdown{font-family:DM Sans,sans-serif}.btn{font-family:DM Sans,sans-serif;font-weight:500;font-size:.875rem;border:1px solid #dee2e6;background-color:#fff}.btn .select-option-text{color:#343a40}.btn .placeholder-text{color:#6c757d}.btn .material-icons{font-size:.875rem}.dropdown-item{font-family:DM Sans,sans-serif;font-weight:400;font-size:.875rem;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }] });
|
|
119
119
|
}
|
|
120
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
120
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DropdownComponent, decorators: [{
|
|
121
121
|
type: Component,
|
|
122
122
|
args: [{ selector: 'lib-dropdown', imports: [CommonModule, ReactiveFormsModule], providers: [
|
|
123
123
|
{
|
|
@@ -269,8 +269,8 @@ class InputComponent {
|
|
|
269
269
|
registerOnTouched(fn) {
|
|
270
270
|
this.onTouched = fn;
|
|
271
271
|
}
|
|
272
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
273
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
272
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: InputComponent, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
|
|
273
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: InputComponent, isStandalone: true, selector: "lib-input", inputs: { label: "label", placeholder: "placeholder", type: "type", customErrorMessages: "customErrorMessages" }, providers: [
|
|
274
274
|
{
|
|
275
275
|
provide: NG_VALUE_ACCESSOR,
|
|
276
276
|
useExisting: forwardRef(() => InputComponent),
|
|
@@ -278,7 +278,7 @@ class InputComponent {
|
|
|
278
278
|
}
|
|
279
279
|
], ngImport: i0, template: "<div class=\"form-group\">\n\n <label>{{ label }}\n <span class=\"required-asterisk\" *ngIf=\"showRequiredAsterisk\">*</span>\n </label>\n\n <div class=\"input-container\" [class.focused]=\"isFocused\" [class.has-value]=\"hasValue()\" [class.disabled]=\"isDisabled\"\n [class.error]=\"showError\">\n\n <input [type]=\"type\" [placeholder]=\"placeholder\" [value]=\"value || ''\" [disabled]=\"isDisabled\"\n [required]=\"isRequired\" (input)=\"onInput($event)\" (focus)=\"onFocus()\" (blur)=\"onBlur()\"\n [ngClass]=\"{'error': showError}\" />\n </div>\n\n <small class=\"form-text error\" *ngIf=\"showError\">\n {{ errorMessage }}\n </small>\n\n</div>", styles: ["label{font-family:DM Sans,sans-serif;font-weight:600;font-size:.875rem;line-height:2.5}.required-asterisk{color:#dc3545;margin-left:.25rem}.input-container{font-family:DM Sans,sans-serif}input{font-family:DM Sans,sans-serif;font-weight:400;font-size:.875rem;border:1px solid #dee2e6;border-radius:.25rem;display:block;width:100%;padding:.375rem .75rem;line-height:1.5;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-clip:padding-box;outline:none}input::placeholder{color:#6c757d}input:focus{border-color:#b2b9be;box-shadow:none}input:focus.error{border-color:#dc3545}small.error{color:#dc3545}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }] });
|
|
280
280
|
}
|
|
281
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
281
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: InputComponent, decorators: [{
|
|
282
282
|
type: Component,
|
|
283
283
|
args: [{ selector: 'lib-input', imports: [CommonModule, ReactiveFormsModule], providers: [
|
|
284
284
|
{
|
|
@@ -312,10 +312,10 @@ class ButtonComponent {
|
|
|
312
312
|
this.onClickEvent.emit();
|
|
313
313
|
}
|
|
314
314
|
}
|
|
315
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
316
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
315
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
316
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: ButtonComponent, isStandalone: true, selector: "lib-button", inputs: { title: "title", backgroundColor: "backgroundColor", color: "color", borderColor: "borderColor", minWidth: "minWidth", disabled: "disabled", loading: "loading", loadingText: "loadingText" }, outputs: { onClickEvent: "onClickEvent" }, ngImport: i0, template: "<button type=\"button\" class=\"btn\" [style.background-color]=\"backgroundColor\" [style.color]=\"color\"\n [style.border-color]=\"borderColor\" [style.min-width]=\"minWidth\" [disabled]=\"disabled || loading\"\n (click)=\"onClick()\">\n <span *ngIf=\"loading\" class=\"spinner-border spinner-border-sm me-2\" role=\"status\" aria-hidden=\"true\"></span>\n <span *ngIf=\"!loading\">{{title}}</span>\n <span *ngIf=\"loading\">{{loadingText}}</span>\n</button>", styles: ["span{font-family:DM Sans,sans-serif;font-weight:400;font-size:.875rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
317
317
|
}
|
|
318
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
318
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
319
319
|
type: Component,
|
|
320
320
|
args: [{ selector: 'lib-button', imports: [CommonModule], template: "<button type=\"button\" class=\"btn\" [style.background-color]=\"backgroundColor\" [style.color]=\"color\"\n [style.border-color]=\"borderColor\" [style.min-width]=\"minWidth\" [disabled]=\"disabled || loading\"\n (click)=\"onClick()\">\n <span *ngIf=\"loading\" class=\"spinner-border spinner-border-sm me-2\" role=\"status\" aria-hidden=\"true\"></span>\n <span *ngIf=\"!loading\">{{title}}</span>\n <span *ngIf=\"loading\">{{loadingText}}</span>\n</button>", styles: ["span{font-family:DM Sans,sans-serif;font-weight:400;font-size:.875rem}\n"] }]
|
|
321
321
|
}], propDecorators: { title: [{
|
|
@@ -393,10 +393,10 @@ class CheckboxComponent {
|
|
|
393
393
|
// Adicione outras mensagens customizadas conforme necessário
|
|
394
394
|
return 'Valor inválido.';
|
|
395
395
|
}
|
|
396
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
397
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
396
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CheckboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
397
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CheckboxComponent, isStandalone: true, selector: "lib-checkbox", inputs: { options: "options", multiple: "multiple", control: "control" }, outputs: { selectedChange: "selectedChange" }, ngImport: i0, template: "<div *ngFor=\"let option of options; let i = index\"\n style=\"display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.25rem;\">\n\n <input class=\"form-check-input\" [type]=\"multiple ? 'checkbox' : 'radio'\"\n [name]=\"multiple ? 'checkbox-group' : 'radio-group'\" [value]=\"option.value\" [checked]=\"isChecked(option.value)\"\n [disabled]=\"disabled\" (change)=\"onOptionChange($event, option.value)\" />\n <span>{{ option.label }}</span>\n</div>\n<div *ngIf=\"showError\" class=\"text-danger small mt-1\">\n {{ errorMessage }}\n</div>", styles: ["input{cursor:pointer;margin-top:0}.form-check-input:checked{background-color:#414141;border-color:#414141}.form-check-input:focus{border-color:#b2b9be;outline:0;box-shadow:0 0 0 .25rem #04112440}span{font-family:DM Sans,sans-serif;font-weight:400;font-size:.875rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }] });
|
|
398
398
|
}
|
|
399
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
399
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CheckboxComponent, decorators: [{
|
|
400
400
|
type: Component,
|
|
401
401
|
args: [{ selector: 'lib-checkbox', imports: [CommonModule, ReactiveFormsModule], template: "<div *ngFor=\"let option of options; let i = index\"\n style=\"display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.25rem;\">\n\n <input class=\"form-check-input\" [type]=\"multiple ? 'checkbox' : 'radio'\"\n [name]=\"multiple ? 'checkbox-group' : 'radio-group'\" [value]=\"option.value\" [checked]=\"isChecked(option.value)\"\n [disabled]=\"disabled\" (change)=\"onOptionChange($event, option.value)\" />\n <span>{{ option.label }}</span>\n</div>\n<div *ngIf=\"showError\" class=\"text-danger small mt-1\">\n {{ errorMessage }}\n</div>", styles: ["input{cursor:pointer;margin-top:0}.form-check-input:checked{background-color:#414141;border-color:#414141}.form-check-input:focus{border-color:#b2b9be;outline:0;box-shadow:0 0 0 .25rem #04112440}span{font-family:DM Sans,sans-serif;font-weight:400;font-size:.875rem}\n"] }]
|
|
402
402
|
}], propDecorators: { options: [{
|
|
@@ -429,8 +429,8 @@ class ToggleComponent {
|
|
|
429
429
|
this.onChange(this.value);
|
|
430
430
|
this.onTouched();
|
|
431
431
|
}
|
|
432
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
433
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
432
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
433
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: ToggleComponent, isStandalone: true, selector: "lib-toggle", inputs: { title: "title", enableTitle: "enableTitle" }, providers: [
|
|
434
434
|
{
|
|
435
435
|
provide: NG_VALUE_ACCESSOR,
|
|
436
436
|
useExisting: forwardRef(() => ToggleComponent),
|
|
@@ -438,7 +438,7 @@ class ToggleComponent {
|
|
|
438
438
|
}
|
|
439
439
|
], ngImport: i0, template: "<div class=\"form-check form-switch centered-toggle\">\n <div>\n <input class=\"form-check-input\" type=\"checkbox\" [checked]=\"value\" (change)=\"toggle()\" />\n </div>\n <span *ngIf=\"enableTitle\">{{ title }}</span>\n</div>", styles: [".centered-toggle{display:flex;align-items:anchor-center}input{cursor:pointer;margin-top:0}.form-check-input:checked{background-color:#414141;border-color:#414141}.form-check-input:focus{border-color:#b2b9be;outline:0;box-shadow:0 0 0 .25rem #04112440}span{font-family:DM Sans,sans-serif;font-weight:400;font-size:.875rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
440
440
|
}
|
|
441
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
441
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ToggleComponent, decorators: [{
|
|
442
442
|
type: Component,
|
|
443
443
|
args: [{ selector: 'lib-toggle', imports: [CommonModule], providers: [
|
|
444
444
|
{
|
|
@@ -455,10 +455,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
455
455
|
|
|
456
456
|
class BreadcrumbComponent {
|
|
457
457
|
items = [];
|
|
458
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
459
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
458
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: BreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
459
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: BreadcrumbComponent, isStandalone: true, selector: "lib-breadcrumb", inputs: { items: "items" }, ngImport: i0, template: "<nav class=\"breadcrumb\">\n <ol class=\"breadcrumb-list\">\n <li class=\"breadcrumb-item\" *ngFor=\"let item of items; let last = last\">\n <a *ngIf=\"!last\" [routerLink]=\"item.url\">{{ item.label }}</a>\n <span *ngIf=\"last\">{{ item.label }}</span>\n </li>\n </ol>\n</nav>", styles: [".breadcrumb{font-family:DM Sans,sans-serif;background:none;padding:.5rem 0;margin-bottom:1rem}.breadcrumb-list{display:flex;flex-wrap:wrap;list-style:none;padding:0;margin:0}.breadcrumb-item{display:flex;align-items:center;font-size:.875rem;color:#495057;font-weight:500}.breadcrumb-item a{color:#414141;text-decoration:none;padding:.25rem .5rem;border-radius:4px;transition:background .2s,color .2s}.breadcrumb-item a:hover{background:#dee2e6;color:#343a40;text-decoration:underline}.breadcrumb-separator{margin:0 .25rem;color:#b2b9be;font-size:1rem}.breadcrumb-item:last-child{color:#6c757d;font-weight:400}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
460
460
|
}
|
|
461
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
461
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: BreadcrumbComponent, decorators: [{
|
|
462
462
|
type: Component,
|
|
463
463
|
args: [{ selector: 'lib-breadcrumb', imports: [RouterModule, CommonModule], template: "<nav class=\"breadcrumb\">\n <ol class=\"breadcrumb-list\">\n <li class=\"breadcrumb-item\" *ngFor=\"let item of items; let last = last\">\n <a *ngIf=\"!last\" [routerLink]=\"item.url\">{{ item.label }}</a>\n <span *ngIf=\"last\">{{ item.label }}</span>\n </li>\n </ol>\n</nav>", styles: [".breadcrumb{font-family:DM Sans,sans-serif;background:none;padding:.5rem 0;margin-bottom:1rem}.breadcrumb-list{display:flex;flex-wrap:wrap;list-style:none;padding:0;margin:0}.breadcrumb-item{display:flex;align-items:center;font-size:.875rem;color:#495057;font-weight:500}.breadcrumb-item a{color:#414141;text-decoration:none;padding:.25rem .5rem;border-radius:4px;transition:background .2s,color .2s}.breadcrumb-item a:hover{background:#dee2e6;color:#343a40;text-decoration:underline}.breadcrumb-separator{margin:0 .25rem;color:#b2b9be;font-size:1rem}.breadcrumb-item:last-child{color:#6c757d;font-weight:400}\n"] }]
|
|
464
464
|
}], propDecorators: { items: [{
|
|
@@ -537,10 +537,10 @@ class TableComponent {
|
|
|
537
537
|
toNumber(val) {
|
|
538
538
|
return typeof val === 'number' ? val : parseInt(val, 10);
|
|
539
539
|
}
|
|
540
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
541
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
540
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
541
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: TableComponent, isStandalone: true, selector: "lib-table", inputs: { columns: "columns", data: "data", columnTypes: "columnTypes", page: "page", pageSize: "pageSize", totalItems: "totalItems", pageSizeOptions: "pageSizeOptions" }, outputs: { pageChange: "pageChange", pageSizeChange: "pageSizeChange" }, ngImport: i0, template: "<table class=\"table\">\n <thead class=\"table-light\">\n <tr>\n <ng-container *ngFor=\"let col of columns\">\n <th [style.width]=\"col.width || null\">\n {{ col.title }}\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of data\">\n <ng-container *ngFor=\"let col of columns\">\n <td class=\"align-middle\">\n <ng-container *ngIf=\"!col.actions\" [ngSwitch]=\"columnTypes[col.prop]\">\n <ng-container *ngSwitchCase=\"'date'\">{{ row[col.prop] | date:'dd/MM/yyyy' }}</ng-container>\n <ng-container *ngSwitchCase=\"'time'\">{{ row[col.prop] | date:'HH:mm' }}</ng-container>\n <ng-container *ngSwitchCase=\"'tag'\">\n <span class=\"badge rounded-pill\" [ngClass]=\"row[col.prop + 'Class'] || 'text-bg-dark'\">{{\n row[col.prop] }}</span>\n </ng-container>\n <ng-container *ngSwitchDefault>{{ row[col.prop] }}</ng-container>\n </ng-container>\n <ng-container *ngIf=\"col.actions\">\n <div class=\"dropdown\">\n <button class=\"btn btn-light btn-sm\" type=\"button\" data-bs-toggle=\"dropdown\"\n aria-expanded=\"false\">\n <i class=\"material-icons align-middle\">more_horiz</i>\n </button>\n <ul class=\"dropdown-menu\">\n <li *ngFor=\"let action of col.actions\">\n <a class=\"dropdown-item\" href=\"#\"\n (click)=\"action.callback(row); $event.preventDefault()\">\n <i *ngIf=\"action.icon\" class=\"material-icons align-middle me-2\">{{ action.icon\n }}</i>\n {{ action.title }}\n </a>\n </li>\n </ul>\n </div>\n </ng-container>\n </td>\n </ng-container>\n </tr>\n </tbody>\n</table>\n\n<!-- Paginator -->\n<nav aria-label=\"Tabela pagina\u00E7\u00E3o\" class=\"d-flex justify-content-between mt-3\">\n <lib-dropdown [options]=\"pageSizeOptions\" placeholder=\"Tamanho da p\u00E1gina\" [selectedOption]=\"pageSize\"\n [hideLabel]=\"true\" (valueChange)=\"onPageSizeChange($event)\"></lib-dropdown>\n\n <ul *ngIf=\"totalPages > 1\" class=\"pagination pagination-sm\">\n <li class=\"page-item\" [class.disabled]=\"currentPage === 1\">\n <button class=\"page-link\" (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage === 1\">\n <i class=\"material-icons align-middle\">chevron_left</i>\n </button>\n </li>\n <ng-container *ngFor=\"let page of getPages()\">\n <li class=\"page-item\" *ngIf=\"page !== '...'\" [class.active]=\"page === currentPage\">\n <button class=\"page-link\" (click)=\"goToPage(toNumber(page))\" [disabled]=\"page === currentPage\">{{ page\n }}</button>\n </li>\n <li class=\"page-item disabled\" *ngIf=\"page === '...'\"><span class=\"page-link\">...</span></li>\n </ng-container>\n <li class=\"page-item\" [class.disabled]=\"currentPage === totalPages\">\n <button class=\"page-link\" (click)=\"goToPage(currentPage + 1)\" [disabled]=\"currentPage === totalPages\">\n <i class=\"material-icons align-middle\">chevron_right</i>\n </button>\n </li>\n </ul>\n</nav>", styles: ["thead{border-top:1px solid #c6c7c8}thead th{font-family:DM Sans,sans-serif;font-weight:600;font-size:.875rem}tbody th,tbody td,tbody .dropdown-menu{font-family:DM Sans,sans-serif;font-weight:400;font-size:.875rem}.pagination i{font-size:20px}.pagination .page-item .page-link{color:#414141;background-color:#fff}.pagination .page-item.active .page-link{color:#fff;background-color:#414141;border-color:#414141}\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]" }, { kind: "component", type: DropdownComponent, selector: "lib-dropdown", inputs: ["label", "placeholder", "options", "disabled", "required", "errorMessage", "selectedOption", "hideLabel"], outputs: ["valueChange"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }] });
|
|
542
542
|
}
|
|
543
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
543
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: TableComponent, decorators: [{
|
|
544
544
|
type: Component,
|
|
545
545
|
args: [{ selector: 'lib-table', imports: [CommonModule, DropdownComponent], template: "<table class=\"table\">\n <thead class=\"table-light\">\n <tr>\n <ng-container *ngFor=\"let col of columns\">\n <th [style.width]=\"col.width || null\">\n {{ col.title }}\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of data\">\n <ng-container *ngFor=\"let col of columns\">\n <td class=\"align-middle\">\n <ng-container *ngIf=\"!col.actions\" [ngSwitch]=\"columnTypes[col.prop]\">\n <ng-container *ngSwitchCase=\"'date'\">{{ row[col.prop] | date:'dd/MM/yyyy' }}</ng-container>\n <ng-container *ngSwitchCase=\"'time'\">{{ row[col.prop] | date:'HH:mm' }}</ng-container>\n <ng-container *ngSwitchCase=\"'tag'\">\n <span class=\"badge rounded-pill\" [ngClass]=\"row[col.prop + 'Class'] || 'text-bg-dark'\">{{\n row[col.prop] }}</span>\n </ng-container>\n <ng-container *ngSwitchDefault>{{ row[col.prop] }}</ng-container>\n </ng-container>\n <ng-container *ngIf=\"col.actions\">\n <div class=\"dropdown\">\n <button class=\"btn btn-light btn-sm\" type=\"button\" data-bs-toggle=\"dropdown\"\n aria-expanded=\"false\">\n <i class=\"material-icons align-middle\">more_horiz</i>\n </button>\n <ul class=\"dropdown-menu\">\n <li *ngFor=\"let action of col.actions\">\n <a class=\"dropdown-item\" href=\"#\"\n (click)=\"action.callback(row); $event.preventDefault()\">\n <i *ngIf=\"action.icon\" class=\"material-icons align-middle me-2\">{{ action.icon\n }}</i>\n {{ action.title }}\n </a>\n </li>\n </ul>\n </div>\n </ng-container>\n </td>\n </ng-container>\n </tr>\n </tbody>\n</table>\n\n<!-- Paginator -->\n<nav aria-label=\"Tabela pagina\u00E7\u00E3o\" class=\"d-flex justify-content-between mt-3\">\n <lib-dropdown [options]=\"pageSizeOptions\" placeholder=\"Tamanho da p\u00E1gina\" [selectedOption]=\"pageSize\"\n [hideLabel]=\"true\" (valueChange)=\"onPageSizeChange($event)\"></lib-dropdown>\n\n <ul *ngIf=\"totalPages > 1\" class=\"pagination pagination-sm\">\n <li class=\"page-item\" [class.disabled]=\"currentPage === 1\">\n <button class=\"page-link\" (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage === 1\">\n <i class=\"material-icons align-middle\">chevron_left</i>\n </button>\n </li>\n <ng-container *ngFor=\"let page of getPages()\">\n <li class=\"page-item\" *ngIf=\"page !== '...'\" [class.active]=\"page === currentPage\">\n <button class=\"page-link\" (click)=\"goToPage(toNumber(page))\" [disabled]=\"page === currentPage\">{{ page\n }}</button>\n </li>\n <li class=\"page-item disabled\" *ngIf=\"page === '...'\"><span class=\"page-link\">...</span></li>\n </ng-container>\n <li class=\"page-item\" [class.disabled]=\"currentPage === totalPages\">\n <button class=\"page-link\" (click)=\"goToPage(currentPage + 1)\" [disabled]=\"currentPage === totalPages\">\n <i class=\"material-icons align-middle\">chevron_right</i>\n </button>\n </li>\n </ul>\n</nav>", styles: ["thead{border-top:1px solid #c6c7c8}thead th{font-family:DM Sans,sans-serif;font-weight:600;font-size:.875rem}tbody th,tbody td,tbody .dropdown-menu{font-family:DM Sans,sans-serif;font-weight:400;font-size:.875rem}.pagination i{font-size:20px}.pagination .page-item .page-link{color:#414141;background-color:#fff}.pagination .page-item.active .page-link{color:#fff;background-color:#414141;border-color:#414141}\n"] }]
|
|
546
546
|
}], propDecorators: { columns: [{
|
|
@@ -769,12 +769,12 @@ class SidebarComponent {
|
|
|
769
769
|
trackByItemId(index, item) {
|
|
770
770
|
return item.id;
|
|
771
771
|
}
|
|
772
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
773
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: SidebarComponent, isStandalone: true, selector: "lib-sidebar", inputs: { config: "config", menuItems: "menuItems", isCollapsed: "isCollapsed" }, outputs: { itemClick: "itemClick", toggle: "toggle", overlayToggle: "overlayToggle", logoClick: "logoClick" }, host: { listeners: { "window:resize": "onResize($event)" } }, ngImport: i0, template: "<!-- Overlay para mobile -->\n<div *ngIf=\"currentState.isMobile && currentState.isOverlayOpen\" class=\"sidebar-overlay\" (click)=\"closeOverlay()\">\n</div>\n\n<!-- Sidebar principal -->\n<aside class=\"sidebar\" [class.collapsed]=\"currentState.isCollapsed\" [class.mobile]=\"currentState.isMobile\"\n [class.overlay-open]=\"currentState.isOverlayOpen\" [class.theme-light]=\"finalConfig.theme === 'light'\"\n [class.theme-dark]=\"finalConfig.theme === 'dark'\" [class.position-left]=\"finalConfig.position === 'left'\"\n [class.position-right]=\"finalConfig.position === 'right'\" [ngClass]=\"finalConfig.customCssClass\"\n [style.width]=\"sidebarWidth\">\n\n <!-- Header com logo -->\n <div class=\"sidebar-header\" *ngIf=\"finalConfig.logo.src\">\n <button class=\"logo-container\" (click)=\"onLogoClick()\" [attr.aria-label]=\"finalConfig.logo.alt\">\n <img [src]=\"finalConfig.logo.src\" [alt]=\"finalConfig.logo.alt\" class=\"logo-image\">\n\n <span class=\"logo-text\" *ngIf=\"!currentState.isCollapsed\">\n {{ finalConfig.logo.alt }}\n </span>\n </button>\n\n <!-- Bot\u00E3o de toggle (se habilitado) -->\n <button *ngIf=\"finalConfig.collapsible && !currentState.isMobile\" class=\"toggle-btn\" (click)=\"toggleSidebar()\"\n [attr.aria-label]=\"currentState.isCollapsed ? 'Expandir menu' : 'Recolher menu'\">\n <i class=\"toggle-icon fa\" [class.fa-angle-left]=\"!currentState.isCollapsed\"\n [class.fa-angle-right]=\"currentState.isCollapsed\">\n </i>\n </button>\n </div>\n\n <!-- Navega\u00E7\u00E3o principal -->\n <nav class=\"sidebar-nav\">\n <ul class=\"nav-list\">\n <ng-container *ngFor=\"let item of menuItems; trackBy: trackByItemId\">\n\n <!-- Divisor -->\n <li *ngIf=\"item.divider\" class=\"nav-divider\" role=\"separator\"></li>\n\n <!-- Item do menu -->\n <li class=\"nav-item\" [class.active]=\"isItemActive(item)\"\n [class.has-children]=\"item.children && item.children.length > 0\" [class.expanded]=\"item.isExpanded\"\n [class.disabled]=\"item.disabled\" [class.has-active-child]=\"hasActiveChild(item)\">\n\n <a class=\"nav-link\" [routerLink]=\"item.route\" [class.no-route]=\"!item.route\"\n (click)=\"onItemClick(item, $event)\" [attr.aria-label]=\"item.label\"\n [attr.aria-expanded]=\"item.children ? item.isExpanded : null\" [attr.tabindex]=\"item.disabled ? -1 : 0\">\n\n <!-- \u00CDcone -->\n <i class=\"nav-icon\" [ngClass]=\"item.icon\" [attr.aria-hidden]=\"true\">\n </i>\n\n <!-- Label -->\n <span class=\"nav-label\" *ngIf=\"!currentState.isCollapsed\">\n {{ item.label }}\n </span>\n\n <!-- Badge -->\n <span class=\"nav-badge\" *ngIf=\"item.badge && !currentState.isCollapsed\">\n {{ item.badge }}\n </span>\n\n <!-- Seta para submenu -->\n <i class=\"nav-arrow fa\" *ngIf=\"item.children && item.children.length > 0 && !currentState.isCollapsed\"\n [class.fa-chevron-down]=\"item.isExpanded\" [class.fa-chevron-right]=\"!item.isExpanded\"\n [attr.aria-hidden]=\"true\">\n </i>\n </a>\n\n <!-- Submenu -->\n <ul class=\"nav-submenu\"\n *ngIf=\"item.children && item.children.length > 0 && item.isExpanded && !currentState.isCollapsed\">\n <li class=\"nav-subitem\" *ngFor=\"let subItem of item.children; trackBy: trackByItemId\"\n [class.active]=\"isItemActive(subItem)\" [class.disabled]=\"subItem.disabled\">\n\n <a class=\"nav-sublink\" [routerLink]=\"subItem.route\" [class.no-route]=\"!subItem.route\"\n (click)=\"onItemClick(subItem, $event)\" [attr.aria-label]=\"subItem.label\"\n [attr.tabindex]=\"subItem.disabled ? -1 : 0\">\n\n <!-- \u00CDcone do subitem -->\n <i class=\"nav-subicon\" [ngClass]=\"subItem.icon\" [attr.aria-hidden]=\"true\">\n </i>\n\n <!-- Label do subitem -->\n <span class=\"nav-sublabel\">\n {{ subItem.label }}\n </span>\n\n <!-- Badge do subitem -->\n <span class=\"nav-subbadge\" *ngIf=\"subItem.badge\">\n {{ subItem.badge }}\n </span>\n </a>\n </li>\n </ul>\n </li>\n </ng-container>\n </ul>\n </nav>\n\n <!-- Footer opcional -->\n <div class=\"sidebar-footer\" *ngIf=\"!currentState.isCollapsed\">\n <ng-content select=\"[slot=footer]\"></ng-content>\n </div>\n</aside>\n\n<!-- Bot\u00E3o mobile para abrir sidebar -->\n<button *ngIf=\"currentState.isMobile && !currentState.isOverlayOpen\" class=\"mobile-toggle-btn\" (click)=\"toggleOverlay()\"\n [attr.aria-label]=\"'Abrir menu'\">\n <i class=\"fa fa-bars\" [attr.aria-hidden]=\"true\"></i>\n</button>", styles: [":host{--sidebar-bg: #ffffff;--sidebar-text: #343a40;--sidebar-text-secondary: #495057;--sidebar-border: #dee2e6;--sidebar-hover: #f8f9fa;--sidebar-active: #007bff;--sidebar-active-bg: rgba(0, 123, 255, .1);--sidebar-transition: .3s cubic-bezier(.4, 0, .2, 1);--sidebar-shadow: 0 2px 12px rgba(0, 0, 0, .08)}:host.theme-dark{--sidebar-bg: #343a40;--sidebar-text: #ffffff;--sidebar-text-secondary: #b2b9be;--sidebar-border: #495057;--sidebar-hover: rgba(255, 255, 255, .1);--sidebar-shadow: 0 2px 12px rgba(0, 0, 0, .25)}.sidebar-overlay{position:fixed;inset:0;background:#00000080;z-index:998;backdrop-filter:blur(2px)}.sidebar{position:fixed;top:0;bottom:0;left:0;width:280px;background:var(--sidebar-bg);border-right:1px solid var(--sidebar-border);box-shadow:var(--sidebar-shadow);transition:var(--sidebar-transition);z-index:999;display:flex;flex-direction:column;overflow:visible}.sidebar.position-right{left:auto;right:0;border-left:1px solid var(--sidebar-border);border-right:none}.sidebar.collapsed{width:64px}.sidebar.collapsed .sidebar-header .logo-text,.sidebar.collapsed .nav-label,.sidebar.collapsed .nav-badge,.sidebar.collapsed .nav-arrow,.sidebar.collapsed .nav-submenu{opacity:0;pointer-events:none}.sidebar.collapsed .nav-link{justify-content:center;padding-left:.5rem;padding-right:.5rem;gap:0}.sidebar.collapsed .nav-icon{margin:0 auto}.sidebar.collapsed .sidebar-header{padding:1rem;justify-content:center!important}.sidebar.collapsed .logo-container{width:100%;display:flex;justify-content:center;align-items:center;gap:0;padding:0;margin:0}.sidebar.collapsed .logo-image{margin:0 auto;display:block;width:32px;height:32px}.sidebar.collapsed .toggle-btn{right:-18px;width:36px;height:36px}.sidebar.mobile{transform:translate(-100%)}.sidebar.mobile.position-right{transform:translate(100%)}.sidebar.mobile.overlay-open{transform:translate(0)}.sidebar-header{padding:1.5rem;border-bottom:1px solid var(--sidebar-border);display:flex;align-items:center;justify-content:space-between;min-height:80px;position:relative}.logo-container{display:flex;align-items:center;gap:1rem;background:none;border:none;padding:0;cursor:pointer;color:inherit;text-decoration:none;transition:var(--sidebar-transition)}.logo-container:hover{opacity:.8}.logo-image{width:32px;height:32px;object-fit:contain;flex-shrink:0}.logo-text{font-family:DM Sans,sans-serif;font-size:1.125rem;font-weight:600;color:var(--sidebar-text);transition:var(--sidebar-transition);white-space:nowrap}.toggle-btn{background:none;border:none;width:32px;height:32px;border-radius:.5rem;display:flex;align-items:center;background:var(--sidebar-bg);border:1px solid rgba(0,0,0,.06);box-shadow:0 6px 14px #0614231f;backdrop-filter:blur(4px);transition:transform .18s var(--sidebar-transition),box-shadow .18s var(--sidebar-transition);position:absolute;top:50%;transform:translateY(-50%);right:-16px;z-index:1000}.toggle-btn:hover{transform:translateY(-50%) translateY(-2px);box-shadow:0 10px 20px #06142329}.toggle-btn:hover{background:var(--sidebar-hover);color:var(--sidebar-text)}.toggle-btn .toggle-icon{font-size:1rem}.sidebar-nav{flex:1;overflow-y:auto;overflow-x:hidden;padding:1rem 0}.sidebar-nav::-webkit-scrollbar{width:4px}.sidebar-nav::-webkit-scrollbar-track{background:transparent}.sidebar-nav::-webkit-scrollbar-thumb{background:var(--sidebar-border);border-radius:2px}.sidebar-nav::-webkit-scrollbar-thumb:hover{background:var(--sidebar-text-secondary)}.nav-list{list-style:none;margin:0;padding:0}.nav-divider{height:1px;background:var(--sidebar-border);margin:1rem 0}.nav-item{position:relative;margin:0 1rem .25rem}.nav-item.active>.nav-link{background:var(--sidebar-active-bg);color:var(--sidebar-active)}.nav-item.active>.nav-link .nav-icon{color:var(--sidebar-active)}.nav-item.has-active-child>.nav-link{color:var(--sidebar-active)}.nav-item.has-active-child>.nav-link .nav-icon{color:var(--sidebar-active)}.nav-item.disabled{opacity:.5;pointer-events:none}.nav-link{display:flex;align-items:center;gap:1rem;padding:1rem;border-radius:.5rem;color:var(--sidebar-text);text-decoration:none;font-family:DM Sans,sans-serif;font-size:.875rem;font-weight:500;line-height:1.5;transition:var(--sidebar-transition);cursor:pointer;position:relative}.nav-link:hover:not(.active){background:var(--sidebar-hover)}.nav-link.no-route{cursor:pointer}.nav-icon{font-size:1.125rem;color:var(--sidebar-text-secondary);flex-shrink:0;width:20px;text-align:center;transition:var(--sidebar-transition)}.nav-label{flex:1;white-space:nowrap;transition:var(--sidebar-transition)}.nav-badge{background:var(--sidebar-active);color:#fff;font-size:.75rem;font-weight:600;padding:2px 6px;border-radius:10px;min-width:18px;text-align:center;transition:var(--sidebar-transition)}.nav-arrow{font-size:.875rem;color:var(--sidebar-text-secondary);transition:var(--sidebar-transition);margin-left:auto}.nav-submenu{list-style:none;margin:.25rem 0 0;padding:0;border-left:2px solid var(--sidebar-border);margin-left:calc(20px + 1rem);transition:var(--sidebar-transition)}.nav-subitem{margin:0 0 .25rem}.nav-subitem.active>.nav-sublink{color:var(--sidebar-active);background:var(--sidebar-active-bg)}.nav-subitem.active>.nav-sublink .nav-subicon{color:var(--sidebar-active)}.nav-subitem.disabled{opacity:.5;pointer-events:none}.nav-subicon{font-size:.875rem;width:16px;text-align:center;flex-shrink:0;transition:var(--sidebar-transition)}.nav-sublabel{flex:1;white-space:nowrap}.nav-subbadge{background:var(--sidebar-active);color:#fff;font-size:10px;font-weight:600;padding:1px 4px;border-radius:8px;min-width:14px;text-align:center}.sidebar-footer{padding:1rem;border-top:1px solid var(--sidebar-border);margin-top:auto}.mobile-toggle-btn{position:fixed;top:1.5rem;left:1.5rem;width:48px;height:48px;background:var(--sidebar-active);color:#fff;border:none;border-radius:.75rem;display:flex;align-items:center;justify-content:center;font-size:1.125rem;box-shadow:var(--sidebar-shadow);z-index:997;cursor:pointer;transition:var(--sidebar-transition)}.mobile-toggle-btn:hover{transform:scale(1.05)}.mobile-toggle-btn:active{transform:scale(.95)}@media (max-width: 768px){.sidebar{width:280px!important}.sidebar.position-right{transform:translate(100%)}.sidebar.position-right.overlay-open{transform:translate(0)}}@keyframes slideInLeft{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes slideInRight{0%{transform:translate(100%)}to{transform:translate(0)}}.sidebar.mobile.overlay-open{animation:slideInLeft .3s ease-out}.sidebar.mobile.overlay-open.position-right{animation:slideInRight .3s ease-out}.nav-link:focus,.nav-sublink:focus,.toggle-btn:focus,.logo-container:focus,.mobile-toggle-btn:focus{outline:2px solid var(--sidebar-active);outline-offset:2px}.collapsed .nav-submenu{display:none!important}.has-children.collapsed .nav-arrow{display:none}\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: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
|
|
772
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
773
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: SidebarComponent, isStandalone: true, selector: "lib-sidebar", inputs: { config: "config", menuItems: "menuItems", isCollapsed: "isCollapsed" }, outputs: { itemClick: "itemClick", toggle: "toggle", overlayToggle: "overlayToggle", logoClick: "logoClick" }, host: { listeners: { "window:resize": "onResize($event)" } }, ngImport: i0, template: "<!-- Overlay para mobile -->\n<div *ngIf=\"currentState.isMobile && currentState.isOverlayOpen\" class=\"sidebar-overlay\" (click)=\"closeOverlay()\">\n</div>\n\n<!-- Sidebar principal -->\n<aside class=\"sidebar\" [class.collapsed]=\"currentState.isCollapsed\" [class.mobile]=\"currentState.isMobile\"\n [class.overlay-open]=\"currentState.isOverlayOpen\" [class.theme-light]=\"finalConfig.theme === 'light'\"\n [class.theme-dark]=\"finalConfig.theme === 'dark'\" [class.position-left]=\"finalConfig.position === 'left'\"\n [class.position-right]=\"finalConfig.position === 'right'\" [ngClass]=\"finalConfig.customCssClass\"\n [style.width]=\"sidebarWidth\">\n\n <!-- Header com logo -->\n <div class=\"sidebar-header\" *ngIf=\"finalConfig.logo.src\">\n <button class=\"logo-container\" (click)=\"onLogoClick()\" [attr.aria-label]=\"finalConfig.logo.alt\">\n <img [src]=\"finalConfig.logo.src\" [alt]=\"finalConfig.logo.alt\" class=\"logo-image\">\n\n <span class=\"logo-text\" *ngIf=\"!currentState.isCollapsed\">\n {{ finalConfig.logo.alt }}\n </span>\n </button>\n\n <!-- Bot\u00E3o de toggle (se habilitado) -->\n <button *ngIf=\"finalConfig.collapsible && !currentState.isMobile\" class=\"toggle-btn\" (click)=\"toggleSidebar()\"\n [attr.aria-label]=\"currentState.isCollapsed ? 'Expandir menu' : 'Recolher menu'\">\n <i class=\"toggle-icon fa\" [class.fa-angle-left]=\"!currentState.isCollapsed\"\n [class.fa-angle-right]=\"currentState.isCollapsed\">\n </i>\n </button>\n </div>\n\n <!-- Navega\u00E7\u00E3o principal -->\n <nav class=\"sidebar-nav\">\n <ul class=\"nav-list\">\n <ng-container *ngFor=\"let item of menuItems; trackBy: trackByItemId\">\n\n <!-- Divisor -->\n <li *ngIf=\"item.divider\" class=\"nav-divider\" role=\"separator\"></li>\n\n <!-- Item do menu -->\n <li class=\"nav-item\" [class.active]=\"isItemActive(item)\"\n [class.has-children]=\"item.children && item.children.length > 0\" [class.expanded]=\"item.isExpanded\"\n [class.disabled]=\"item.disabled\" [class.has-active-child]=\"hasActiveChild(item)\">\n\n <a class=\"nav-link\" [routerLink]=\"item.route\" [class.no-route]=\"!item.route\"\n (click)=\"onItemClick(item, $event)\" [attr.aria-label]=\"item.label\"\n [attr.aria-expanded]=\"item.children ? item.isExpanded : null\" [attr.tabindex]=\"item.disabled ? -1 : 0\">\n\n <!-- \u00CDcone -->\n <i class=\"nav-icon\" [ngClass]=\"item.icon\" [attr.aria-hidden]=\"true\">\n </i>\n\n <!-- Label -->\n <span class=\"nav-label\" *ngIf=\"!currentState.isCollapsed\">\n {{ item.label }}\n </span>\n\n <!-- Badge -->\n <span class=\"nav-badge\" *ngIf=\"item.badge && !currentState.isCollapsed\">\n {{ item.badge }}\n </span>\n\n <!-- Seta para submenu -->\n <i class=\"nav-arrow fa\" *ngIf=\"item.children && item.children.length > 0 && !currentState.isCollapsed\"\n [class.fa-chevron-down]=\"item.isExpanded\" [class.fa-chevron-right]=\"!item.isExpanded\"\n [attr.aria-hidden]=\"true\">\n </i>\n </a>\n\n <!-- Submenu -->\n <ul class=\"nav-submenu\"\n *ngIf=\"item.children && item.children.length > 0 && item.isExpanded && !currentState.isCollapsed\">\n <li class=\"nav-subitem\" *ngFor=\"let subItem of item.children; trackBy: trackByItemId\"\n [class.active]=\"isItemActive(subItem)\" [class.disabled]=\"subItem.disabled\">\n\n <a class=\"nav-sublink\" [routerLink]=\"subItem.route\" [class.no-route]=\"!subItem.route\"\n (click)=\"onItemClick(subItem, $event)\" [attr.aria-label]=\"subItem.label\"\n [attr.tabindex]=\"subItem.disabled ? -1 : 0\">\n\n <!-- \u00CDcone do subitem -->\n <i class=\"nav-subicon\" [ngClass]=\"subItem.icon\" [attr.aria-hidden]=\"true\">\n </i>\n\n <!-- Label do subitem -->\n <span class=\"nav-sublabel\">\n {{ subItem.label }}\n </span>\n\n <!-- Badge do subitem -->\n <span class=\"nav-subbadge\" *ngIf=\"subItem.badge\">\n {{ subItem.badge }}\n </span>\n </a>\n </li>\n </ul>\n </li>\n </ng-container>\n </ul>\n </nav>\n\n <!-- Footer opcional -->\n <div class=\"sidebar-footer\" *ngIf=\"!currentState.isCollapsed\">\n <ng-content select=\"[slot=footer]\"></ng-content>\n </div>\n</aside>\n\n<!-- Bot\u00E3o mobile para abrir sidebar -->\n<button *ngIf=\"currentState.isMobile && !currentState.isOverlayOpen\" class=\"mobile-toggle-btn\" (click)=\"toggleOverlay()\"\n [attr.aria-label]=\"'Abrir menu'\">\n <i class=\"fa fa-bars\" [attr.aria-hidden]=\"true\"></i>\n</button>", styles: [":host{--sidebar-bg: #ffffff;--sidebar-text: #343a40;--sidebar-text-secondary: #495057;--sidebar-border: #dee2e6;--sidebar-hover: #f8f9fa;--sidebar-active: #007bff;--sidebar-active-bg: rgba(0, 123, 255, .1);--sidebar-transition: .3s cubic-bezier(.4, 0, .2, 1);--sidebar-shadow: 0 2px 12px rgba(0, 0, 0, .08)}:host.theme-dark{--sidebar-bg: #343a40;--sidebar-text: #ffffff;--sidebar-text-secondary: #b2b9be;--sidebar-border: #495057;--sidebar-hover: rgba(255, 255, 255, .1);--sidebar-shadow: 0 2px 12px rgba(0, 0, 0, .25)}.sidebar-overlay{position:fixed;inset:0;background:#00000080;z-index:998;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.sidebar{position:fixed;top:0;bottom:0;left:0;width:280px;background:var(--sidebar-bg);border-right:1px solid var(--sidebar-border);box-shadow:var(--sidebar-shadow);transition:var(--sidebar-transition);z-index:999;display:flex;flex-direction:column;overflow:visible}.sidebar.position-right{left:auto;right:0;border-left:1px solid var(--sidebar-border);border-right:none}.sidebar.collapsed{width:64px}.sidebar.collapsed .sidebar-header .logo-text,.sidebar.collapsed .nav-label,.sidebar.collapsed .nav-badge,.sidebar.collapsed .nav-arrow,.sidebar.collapsed .nav-submenu{opacity:0;pointer-events:none}.sidebar.collapsed .nav-link{justify-content:center;padding-left:.5rem;padding-right:.5rem;gap:0}.sidebar.collapsed .nav-icon{margin:0 auto}.sidebar.collapsed .sidebar-header{padding:1rem;justify-content:center!important}.sidebar.collapsed .logo-container{width:100%;display:flex;justify-content:center;align-items:center;gap:0;padding:0;margin:0}.sidebar.collapsed .logo-image{margin:0 auto;display:block;width:32px;height:32px}.sidebar.collapsed .toggle-btn{right:-18px;width:36px;height:36px}.sidebar.mobile{transform:translate(-100%)}.sidebar.mobile.position-right{transform:translate(100%)}.sidebar.mobile.overlay-open{transform:translate(0)}.sidebar-header{padding:1.5rem;border-bottom:1px solid var(--sidebar-border);display:flex;align-items:center;justify-content:space-between;min-height:80px;position:relative}.logo-container{display:flex;align-items:center;gap:1rem;background:none;border:none;padding:0;cursor:pointer;color:inherit;text-decoration:none;transition:var(--sidebar-transition)}.logo-container:hover{opacity:.8}.logo-image{width:32px;height:32px;object-fit:contain;flex-shrink:0}.logo-text{font-family:DM Sans,sans-serif;font-size:1.125rem;font-weight:600;color:var(--sidebar-text);transition:var(--sidebar-transition);white-space:nowrap}.toggle-btn{background:none;border:none;width:32px;height:32px;border-radius:.5rem;display:flex;align-items:center;background:var(--sidebar-bg);border:1px solid rgba(0,0,0,.06);box-shadow:0 6px 14px #0614231f;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);transition:transform .18s var(--sidebar-transition),box-shadow .18s var(--sidebar-transition)}.toggle-btn:hover{transform:translateY(-50%) translateY(-2px);box-shadow:0 10px 20px #06142329}.toggle-btn{position:absolute;top:50%;transform:translateY(-50%);right:-16px;z-index:1000}.toggle-btn:hover{background:var(--sidebar-hover);color:var(--sidebar-text)}.toggle-btn .toggle-icon{font-size:1rem}.sidebar-nav{flex:1;overflow-y:auto;overflow-x:hidden;padding:1rem 0}.sidebar-nav::-webkit-scrollbar{width:4px}.sidebar-nav::-webkit-scrollbar-track{background:transparent}.sidebar-nav::-webkit-scrollbar-thumb{background:var(--sidebar-border);border-radius:2px}.sidebar-nav::-webkit-scrollbar-thumb:hover{background:var(--sidebar-text-secondary)}.nav-list{list-style:none;margin:0;padding:0}.nav-divider{height:1px;background:var(--sidebar-border);margin:1rem 0}.nav-item{position:relative;margin:0 1rem .25rem}.nav-item.active>.nav-link{background:var(--sidebar-active-bg);color:var(--sidebar-active)}.nav-item.active>.nav-link .nav-icon{color:var(--sidebar-active)}.nav-item.has-active-child>.nav-link{color:var(--sidebar-active)}.nav-item.has-active-child>.nav-link .nav-icon{color:var(--sidebar-active)}.nav-item.disabled{opacity:.5;pointer-events:none}.nav-link{display:flex;align-items:center;gap:1rem;padding:1rem;border-radius:.5rem;color:var(--sidebar-text);text-decoration:none;font-family:DM Sans,sans-serif;font-size:.875rem;font-weight:500;line-height:1.5;transition:var(--sidebar-transition);cursor:pointer;position:relative}.nav-link:hover:not(.active){background:var(--sidebar-hover)}.nav-link.no-route{cursor:pointer}.nav-icon{font-size:1.125rem;color:var(--sidebar-text-secondary);flex-shrink:0;width:20px;text-align:center;transition:var(--sidebar-transition)}.nav-label{flex:1;white-space:nowrap;transition:var(--sidebar-transition)}.nav-badge{background:var(--sidebar-active);color:#fff;font-size:.75rem;font-weight:600;padding:2px 6px;border-radius:10px;min-width:18px;text-align:center;transition:var(--sidebar-transition)}.nav-arrow{font-size:.875rem;color:var(--sidebar-text-secondary);transition:var(--sidebar-transition);margin-left:auto}.nav-submenu{list-style:none;margin:.25rem 0 0;padding:0;border-left:2px solid var(--sidebar-border);margin-left:calc(20px + 1rem);transition:var(--sidebar-transition)}.nav-subitem{margin:0 0 .25rem}.nav-subitem.active>.nav-sublink{color:var(--sidebar-active);background:var(--sidebar-active-bg)}.nav-subitem.active>.nav-sublink .nav-subicon{color:var(--sidebar-active)}.nav-subitem.disabled{opacity:.5;pointer-events:none}.nav-subicon{font-size:.875rem;width:16px;text-align:center;flex-shrink:0;transition:var(--sidebar-transition)}.nav-sublabel{flex:1;white-space:nowrap}.nav-subbadge{background:var(--sidebar-active);color:#fff;font-size:10px;font-weight:600;padding:1px 4px;border-radius:8px;min-width:14px;text-align:center}.sidebar-footer{padding:1rem;border-top:1px solid var(--sidebar-border);margin-top:auto}.mobile-toggle-btn{position:fixed;top:1.5rem;left:1.5rem;width:48px;height:48px;background:var(--sidebar-active);color:#fff;border:none;border-radius:.75rem;display:flex;align-items:center;justify-content:center;font-size:1.125rem;box-shadow:var(--sidebar-shadow);z-index:997;cursor:pointer;transition:var(--sidebar-transition)}.mobile-toggle-btn:hover{transform:scale(1.05)}.mobile-toggle-btn:active{transform:scale(.95)}@media(max-width:768px){.sidebar{width:280px!important}.sidebar.position-right{transform:translate(100%)}.sidebar.position-right.overlay-open{transform:translate(0)}}@keyframes slideInLeft{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes slideInRight{0%{transform:translate(100%)}to{transform:translate(0)}}.sidebar.mobile.overlay-open{animation:slideInLeft .3s ease-out}.sidebar.mobile.overlay-open.position-right{animation:slideInRight .3s ease-out}.nav-link:focus,.nav-sublink:focus,.toggle-btn:focus,.logo-container:focus,.mobile-toggle-btn:focus{outline:2px solid var(--sidebar-active);outline-offset:2px}.collapsed .nav-submenu{display:none!important}.has-children.collapsed .nav-arrow{display:none}\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: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
|
|
774
774
|
}
|
|
775
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
775
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SidebarComponent, decorators: [{
|
|
776
776
|
type: Component,
|
|
777
|
-
args: [{ selector: 'lib-sidebar', imports: [CommonModule, RouterModule], template: "<!-- Overlay para mobile -->\n<div *ngIf=\"currentState.isMobile && currentState.isOverlayOpen\" class=\"sidebar-overlay\" (click)=\"closeOverlay()\">\n</div>\n\n<!-- Sidebar principal -->\n<aside class=\"sidebar\" [class.collapsed]=\"currentState.isCollapsed\" [class.mobile]=\"currentState.isMobile\"\n [class.overlay-open]=\"currentState.isOverlayOpen\" [class.theme-light]=\"finalConfig.theme === 'light'\"\n [class.theme-dark]=\"finalConfig.theme === 'dark'\" [class.position-left]=\"finalConfig.position === 'left'\"\n [class.position-right]=\"finalConfig.position === 'right'\" [ngClass]=\"finalConfig.customCssClass\"\n [style.width]=\"sidebarWidth\">\n\n <!-- Header com logo -->\n <div class=\"sidebar-header\" *ngIf=\"finalConfig.logo.src\">\n <button class=\"logo-container\" (click)=\"onLogoClick()\" [attr.aria-label]=\"finalConfig.logo.alt\">\n <img [src]=\"finalConfig.logo.src\" [alt]=\"finalConfig.logo.alt\" class=\"logo-image\">\n\n <span class=\"logo-text\" *ngIf=\"!currentState.isCollapsed\">\n {{ finalConfig.logo.alt }}\n </span>\n </button>\n\n <!-- Bot\u00E3o de toggle (se habilitado) -->\n <button *ngIf=\"finalConfig.collapsible && !currentState.isMobile\" class=\"toggle-btn\" (click)=\"toggleSidebar()\"\n [attr.aria-label]=\"currentState.isCollapsed ? 'Expandir menu' : 'Recolher menu'\">\n <i class=\"toggle-icon fa\" [class.fa-angle-left]=\"!currentState.isCollapsed\"\n [class.fa-angle-right]=\"currentState.isCollapsed\">\n </i>\n </button>\n </div>\n\n <!-- Navega\u00E7\u00E3o principal -->\n <nav class=\"sidebar-nav\">\n <ul class=\"nav-list\">\n <ng-container *ngFor=\"let item of menuItems; trackBy: trackByItemId\">\n\n <!-- Divisor -->\n <li *ngIf=\"item.divider\" class=\"nav-divider\" role=\"separator\"></li>\n\n <!-- Item do menu -->\n <li class=\"nav-item\" [class.active]=\"isItemActive(item)\"\n [class.has-children]=\"item.children && item.children.length > 0\" [class.expanded]=\"item.isExpanded\"\n [class.disabled]=\"item.disabled\" [class.has-active-child]=\"hasActiveChild(item)\">\n\n <a class=\"nav-link\" [routerLink]=\"item.route\" [class.no-route]=\"!item.route\"\n (click)=\"onItemClick(item, $event)\" [attr.aria-label]=\"item.label\"\n [attr.aria-expanded]=\"item.children ? item.isExpanded : null\" [attr.tabindex]=\"item.disabled ? -1 : 0\">\n\n <!-- \u00CDcone -->\n <i class=\"nav-icon\" [ngClass]=\"item.icon\" [attr.aria-hidden]=\"true\">\n </i>\n\n <!-- Label -->\n <span class=\"nav-label\" *ngIf=\"!currentState.isCollapsed\">\n {{ item.label }}\n </span>\n\n <!-- Badge -->\n <span class=\"nav-badge\" *ngIf=\"item.badge && !currentState.isCollapsed\">\n {{ item.badge }}\n </span>\n\n <!-- Seta para submenu -->\n <i class=\"nav-arrow fa\" *ngIf=\"item.children && item.children.length > 0 && !currentState.isCollapsed\"\n [class.fa-chevron-down]=\"item.isExpanded\" [class.fa-chevron-right]=\"!item.isExpanded\"\n [attr.aria-hidden]=\"true\">\n </i>\n </a>\n\n <!-- Submenu -->\n <ul class=\"nav-submenu\"\n *ngIf=\"item.children && item.children.length > 0 && item.isExpanded && !currentState.isCollapsed\">\n <li class=\"nav-subitem\" *ngFor=\"let subItem of item.children; trackBy: trackByItemId\"\n [class.active]=\"isItemActive(subItem)\" [class.disabled]=\"subItem.disabled\">\n\n <a class=\"nav-sublink\" [routerLink]=\"subItem.route\" [class.no-route]=\"!subItem.route\"\n (click)=\"onItemClick(subItem, $event)\" [attr.aria-label]=\"subItem.label\"\n [attr.tabindex]=\"subItem.disabled ? -1 : 0\">\n\n <!-- \u00CDcone do subitem -->\n <i class=\"nav-subicon\" [ngClass]=\"subItem.icon\" [attr.aria-hidden]=\"true\">\n </i>\n\n <!-- Label do subitem -->\n <span class=\"nav-sublabel\">\n {{ subItem.label }}\n </span>\n\n <!-- Badge do subitem -->\n <span class=\"nav-subbadge\" *ngIf=\"subItem.badge\">\n {{ subItem.badge }}\n </span>\n </a>\n </li>\n </ul>\n </li>\n </ng-container>\n </ul>\n </nav>\n\n <!-- Footer opcional -->\n <div class=\"sidebar-footer\" *ngIf=\"!currentState.isCollapsed\">\n <ng-content select=\"[slot=footer]\"></ng-content>\n </div>\n</aside>\n\n<!-- Bot\u00E3o mobile para abrir sidebar -->\n<button *ngIf=\"currentState.isMobile && !currentState.isOverlayOpen\" class=\"mobile-toggle-btn\" (click)=\"toggleOverlay()\"\n [attr.aria-label]=\"'Abrir menu'\">\n <i class=\"fa fa-bars\" [attr.aria-hidden]=\"true\"></i>\n</button>", styles: [":host{--sidebar-bg: #ffffff;--sidebar-text: #343a40;--sidebar-text-secondary: #495057;--sidebar-border: #dee2e6;--sidebar-hover: #f8f9fa;--sidebar-active: #007bff;--sidebar-active-bg: rgba(0, 123, 255, .1);--sidebar-transition: .3s cubic-bezier(.4, 0, .2, 1);--sidebar-shadow: 0 2px 12px rgba(0, 0, 0, .08)}:host.theme-dark{--sidebar-bg: #343a40;--sidebar-text: #ffffff;--sidebar-text-secondary: #b2b9be;--sidebar-border: #495057;--sidebar-hover: rgba(255, 255, 255, .1);--sidebar-shadow: 0 2px 12px rgba(0, 0, 0, .25)}.sidebar-overlay{position:fixed;inset:0;background:#00000080;z-index:998;backdrop-filter:blur(2px)}.sidebar{position:fixed;top:0;bottom:0;left:0;width:280px;background:var(--sidebar-bg);border-right:1px solid var(--sidebar-border);box-shadow:var(--sidebar-shadow);transition:var(--sidebar-transition);z-index:999;display:flex;flex-direction:column;overflow:visible}.sidebar.position-right{left:auto;right:0;border-left:1px solid var(--sidebar-border);border-right:none}.sidebar.collapsed{width:64px}.sidebar.collapsed .sidebar-header .logo-text,.sidebar.collapsed .nav-label,.sidebar.collapsed .nav-badge,.sidebar.collapsed .nav-arrow,.sidebar.collapsed .nav-submenu{opacity:0;pointer-events:none}.sidebar.collapsed .nav-link{justify-content:center;padding-left:.5rem;padding-right:.5rem;gap:0}.sidebar.collapsed .nav-icon{margin:0 auto}.sidebar.collapsed .sidebar-header{padding:1rem;justify-content:center!important}.sidebar.collapsed .logo-container{width:100%;display:flex;justify-content:center;align-items:center;gap:0;padding:0;margin:0}.sidebar.collapsed .logo-image{margin:0 auto;display:block;width:32px;height:32px}.sidebar.collapsed .toggle-btn{right:-18px;width:36px;height:36px}.sidebar.mobile{transform:translate(-100%)}.sidebar.mobile.position-right{transform:translate(100%)}.sidebar.mobile.overlay-open{transform:translate(0)}.sidebar-header{padding:1.5rem;border-bottom:1px solid var(--sidebar-border);display:flex;align-items:center;justify-content:space-between;min-height:80px;position:relative}.logo-container{display:flex;align-items:center;gap:1rem;background:none;border:none;padding:0;cursor:pointer;color:inherit;text-decoration:none;transition:var(--sidebar-transition)}.logo-container:hover{opacity:.8}.logo-image{width:32px;height:32px;object-fit:contain;flex-shrink:0}.logo-text{font-family:DM Sans,sans-serif;font-size:1.125rem;font-weight:600;color:var(--sidebar-text);transition:var(--sidebar-transition);white-space:nowrap}.toggle-btn{background:none;border:none;width:32px;height:32px;border-radius:.5rem;display:flex;align-items:center;background:var(--sidebar-bg);border:1px solid rgba(0,0,0,.06);box-shadow:0 6px 14px #0614231f;backdrop-filter:blur(4px);transition:transform .18s var(--sidebar-transition),box-shadow .18s var(--sidebar-transition);position:absolute;top:50%;transform:translateY(-50%);right:-16px;z-index:1000}.toggle-btn:hover{transform:translateY(-50%) translateY(-2px);box-shadow:0 10px 20px #06142329}.toggle-btn:hover{background:var(--sidebar-hover);color:var(--sidebar-text)}.toggle-btn .toggle-icon{font-size:1rem}.sidebar-nav{flex:1;overflow-y:auto;overflow-x:hidden;padding:1rem 0}.sidebar-nav::-webkit-scrollbar{width:4px}.sidebar-nav::-webkit-scrollbar-track{background:transparent}.sidebar-nav::-webkit-scrollbar-thumb{background:var(--sidebar-border);border-radius:2px}.sidebar-nav::-webkit-scrollbar-thumb:hover{background:var(--sidebar-text-secondary)}.nav-list{list-style:none;margin:0;padding:0}.nav-divider{height:1px;background:var(--sidebar-border);margin:1rem 0}.nav-item{position:relative;margin:0 1rem .25rem}.nav-item.active>.nav-link{background:var(--sidebar-active-bg);color:var(--sidebar-active)}.nav-item.active>.nav-link .nav-icon{color:var(--sidebar-active)}.nav-item.has-active-child>.nav-link{color:var(--sidebar-active)}.nav-item.has-active-child>.nav-link .nav-icon{color:var(--sidebar-active)}.nav-item.disabled{opacity:.5;pointer-events:none}.nav-link{display:flex;align-items:center;gap:1rem;padding:1rem;border-radius:.5rem;color:var(--sidebar-text);text-decoration:none;font-family:DM Sans,sans-serif;font-size:.875rem;font-weight:500;line-height:1.5;transition:var(--sidebar-transition);cursor:pointer;position:relative}.nav-link:hover:not(.active){background:var(--sidebar-hover)}.nav-link.no-route{cursor:pointer}.nav-icon{font-size:1.125rem;color:var(--sidebar-text-secondary);flex-shrink:0;width:20px;text-align:center;transition:var(--sidebar-transition)}.nav-label{flex:1;white-space:nowrap;transition:var(--sidebar-transition)}.nav-badge{background:var(--sidebar-active);color:#fff;font-size:.75rem;font-weight:600;padding:2px 6px;border-radius:10px;min-width:18px;text-align:center;transition:var(--sidebar-transition)}.nav-arrow{font-size:.875rem;color:var(--sidebar-text-secondary);transition:var(--sidebar-transition);margin-left:auto}.nav-submenu{list-style:none;margin:.25rem 0 0;padding:0;border-left:2px solid var(--sidebar-border);margin-left:calc(20px + 1rem);transition:var(--sidebar-transition)}.nav-subitem{margin:0 0 .25rem}.nav-subitem.active>.nav-sublink{color:var(--sidebar-active);background:var(--sidebar-active-bg)}.nav-subitem.active>.nav-sublink .nav-subicon{color:var(--sidebar-active)}.nav-subitem.disabled{opacity:.5;pointer-events:none}.nav-subicon{font-size:.875rem;width:16px;text-align:center;flex-shrink:0;transition:var(--sidebar-transition)}.nav-sublabel{flex:1;white-space:nowrap}.nav-subbadge{background:var(--sidebar-active);color:#fff;font-size:10px;font-weight:600;padding:1px 4px;border-radius:8px;min-width:14px;text-align:center}.sidebar-footer{padding:1rem;border-top:1px solid var(--sidebar-border);margin-top:auto}.mobile-toggle-btn{position:fixed;top:1.5rem;left:1.5rem;width:48px;height:48px;background:var(--sidebar-active);color:#fff;border:none;border-radius:.75rem;display:flex;align-items:center;justify-content:center;font-size:1.125rem;box-shadow:var(--sidebar-shadow);z-index:997;cursor:pointer;transition:var(--sidebar-transition)}.mobile-toggle-btn:hover{transform:scale(1.05)}.mobile-toggle-btn:active{transform:scale(.95)}@media (max-width: 768px){.sidebar{width:280px!important}.sidebar.position-right{transform:translate(100%)}.sidebar.position-right.overlay-open{transform:translate(0)}}@keyframes slideInLeft{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes slideInRight{0%{transform:translate(100%)}to{transform:translate(0)}}.sidebar.mobile.overlay-open{animation:slideInLeft .3s ease-out}.sidebar.mobile.overlay-open.position-right{animation:slideInRight .3s ease-out}.nav-link:focus,.nav-sublink:focus,.toggle-btn:focus,.logo-container:focus,.mobile-toggle-btn:focus{outline:2px solid var(--sidebar-active);outline-offset:2px}.collapsed .nav-submenu{display:none!important}.has-children.collapsed .nav-arrow{display:none}\n"] }]
|
|
777
|
+
args: [{ selector: 'lib-sidebar', imports: [CommonModule, RouterModule], template: "<!-- Overlay para mobile -->\n<div *ngIf=\"currentState.isMobile && currentState.isOverlayOpen\" class=\"sidebar-overlay\" (click)=\"closeOverlay()\">\n</div>\n\n<!-- Sidebar principal -->\n<aside class=\"sidebar\" [class.collapsed]=\"currentState.isCollapsed\" [class.mobile]=\"currentState.isMobile\"\n [class.overlay-open]=\"currentState.isOverlayOpen\" [class.theme-light]=\"finalConfig.theme === 'light'\"\n [class.theme-dark]=\"finalConfig.theme === 'dark'\" [class.position-left]=\"finalConfig.position === 'left'\"\n [class.position-right]=\"finalConfig.position === 'right'\" [ngClass]=\"finalConfig.customCssClass\"\n [style.width]=\"sidebarWidth\">\n\n <!-- Header com logo -->\n <div class=\"sidebar-header\" *ngIf=\"finalConfig.logo.src\">\n <button class=\"logo-container\" (click)=\"onLogoClick()\" [attr.aria-label]=\"finalConfig.logo.alt\">\n <img [src]=\"finalConfig.logo.src\" [alt]=\"finalConfig.logo.alt\" class=\"logo-image\">\n\n <span class=\"logo-text\" *ngIf=\"!currentState.isCollapsed\">\n {{ finalConfig.logo.alt }}\n </span>\n </button>\n\n <!-- Bot\u00E3o de toggle (se habilitado) -->\n <button *ngIf=\"finalConfig.collapsible && !currentState.isMobile\" class=\"toggle-btn\" (click)=\"toggleSidebar()\"\n [attr.aria-label]=\"currentState.isCollapsed ? 'Expandir menu' : 'Recolher menu'\">\n <i class=\"toggle-icon fa\" [class.fa-angle-left]=\"!currentState.isCollapsed\"\n [class.fa-angle-right]=\"currentState.isCollapsed\">\n </i>\n </button>\n </div>\n\n <!-- Navega\u00E7\u00E3o principal -->\n <nav class=\"sidebar-nav\">\n <ul class=\"nav-list\">\n <ng-container *ngFor=\"let item of menuItems; trackBy: trackByItemId\">\n\n <!-- Divisor -->\n <li *ngIf=\"item.divider\" class=\"nav-divider\" role=\"separator\"></li>\n\n <!-- Item do menu -->\n <li class=\"nav-item\" [class.active]=\"isItemActive(item)\"\n [class.has-children]=\"item.children && item.children.length > 0\" [class.expanded]=\"item.isExpanded\"\n [class.disabled]=\"item.disabled\" [class.has-active-child]=\"hasActiveChild(item)\">\n\n <a class=\"nav-link\" [routerLink]=\"item.route\" [class.no-route]=\"!item.route\"\n (click)=\"onItemClick(item, $event)\" [attr.aria-label]=\"item.label\"\n [attr.aria-expanded]=\"item.children ? item.isExpanded : null\" [attr.tabindex]=\"item.disabled ? -1 : 0\">\n\n <!-- \u00CDcone -->\n <i class=\"nav-icon\" [ngClass]=\"item.icon\" [attr.aria-hidden]=\"true\">\n </i>\n\n <!-- Label -->\n <span class=\"nav-label\" *ngIf=\"!currentState.isCollapsed\">\n {{ item.label }}\n </span>\n\n <!-- Badge -->\n <span class=\"nav-badge\" *ngIf=\"item.badge && !currentState.isCollapsed\">\n {{ item.badge }}\n </span>\n\n <!-- Seta para submenu -->\n <i class=\"nav-arrow fa\" *ngIf=\"item.children && item.children.length > 0 && !currentState.isCollapsed\"\n [class.fa-chevron-down]=\"item.isExpanded\" [class.fa-chevron-right]=\"!item.isExpanded\"\n [attr.aria-hidden]=\"true\">\n </i>\n </a>\n\n <!-- Submenu -->\n <ul class=\"nav-submenu\"\n *ngIf=\"item.children && item.children.length > 0 && item.isExpanded && !currentState.isCollapsed\">\n <li class=\"nav-subitem\" *ngFor=\"let subItem of item.children; trackBy: trackByItemId\"\n [class.active]=\"isItemActive(subItem)\" [class.disabled]=\"subItem.disabled\">\n\n <a class=\"nav-sublink\" [routerLink]=\"subItem.route\" [class.no-route]=\"!subItem.route\"\n (click)=\"onItemClick(subItem, $event)\" [attr.aria-label]=\"subItem.label\"\n [attr.tabindex]=\"subItem.disabled ? -1 : 0\">\n\n <!-- \u00CDcone do subitem -->\n <i class=\"nav-subicon\" [ngClass]=\"subItem.icon\" [attr.aria-hidden]=\"true\">\n </i>\n\n <!-- Label do subitem -->\n <span class=\"nav-sublabel\">\n {{ subItem.label }}\n </span>\n\n <!-- Badge do subitem -->\n <span class=\"nav-subbadge\" *ngIf=\"subItem.badge\">\n {{ subItem.badge }}\n </span>\n </a>\n </li>\n </ul>\n </li>\n </ng-container>\n </ul>\n </nav>\n\n <!-- Footer opcional -->\n <div class=\"sidebar-footer\" *ngIf=\"!currentState.isCollapsed\">\n <ng-content select=\"[slot=footer]\"></ng-content>\n </div>\n</aside>\n\n<!-- Bot\u00E3o mobile para abrir sidebar -->\n<button *ngIf=\"currentState.isMobile && !currentState.isOverlayOpen\" class=\"mobile-toggle-btn\" (click)=\"toggleOverlay()\"\n [attr.aria-label]=\"'Abrir menu'\">\n <i class=\"fa fa-bars\" [attr.aria-hidden]=\"true\"></i>\n</button>", styles: [":host{--sidebar-bg: #ffffff;--sidebar-text: #343a40;--sidebar-text-secondary: #495057;--sidebar-border: #dee2e6;--sidebar-hover: #f8f9fa;--sidebar-active: #007bff;--sidebar-active-bg: rgba(0, 123, 255, .1);--sidebar-transition: .3s cubic-bezier(.4, 0, .2, 1);--sidebar-shadow: 0 2px 12px rgba(0, 0, 0, .08)}:host.theme-dark{--sidebar-bg: #343a40;--sidebar-text: #ffffff;--sidebar-text-secondary: #b2b9be;--sidebar-border: #495057;--sidebar-hover: rgba(255, 255, 255, .1);--sidebar-shadow: 0 2px 12px rgba(0, 0, 0, .25)}.sidebar-overlay{position:fixed;inset:0;background:#00000080;z-index:998;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.sidebar{position:fixed;top:0;bottom:0;left:0;width:280px;background:var(--sidebar-bg);border-right:1px solid var(--sidebar-border);box-shadow:var(--sidebar-shadow);transition:var(--sidebar-transition);z-index:999;display:flex;flex-direction:column;overflow:visible}.sidebar.position-right{left:auto;right:0;border-left:1px solid var(--sidebar-border);border-right:none}.sidebar.collapsed{width:64px}.sidebar.collapsed .sidebar-header .logo-text,.sidebar.collapsed .nav-label,.sidebar.collapsed .nav-badge,.sidebar.collapsed .nav-arrow,.sidebar.collapsed .nav-submenu{opacity:0;pointer-events:none}.sidebar.collapsed .nav-link{justify-content:center;padding-left:.5rem;padding-right:.5rem;gap:0}.sidebar.collapsed .nav-icon{margin:0 auto}.sidebar.collapsed .sidebar-header{padding:1rem;justify-content:center!important}.sidebar.collapsed .logo-container{width:100%;display:flex;justify-content:center;align-items:center;gap:0;padding:0;margin:0}.sidebar.collapsed .logo-image{margin:0 auto;display:block;width:32px;height:32px}.sidebar.collapsed .toggle-btn{right:-18px;width:36px;height:36px}.sidebar.mobile{transform:translate(-100%)}.sidebar.mobile.position-right{transform:translate(100%)}.sidebar.mobile.overlay-open{transform:translate(0)}.sidebar-header{padding:1.5rem;border-bottom:1px solid var(--sidebar-border);display:flex;align-items:center;justify-content:space-between;min-height:80px;position:relative}.logo-container{display:flex;align-items:center;gap:1rem;background:none;border:none;padding:0;cursor:pointer;color:inherit;text-decoration:none;transition:var(--sidebar-transition)}.logo-container:hover{opacity:.8}.logo-image{width:32px;height:32px;object-fit:contain;flex-shrink:0}.logo-text{font-family:DM Sans,sans-serif;font-size:1.125rem;font-weight:600;color:var(--sidebar-text);transition:var(--sidebar-transition);white-space:nowrap}.toggle-btn{background:none;border:none;width:32px;height:32px;border-radius:.5rem;display:flex;align-items:center;background:var(--sidebar-bg);border:1px solid rgba(0,0,0,.06);box-shadow:0 6px 14px #0614231f;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);transition:transform .18s var(--sidebar-transition),box-shadow .18s var(--sidebar-transition)}.toggle-btn:hover{transform:translateY(-50%) translateY(-2px);box-shadow:0 10px 20px #06142329}.toggle-btn{position:absolute;top:50%;transform:translateY(-50%);right:-16px;z-index:1000}.toggle-btn:hover{background:var(--sidebar-hover);color:var(--sidebar-text)}.toggle-btn .toggle-icon{font-size:1rem}.sidebar-nav{flex:1;overflow-y:auto;overflow-x:hidden;padding:1rem 0}.sidebar-nav::-webkit-scrollbar{width:4px}.sidebar-nav::-webkit-scrollbar-track{background:transparent}.sidebar-nav::-webkit-scrollbar-thumb{background:var(--sidebar-border);border-radius:2px}.sidebar-nav::-webkit-scrollbar-thumb:hover{background:var(--sidebar-text-secondary)}.nav-list{list-style:none;margin:0;padding:0}.nav-divider{height:1px;background:var(--sidebar-border);margin:1rem 0}.nav-item{position:relative;margin:0 1rem .25rem}.nav-item.active>.nav-link{background:var(--sidebar-active-bg);color:var(--sidebar-active)}.nav-item.active>.nav-link .nav-icon{color:var(--sidebar-active)}.nav-item.has-active-child>.nav-link{color:var(--sidebar-active)}.nav-item.has-active-child>.nav-link .nav-icon{color:var(--sidebar-active)}.nav-item.disabled{opacity:.5;pointer-events:none}.nav-link{display:flex;align-items:center;gap:1rem;padding:1rem;border-radius:.5rem;color:var(--sidebar-text);text-decoration:none;font-family:DM Sans,sans-serif;font-size:.875rem;font-weight:500;line-height:1.5;transition:var(--sidebar-transition);cursor:pointer;position:relative}.nav-link:hover:not(.active){background:var(--sidebar-hover)}.nav-link.no-route{cursor:pointer}.nav-icon{font-size:1.125rem;color:var(--sidebar-text-secondary);flex-shrink:0;width:20px;text-align:center;transition:var(--sidebar-transition)}.nav-label{flex:1;white-space:nowrap;transition:var(--sidebar-transition)}.nav-badge{background:var(--sidebar-active);color:#fff;font-size:.75rem;font-weight:600;padding:2px 6px;border-radius:10px;min-width:18px;text-align:center;transition:var(--sidebar-transition)}.nav-arrow{font-size:.875rem;color:var(--sidebar-text-secondary);transition:var(--sidebar-transition);margin-left:auto}.nav-submenu{list-style:none;margin:.25rem 0 0;padding:0;border-left:2px solid var(--sidebar-border);margin-left:calc(20px + 1rem);transition:var(--sidebar-transition)}.nav-subitem{margin:0 0 .25rem}.nav-subitem.active>.nav-sublink{color:var(--sidebar-active);background:var(--sidebar-active-bg)}.nav-subitem.active>.nav-sublink .nav-subicon{color:var(--sidebar-active)}.nav-subitem.disabled{opacity:.5;pointer-events:none}.nav-subicon{font-size:.875rem;width:16px;text-align:center;flex-shrink:0;transition:var(--sidebar-transition)}.nav-sublabel{flex:1;white-space:nowrap}.nav-subbadge{background:var(--sidebar-active);color:#fff;font-size:10px;font-weight:600;padding:1px 4px;border-radius:8px;min-width:14px;text-align:center}.sidebar-footer{padding:1rem;border-top:1px solid var(--sidebar-border);margin-top:auto}.mobile-toggle-btn{position:fixed;top:1.5rem;left:1.5rem;width:48px;height:48px;background:var(--sidebar-active);color:#fff;border:none;border-radius:.75rem;display:flex;align-items:center;justify-content:center;font-size:1.125rem;box-shadow:var(--sidebar-shadow);z-index:997;cursor:pointer;transition:var(--sidebar-transition)}.mobile-toggle-btn:hover{transform:scale(1.05)}.mobile-toggle-btn:active{transform:scale(.95)}@media(max-width:768px){.sidebar{width:280px!important}.sidebar.position-right{transform:translate(100%)}.sidebar.position-right.overlay-open{transform:translate(0)}}@keyframes slideInLeft{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes slideInRight{0%{transform:translate(100%)}to{transform:translate(0)}}.sidebar.mobile.overlay-open{animation:slideInLeft .3s ease-out}.sidebar.mobile.overlay-open.position-right{animation:slideInRight .3s ease-out}.nav-link:focus,.nav-sublink:focus,.toggle-btn:focus,.logo-container:focus,.mobile-toggle-btn:focus{outline:2px solid var(--sidebar-active);outline-offset:2px}.collapsed .nav-submenu{display:none!important}.has-children.collapsed .nav-arrow{display:none}\n"] }]
|
|
778
778
|
}], propDecorators: { config: [{
|
|
779
779
|
type: Input
|
|
780
780
|
}], menuItems: [{
|
|
@@ -1260,10 +1260,10 @@ class LocalStorageService {
|
|
|
1260
1260
|
return true;
|
|
1261
1261
|
}
|
|
1262
1262
|
lastEventTime = 0;
|
|
1263
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1264
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1263
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: LocalStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1264
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: LocalStorageService, providedIn: 'root' });
|
|
1265
1265
|
}
|
|
1266
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1266
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: LocalStorageService, decorators: [{
|
|
1267
1267
|
type: Injectable,
|
|
1268
1268
|
args: [{
|
|
1269
1269
|
providedIn: 'root'
|
|
@@ -1483,10 +1483,10 @@ class AuthStorageService {
|
|
|
1483
1483
|
return null;
|
|
1484
1484
|
}
|
|
1485
1485
|
}
|
|
1486
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1487
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1486
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AuthStorageService, deps: [{ token: LocalStorageService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1487
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AuthStorageService, providedIn: 'root' });
|
|
1488
1488
|
}
|
|
1489
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1489
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AuthStorageService, decorators: [{
|
|
1490
1490
|
type: Injectable,
|
|
1491
1491
|
args: [{
|
|
1492
1492
|
providedIn: 'root'
|
|
@@ -1873,10 +1873,10 @@ class LoginService {
|
|
|
1873
1873
|
message: 'Email ou senha incorretos'
|
|
1874
1874
|
};
|
|
1875
1875
|
}
|
|
1876
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1877
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1876
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: LoginService, deps: [{ token: AuthStorageService }, { token: AUTH_PROVIDER, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1877
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: LoginService, providedIn: 'root' });
|
|
1878
1878
|
}
|
|
1879
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1879
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: LoginService, decorators: [{
|
|
1880
1880
|
type: Injectable,
|
|
1881
1881
|
args: [{
|
|
1882
1882
|
providedIn: 'root'
|
|
@@ -2108,12 +2108,12 @@ class LoginComponent {
|
|
|
2108
2108
|
// Implementação específica da aplicação
|
|
2109
2109
|
console.log('Create account clicked');
|
|
2110
2110
|
}
|
|
2111
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2112
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: LoginComponent, isStandalone: true, selector: "lib-login", inputs: { options: "options", showHeader: "showHeader", showFooter: "showFooter", logoUrl: "logoUrl", backgroundImageUrl: "backgroundImageUrl", customCssClass: "customCssClass" }, outputs: { loginSuccess: "loginSuccess", loginError: "loginError", formChange: "formChange" }, ngImport: i0, template: "<!-- Container principal do login -->\n<div class=\"login-container\" [ngClass]=\"customCssClass\"\n [style.background-image]=\"options.backgroundUrl ? 'url(' + options.backgroundUrl + ')' : null\">\n\n <!-- Card de login -->\n <div class=\"login-card\">\n\n <!-- Header -->\n <div class=\"login-header\">\n <img *ngIf=\"options.logoUrl\" [src]=\"options.logoUrl\" alt=\"Logo\" class=\"login-logo\">\n\n <h1 class=\"login-title\">{{ options.title || 'Entrar' }}</h1>\n <p class=\"login-subtitle\">{{ options.subtitle || 'Acesse sua conta' }}</p>\n </div>\n\n <!-- Indicador de loading -->\n <div *ngIf=\"isLoading$ | async\" class=\"loading-overlay\">\n <div class=\"loading-spinner\"></div>\n <span class=\"loading-text\">Entrando...</span>\n </div>\n\n <!-- Estado de bloqueio removido conforme solicita\u00E7\u00E3o -->\n\n <!-- Formul\u00E1rio de login -->\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"onSubmit()\" class=\"login-form\"\n [class.disabled]=\"(isLoading$ | async)\">\n\n <!-- Campo Email -->\n <div class=\"form-group\">\n <label for=\"email\" class=\"form-label\">\n Email <span class=\"required\">*</span>\n </label>\n\n <div class=\"input-wrapper\">\n <input id=\"email\" type=\"email\" formControlName=\"email\" class=\"form-input\"\n [class.error]=\"hasFieldError('email', 'required') || hasFieldError('email', 'email')\"\n placeholder=\"Digite seu email\" autocomplete=\"email\" autocapitalize=\"off\">\n\n <i class=\"input-icon icon-email\"></i>\n </div>\n\n <!-- Erro do campo email -->\n <div *ngIf=\"getFieldErrorMessage('email')\" class=\"field-error\">\n {{ getFieldErrorMessage('email') }}\n </div>\n </div>\n\n <!-- Campo Senha -->\n <div class=\"form-group\">\n <label for=\"password\" class=\"form-label\">\n Senha <span class=\"required\">*</span>\n </label>\n\n <div class=\"input-wrapper\">\n <input id=\"password\" [type]=\"showPassword ? 'text' : 'password'\" formControlName=\"password\"\n class=\"form-input\"\n [class.error]=\"hasFieldError('password', 'required') || hasFieldError('password', 'minlength')\"\n placeholder=\"Digite sua senha\" autocomplete=\"current-password\">\n\n <button type=\"button\" class=\"password-toggle\" (click)=\"togglePasswordVisibility()\"\n [attr.aria-label]=\"showPassword ? 'Ocultar senha' : 'Mostrar senha'\">\n <i [class]=\"showPassword ? 'icon-eye-off' : 'icon-eye'\"></i>\n </button>\n </div>\n\n <!-- Erro do campo senha -->\n <div *ngIf=\"getFieldErrorMessage('password')\" class=\"field-error\">\n {{ getFieldErrorMessage('password') }}\n </div>\n </div>\n\n <!-- Checkbox removido conforme solicita\u00E7\u00E3o -->\n\n <!-- Erros gerais -->\n <div *ngIf=\"(errors$ | async)?.general\" class=\"alert alert-error\">\n <i class=\"icon-error\"></i>\n <div>\n <div *ngFor=\"let error of (errors$ | async)?.general\">\n {{ error }}\n </div>\n </div>\n </div>\n\n <!-- Bot\u00E3o de submit -->\n <button type=\"submit\" class=\"login-button\" [disabled]=\"loginForm.invalid || (isLoading$ | async)\">\n\n <span *ngIf=\"!(isLoading$ | async)\">Entrar</span>\n <span *ngIf=\"isLoading$ | async\" class=\"loading-content\">\n <i class=\"icon-spinner spin\"></i>\n Entrando...\n </span>\n </button>\n\n <!-- Contador de tentativas removido conforme solicita\u00E7\u00E3o -->\n </form>\n\n <!-- Links adicionais -->\n <div class=\"login-links\">\n <a href=\"#\" (click)=\"onForgotPassword(); $event.preventDefault()\" class=\"link\">\n Esqueci minha senha\n </a>\n\n <span class=\"separator\">\u2022</span>\n\n <a href=\"#\" (click)=\"onCreateAccount(); $event.preventDefault()\" class=\"link\">\n Criar conta\n </a>\n </div>\n\n <!-- Se\u00E7\u00E3o de demonstra\u00E7\u00E3o removida conforme solicita\u00E7\u00E3o -->\n\n <!-- Footer -->\n <div *ngIf=\"options.footerText\" class=\"login-footer\">\n <p class=\"footer-text\">\n {{ options.footerText }}\n </p>\n </div>\n </div>\n</div>", styles: ["@charset \"UTF-8\";:host{--login-primary-color: #007bff;--login-primary-hover: #0056b3;--login-secondary-color: #6c757d;--login-background: #f8f9fa;--login-card-background: #ffffff;--login-border-color: #dee2e6;--login-text-color: #343a40;--login-error-color: #dc3545;--login-success-color: #28a745;--login-warning-color: #ffc107;--login-shadow: 0 10px 25px rgba(0, 0, 0, .1);--login-border-radius: .75rem;--login-transition: all .3s ease}.login-container{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:1rem;background:var(--login-background);background-size:cover;background-position:center;background-repeat:no-repeat;position:relative;font-family:DM Sans,sans-serif}.login-container:before{content:\"\";position:absolute;inset:0;background:#0000004d;z-index:1;opacity:0;transition:opacity .3s ease}.login-container[style*=background-image]:before{opacity:1}.login-card{background:var(--login-card-background);border-radius:var(--login-border-radius);box-shadow:var(--login-shadow);padding:2rem;width:100%;max-width:420px;position:relative;border:1px solid var(--login-border-color);z-index:2}@media (max-width: 480px){.login-card{padding:1.5rem;margin:.5rem}}.login-header{text-align:center;margin-bottom:2rem}.login-header .login-logo{max-width:80px;height:auto;margin-bottom:1rem}.login-header .login-title{font-family:DM Sans,sans-serif;font-size:1.75rem;font-weight:700;color:var(--login-text-color);margin:0 0 .5rem;line-height:1.2}.login-header .login-subtitle{font-size:.875rem;color:var(--login-secondary-color);margin:0;font-weight:400}.loading-overlay{position:absolute;inset:0;background:#fffffff2;display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:var(--login-border-radius);z-index:10}.loading-overlay .loading-spinner{width:40px;height:40px;border:3px solid var(--login-border-color);border-top:3px solid var(--login-primary-color);border-radius:50%;animation:spin 1s linear infinite;margin-bottom:1rem}.loading-overlay .loading-text{color:var(--login-secondary-color);font-size:.9rem;font-weight:500}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.login-form.disabled{pointer-events:none;opacity:.7}.form-group{margin-bottom:1.5rem}.form-label{display:block;font-family:DM Sans,sans-serif;font-size:.875rem;font-weight:600;color:var(--login-text-color);margin-bottom:.5rem;line-height:2.5}.form-label .required{color:var(--login-error-color);margin-left:.25rem}.input-wrapper{position:relative;display:flex;align-items:center}.form-input{font-family:DM Sans,sans-serif;font-weight:400;font-size:.875rem;border:1px solid var(--login-border-color);border-radius:.25rem;display:block;width:100%;padding:.375rem 2.75rem .375rem .75rem;line-height:1.5;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#fff;background-clip:padding-box;color:var(--login-text-color);transition:var(--login-transition);outline:none}.form-input::placeholder{color:#6c757d}.form-input:focus{border-color:#b2b9be;box-shadow:none}.form-input:focus.error{border-color:var(--login-error-color)}.form-input.error{border-color:var(--login-error-color)}.form-input:disabled{background:#f8f9fa;color:#6c757d;cursor:not-allowed}.input-icon{position:absolute;right:1rem;color:var(--login-secondary-color);font-size:1.1rem;pointer-events:none}.password-toggle{position:absolute;right:.75rem;background:none;border:none;padding:.25rem;cursor:pointer;color:var(--login-secondary-color);transition:var(--login-transition);border-radius:4px}.password-toggle:hover{color:var(--login-primary-color);background:#3b82f61a}.password-toggle:focus{outline:none;box-shadow:0 0 0 2px #3b82f64d}.field-error{margin-top:.5rem;font-size:.75rem;color:var(--login-error-color);font-family:DM Sans,sans-serif}.field-error:before{content:\"\\26a0 \";font-size:.75rem}.alert{padding:1rem;border-radius:8px;margin-bottom:1rem;display:flex;align-items:flex-start;gap:.75rem;font-size:.9rem}.alert.alert-error{background:#fef2f2;border:1px solid #fecaca;color:#991b1b}.alert.alert-error i{color:var(--login-error-color);font-size:1.1rem;margin-top:.1rem}.alert.alert-warning{background:#fffbeb;border:1px solid #fed7aa;color:#92400e}.alert.alert-warning i{color:var(--login-warning-color);font-size:1.1rem;margin-top:.1rem}.lockout-message{margin-bottom:1.5rem}.lockout-message strong{display:block;margin-bottom:.5rem}.lockout-message p{margin:.25rem 0}.login-button{width:100%;padding:.375rem .75rem;background:var(--login-primary-color);color:#fff;border:none;border-radius:.25rem;font-family:DM Sans,sans-serif;font-size:.875rem;font-weight:600;cursor:pointer;transition:var(--login-transition);position:relative;display:flex;align-items:center;justify-content:center;gap:.5rem;line-height:1.5}.login-button:hover:not(:disabled){background:var(--login-primary-hover)}.login-button:focus{outline:none;box-shadow:0 0 0 .2rem #007bff40}.login-button:disabled{background:#6c757d;cursor:not-allowed}.login-button .loading-content{display:flex;align-items:center;gap:.5rem}.login-button .icon-spinner{animation:spin 1s linear infinite}.login-links{margin-top:1.5rem;text-align:center;display:flex;align-items:center;justify-content:center;gap:.75rem;flex-wrap:wrap}.login-links .link{color:var(--login-primary-color);text-decoration:none;font-size:.875rem;font-weight:500;transition:var(--login-transition)}.login-links .link:hover{color:var(--login-primary-hover);text-decoration:underline}.login-links .link:focus{outline:2px solid var(--login-primary-color);outline-offset:2px;border-radius:4px}.login-links .separator{color:var(--login-secondary-color);font-size:.875rem}.login-footer{margin-top:2rem;padding-top:1.5rem;border-top:1px solid var(--login-border-color);text-align:center}.login-footer .footer-text{font-family:DM Sans,sans-serif;font-size:.75rem;color:var(--login-secondary-color);margin:0;font-weight:400}@media (max-width: 640px){.login-container{padding:.5rem}.login-card{padding:1.5rem}.login-header .login-title{font-size:1.5rem}.demo-buttons{grid-template-columns:1fr}.login-links{flex-direction:column;gap:.5rem}.login-links .separator{display:none}}@media (max-width: 480px){.form-input{padding:.75rem;font-size:.9rem}.login-button{padding:.8rem;font-size:.9rem}}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.login-card{animation:fadeIn .5s ease-out}@media (prefers-color-scheme: dark){:host{--login-background: #0f172a;--login-card-background: #1e293b;--login-border-color: #334155;--login-text-color: #f1f5f9;--login-secondary-color: #94a3b8}}@media (prefers-contrast: high){:host{--login-border-color: #000000;--login-text-color: #000000;--login-background: #ffffff}.form-input:focus{border-width:3px}}@media (prefers-reduced-motion: reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@media print{.login-container{min-height:auto;background:#fff}.demo-section,.loading-overlay{display:none}}\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: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
|
|
2111
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: LoginComponent, deps: [{ token: LoginService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2112
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: LoginComponent, isStandalone: true, selector: "lib-login", inputs: { options: "options", showHeader: "showHeader", showFooter: "showFooter", logoUrl: "logoUrl", backgroundImageUrl: "backgroundImageUrl", customCssClass: "customCssClass" }, outputs: { loginSuccess: "loginSuccess", loginError: "loginError", formChange: "formChange" }, ngImport: i0, template: "<!-- Container principal do login -->\n<div class=\"login-container\" [ngClass]=\"customCssClass\"\n [style.background-image]=\"options.backgroundUrl ? 'url(' + options.backgroundUrl + ')' : null\">\n\n <!-- Card de login -->\n <div class=\"login-card\">\n\n <!-- Header -->\n <div class=\"login-header\">\n <img *ngIf=\"options.logoUrl\" [src]=\"options.logoUrl\" alt=\"Logo\" class=\"login-logo\">\n\n <h1 class=\"login-title\">{{ options.title || 'Entrar' }}</h1>\n <p class=\"login-subtitle\">{{ options.subtitle || 'Acesse sua conta' }}</p>\n </div>\n\n <!-- Indicador de loading -->\n <div *ngIf=\"isLoading$ | async\" class=\"loading-overlay\">\n <div class=\"loading-spinner\"></div>\n <span class=\"loading-text\">Entrando...</span>\n </div>\n\n <!-- Estado de bloqueio removido conforme solicita\u00E7\u00E3o -->\n\n <!-- Formul\u00E1rio de login -->\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"onSubmit()\" class=\"login-form\"\n [class.disabled]=\"(isLoading$ | async)\">\n\n <!-- Campo Email -->\n <div class=\"form-group\">\n <label for=\"email\" class=\"form-label\">\n Email <span class=\"required\">*</span>\n </label>\n\n <div class=\"input-wrapper\">\n <input id=\"email\" type=\"email\" formControlName=\"email\" class=\"form-input\"\n [class.error]=\"hasFieldError('email', 'required') || hasFieldError('email', 'email')\"\n placeholder=\"Digite seu email\" autocomplete=\"email\" autocapitalize=\"off\">\n\n <i class=\"input-icon icon-email\"></i>\n </div>\n\n <!-- Erro do campo email -->\n <div *ngIf=\"getFieldErrorMessage('email')\" class=\"field-error\">\n {{ getFieldErrorMessage('email') }}\n </div>\n </div>\n\n <!-- Campo Senha -->\n <div class=\"form-group\">\n <label for=\"password\" class=\"form-label\">\n Senha <span class=\"required\">*</span>\n </label>\n\n <div class=\"input-wrapper\">\n <input id=\"password\" [type]=\"showPassword ? 'text' : 'password'\" formControlName=\"password\"\n class=\"form-input\"\n [class.error]=\"hasFieldError('password', 'required') || hasFieldError('password', 'minlength')\"\n placeholder=\"Digite sua senha\" autocomplete=\"current-password\">\n\n <button type=\"button\" class=\"password-toggle\" (click)=\"togglePasswordVisibility()\"\n [attr.aria-label]=\"showPassword ? 'Ocultar senha' : 'Mostrar senha'\">\n <i [class]=\"showPassword ? 'icon-eye-off' : 'icon-eye'\"></i>\n </button>\n </div>\n\n <!-- Erro do campo senha -->\n <div *ngIf=\"getFieldErrorMessage('password')\" class=\"field-error\">\n {{ getFieldErrorMessage('password') }}\n </div>\n </div>\n\n <!-- Checkbox removido conforme solicita\u00E7\u00E3o -->\n\n <!-- Erros gerais -->\n <div *ngIf=\"(errors$ | async)?.general\" class=\"alert alert-error\">\n <i class=\"icon-error\"></i>\n <div>\n <div *ngFor=\"let error of (errors$ | async)?.general\">\n {{ error }}\n </div>\n </div>\n </div>\n\n <!-- Bot\u00E3o de submit -->\n <button type=\"submit\" class=\"login-button\" [disabled]=\"loginForm.invalid || (isLoading$ | async)\">\n\n <span *ngIf=\"!(isLoading$ | async)\">Entrar</span>\n <span *ngIf=\"isLoading$ | async\" class=\"loading-content\">\n <i class=\"icon-spinner spin\"></i>\n Entrando...\n </span>\n </button>\n\n <!-- Contador de tentativas removido conforme solicita\u00E7\u00E3o -->\n </form>\n\n <!-- Links adicionais -->\n <div class=\"login-links\">\n <a href=\"#\" (click)=\"onForgotPassword(); $event.preventDefault()\" class=\"link\">\n Esqueci minha senha\n </a>\n\n <span class=\"separator\">\u2022</span>\n\n <a href=\"#\" (click)=\"onCreateAccount(); $event.preventDefault()\" class=\"link\">\n Criar conta\n </a>\n </div>\n\n <!-- Se\u00E7\u00E3o de demonstra\u00E7\u00E3o removida conforme solicita\u00E7\u00E3o -->\n\n <!-- Footer -->\n <div *ngIf=\"options.footerText\" class=\"login-footer\">\n <p class=\"footer-text\">\n {{ options.footerText }}\n </p>\n </div>\n </div>\n</div>", styles: ["@charset \"UTF-8\";:host{--login-primary-color: #007bff;--login-primary-hover: #0056b3;--login-secondary-color: #6c757d;--login-background: #f8f9fa;--login-card-background: #ffffff;--login-border-color: #dee2e6;--login-text-color: #343a40;--login-error-color: #dc3545;--login-success-color: #28a745;--login-warning-color: #ffc107;--login-shadow: 0 10px 25px rgba(0, 0, 0, .1);--login-border-radius: .75rem;--login-transition: all .3s ease}.login-container{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:1rem;background:var(--login-background);background-size:cover;background-position:center;background-repeat:no-repeat;position:relative;font-family:DM Sans,sans-serif}.login-container:before{content:\"\";position:absolute;inset:0;background:#0000004d;z-index:1;opacity:0;transition:opacity .3s ease}.login-container[style*=background-image]:before{opacity:1}.login-card{background:var(--login-card-background);border-radius:var(--login-border-radius);box-shadow:var(--login-shadow);padding:2rem;width:100%;max-width:420px;position:relative;border:1px solid var(--login-border-color);z-index:2}@media(max-width:480px){.login-card{padding:1.5rem;margin:.5rem}}.login-header{text-align:center;margin-bottom:2rem}.login-header .login-logo{max-width:80px;height:auto;margin-bottom:1rem}.login-header .login-title{font-family:DM Sans,sans-serif;font-size:1.75rem;font-weight:700;color:var(--login-text-color);margin:0 0 .5rem;line-height:1.2}.login-header .login-subtitle{font-size:.875rem;color:var(--login-secondary-color);margin:0;font-weight:400}.loading-overlay{position:absolute;inset:0;background:#fffffff2;display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:var(--login-border-radius);z-index:10}.loading-overlay .loading-spinner{width:40px;height:40px;border:3px solid var(--login-border-color);border-top:3px solid var(--login-primary-color);border-radius:50%;animation:spin 1s linear infinite;margin-bottom:1rem}.loading-overlay .loading-text{color:var(--login-secondary-color);font-size:.9rem;font-weight:500}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.login-form.disabled{pointer-events:none;opacity:.7}.form-group{margin-bottom:1.5rem}.form-label{display:block;font-family:DM Sans,sans-serif;font-size:.875rem;font-weight:600;color:var(--login-text-color);margin-bottom:.5rem;line-height:2.5}.form-label .required{color:var(--login-error-color);margin-left:.25rem}.input-wrapper{position:relative;display:flex;align-items:center}.form-input{font-family:DM Sans,sans-serif;font-weight:400;font-size:.875rem;border:1px solid var(--login-border-color);border-radius:.25rem;display:block;width:100%;padding:.375rem 2.75rem .375rem .75rem;line-height:1.5;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#fff;background-clip:padding-box;color:var(--login-text-color);transition:var(--login-transition);outline:none}.form-input::placeholder{color:#6c757d}.form-input:focus{border-color:#b2b9be;box-shadow:none}.form-input:focus.error{border-color:var(--login-error-color)}.form-input.error{border-color:var(--login-error-color)}.form-input:disabled{background:#f8f9fa;color:#6c757d;cursor:not-allowed}.input-icon{position:absolute;right:1rem;color:var(--login-secondary-color);font-size:1.1rem;pointer-events:none}.password-toggle{position:absolute;right:.75rem;background:none;border:none;padding:.25rem;cursor:pointer;color:var(--login-secondary-color);transition:var(--login-transition);border-radius:4px}.password-toggle:hover{color:var(--login-primary-color);background:#3b82f61a}.password-toggle:focus{outline:none;box-shadow:0 0 0 2px #3b82f64d}.field-error{margin-top:.5rem;font-size:.75rem;color:var(--login-error-color);font-family:DM Sans,sans-serif}.field-error:before{content:\"\\26a0 \";font-size:.75rem}.alert{padding:1rem;border-radius:8px;margin-bottom:1rem;display:flex;align-items:flex-start;gap:.75rem;font-size:.9rem}.alert.alert-error{background:#fef2f2;border:1px solid #fecaca;color:#991b1b}.alert.alert-error i{color:var(--login-error-color);font-size:1.1rem;margin-top:.1rem}.alert.alert-warning{background:#fffbeb;border:1px solid #fed7aa;color:#92400e}.alert.alert-warning i{color:var(--login-warning-color);font-size:1.1rem;margin-top:.1rem}.lockout-message{margin-bottom:1.5rem}.lockout-message strong{display:block;margin-bottom:.5rem}.lockout-message p{margin:.25rem 0}.login-button{width:100%;padding:.375rem .75rem;background:var(--login-primary-color);color:#fff;border:none;border-radius:.25rem;font-family:DM Sans,sans-serif;font-size:.875rem;font-weight:600;cursor:pointer;transition:var(--login-transition);position:relative;display:flex;align-items:center;justify-content:center;gap:.5rem;line-height:1.5}.login-button:hover:not(:disabled){background:var(--login-primary-hover)}.login-button:focus{outline:none;box-shadow:0 0 0 .2rem #007bff40}.login-button:disabled{background:#6c757d;cursor:not-allowed}.login-button .loading-content{display:flex;align-items:center;gap:.5rem}.login-button .icon-spinner{animation:spin 1s linear infinite}.login-links{margin-top:1.5rem;text-align:center;display:flex;align-items:center;justify-content:center;gap:.75rem;flex-wrap:wrap}.login-links .link{color:var(--login-primary-color);text-decoration:none;font-size:.875rem;font-weight:500;transition:var(--login-transition)}.login-links .link:hover{color:var(--login-primary-hover);text-decoration:underline}.login-links .link:focus{outline:2px solid var(--login-primary-color);outline-offset:2px;border-radius:4px}.login-links .separator{color:var(--login-secondary-color);font-size:.875rem}.login-footer{margin-top:2rem;padding-top:1.5rem;border-top:1px solid var(--login-border-color);text-align:center}.login-footer .footer-text{font-family:DM Sans,sans-serif;font-size:.75rem;color:var(--login-secondary-color);margin:0;font-weight:400}@media(max-width:640px){.login-container{padding:.5rem}.login-card{padding:1.5rem}.login-header .login-title{font-size:1.5rem}.demo-buttons{grid-template-columns:1fr}.login-links{flex-direction:column;gap:.5rem}.login-links .separator{display:none}}@media(max-width:480px){.form-input{padding:.75rem;font-size:.9rem}.login-button{padding:.8rem;font-size:.9rem}}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.login-card{animation:fadeIn .5s ease-out}@media(prefers-color-scheme:dark){:host{--login-background: #0f172a;--login-card-background: #1e293b;--login-border-color: #334155;--login-text-color: #f1f5f9;--login-secondary-color: #94a3b8}}@media(prefers-contrast:high){:host{--login-border-color: #000000;--login-text-color: #000000;--login-background: #ffffff}.form-input:focus{border-width:3px}}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@media print{.login-container{min-height:auto;background:#fff}.demo-section,.loading-overlay{display:none}}\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: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
|
|
2113
2113
|
}
|
|
2114
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2114
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: LoginComponent, decorators: [{
|
|
2115
2115
|
type: Component,
|
|
2116
|
-
args: [{ selector: 'lib-login', standalone: true, imports: [CommonModule, ReactiveFormsModule], template: "<!-- Container principal do login -->\n<div class=\"login-container\" [ngClass]=\"customCssClass\"\n [style.background-image]=\"options.backgroundUrl ? 'url(' + options.backgroundUrl + ')' : null\">\n\n <!-- Card de login -->\n <div class=\"login-card\">\n\n <!-- Header -->\n <div class=\"login-header\">\n <img *ngIf=\"options.logoUrl\" [src]=\"options.logoUrl\" alt=\"Logo\" class=\"login-logo\">\n\n <h1 class=\"login-title\">{{ options.title || 'Entrar' }}</h1>\n <p class=\"login-subtitle\">{{ options.subtitle || 'Acesse sua conta' }}</p>\n </div>\n\n <!-- Indicador de loading -->\n <div *ngIf=\"isLoading$ | async\" class=\"loading-overlay\">\n <div class=\"loading-spinner\"></div>\n <span class=\"loading-text\">Entrando...</span>\n </div>\n\n <!-- Estado de bloqueio removido conforme solicita\u00E7\u00E3o -->\n\n <!-- Formul\u00E1rio de login -->\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"onSubmit()\" class=\"login-form\"\n [class.disabled]=\"(isLoading$ | async)\">\n\n <!-- Campo Email -->\n <div class=\"form-group\">\n <label for=\"email\" class=\"form-label\">\n Email <span class=\"required\">*</span>\n </label>\n\n <div class=\"input-wrapper\">\n <input id=\"email\" type=\"email\" formControlName=\"email\" class=\"form-input\"\n [class.error]=\"hasFieldError('email', 'required') || hasFieldError('email', 'email')\"\n placeholder=\"Digite seu email\" autocomplete=\"email\" autocapitalize=\"off\">\n\n <i class=\"input-icon icon-email\"></i>\n </div>\n\n <!-- Erro do campo email -->\n <div *ngIf=\"getFieldErrorMessage('email')\" class=\"field-error\">\n {{ getFieldErrorMessage('email') }}\n </div>\n </div>\n\n <!-- Campo Senha -->\n <div class=\"form-group\">\n <label for=\"password\" class=\"form-label\">\n Senha <span class=\"required\">*</span>\n </label>\n\n <div class=\"input-wrapper\">\n <input id=\"password\" [type]=\"showPassword ? 'text' : 'password'\" formControlName=\"password\"\n class=\"form-input\"\n [class.error]=\"hasFieldError('password', 'required') || hasFieldError('password', 'minlength')\"\n placeholder=\"Digite sua senha\" autocomplete=\"current-password\">\n\n <button type=\"button\" class=\"password-toggle\" (click)=\"togglePasswordVisibility()\"\n [attr.aria-label]=\"showPassword ? 'Ocultar senha' : 'Mostrar senha'\">\n <i [class]=\"showPassword ? 'icon-eye-off' : 'icon-eye'\"></i>\n </button>\n </div>\n\n <!-- Erro do campo senha -->\n <div *ngIf=\"getFieldErrorMessage('password')\" class=\"field-error\">\n {{ getFieldErrorMessage('password') }}\n </div>\n </div>\n\n <!-- Checkbox removido conforme solicita\u00E7\u00E3o -->\n\n <!-- Erros gerais -->\n <div *ngIf=\"(errors$ | async)?.general\" class=\"alert alert-error\">\n <i class=\"icon-error\"></i>\n <div>\n <div *ngFor=\"let error of (errors$ | async)?.general\">\n {{ error }}\n </div>\n </div>\n </div>\n\n <!-- Bot\u00E3o de submit -->\n <button type=\"submit\" class=\"login-button\" [disabled]=\"loginForm.invalid || (isLoading$ | async)\">\n\n <span *ngIf=\"!(isLoading$ | async)\">Entrar</span>\n <span *ngIf=\"isLoading$ | async\" class=\"loading-content\">\n <i class=\"icon-spinner spin\"></i>\n Entrando...\n </span>\n </button>\n\n <!-- Contador de tentativas removido conforme solicita\u00E7\u00E3o -->\n </form>\n\n <!-- Links adicionais -->\n <div class=\"login-links\">\n <a href=\"#\" (click)=\"onForgotPassword(); $event.preventDefault()\" class=\"link\">\n Esqueci minha senha\n </a>\n\n <span class=\"separator\">\u2022</span>\n\n <a href=\"#\" (click)=\"onCreateAccount(); $event.preventDefault()\" class=\"link\">\n Criar conta\n </a>\n </div>\n\n <!-- Se\u00E7\u00E3o de demonstra\u00E7\u00E3o removida conforme solicita\u00E7\u00E3o -->\n\n <!-- Footer -->\n <div *ngIf=\"options.footerText\" class=\"login-footer\">\n <p class=\"footer-text\">\n {{ options.footerText }}\n </p>\n </div>\n </div>\n</div>", styles: ["@charset \"UTF-8\";:host{--login-primary-color: #007bff;--login-primary-hover: #0056b3;--login-secondary-color: #6c757d;--login-background: #f8f9fa;--login-card-background: #ffffff;--login-border-color: #dee2e6;--login-text-color: #343a40;--login-error-color: #dc3545;--login-success-color: #28a745;--login-warning-color: #ffc107;--login-shadow: 0 10px 25px rgba(0, 0, 0, .1);--login-border-radius: .75rem;--login-transition: all .3s ease}.login-container{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:1rem;background:var(--login-background);background-size:cover;background-position:center;background-repeat:no-repeat;position:relative;font-family:DM Sans,sans-serif}.login-container:before{content:\"\";position:absolute;inset:0;background:#0000004d;z-index:1;opacity:0;transition:opacity .3s ease}.login-container[style*=background-image]:before{opacity:1}.login-card{background:var(--login-card-background);border-radius:var(--login-border-radius);box-shadow:var(--login-shadow);padding:2rem;width:100%;max-width:420px;position:relative;border:1px solid var(--login-border-color);z-index:2}@media (max-width: 480px){.login-card{padding:1.5rem;margin:.5rem}}.login-header{text-align:center;margin-bottom:2rem}.login-header .login-logo{max-width:80px;height:auto;margin-bottom:1rem}.login-header .login-title{font-family:DM Sans,sans-serif;font-size:1.75rem;font-weight:700;color:var(--login-text-color);margin:0 0 .5rem;line-height:1.2}.login-header .login-subtitle{font-size:.875rem;color:var(--login-secondary-color);margin:0;font-weight:400}.loading-overlay{position:absolute;inset:0;background:#fffffff2;display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:var(--login-border-radius);z-index:10}.loading-overlay .loading-spinner{width:40px;height:40px;border:3px solid var(--login-border-color);border-top:3px solid var(--login-primary-color);border-radius:50%;animation:spin 1s linear infinite;margin-bottom:1rem}.loading-overlay .loading-text{color:var(--login-secondary-color);font-size:.9rem;font-weight:500}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.login-form.disabled{pointer-events:none;opacity:.7}.form-group{margin-bottom:1.5rem}.form-label{display:block;font-family:DM Sans,sans-serif;font-size:.875rem;font-weight:600;color:var(--login-text-color);margin-bottom:.5rem;line-height:2.5}.form-label .required{color:var(--login-error-color);margin-left:.25rem}.input-wrapper{position:relative;display:flex;align-items:center}.form-input{font-family:DM Sans,sans-serif;font-weight:400;font-size:.875rem;border:1px solid var(--login-border-color);border-radius:.25rem;display:block;width:100%;padding:.375rem 2.75rem .375rem .75rem;line-height:1.5;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#fff;background-clip:padding-box;color:var(--login-text-color);transition:var(--login-transition);outline:none}.form-input::placeholder{color:#6c757d}.form-input:focus{border-color:#b2b9be;box-shadow:none}.form-input:focus.error{border-color:var(--login-error-color)}.form-input.error{border-color:var(--login-error-color)}.form-input:disabled{background:#f8f9fa;color:#6c757d;cursor:not-allowed}.input-icon{position:absolute;right:1rem;color:var(--login-secondary-color);font-size:1.1rem;pointer-events:none}.password-toggle{position:absolute;right:.75rem;background:none;border:none;padding:.25rem;cursor:pointer;color:var(--login-secondary-color);transition:var(--login-transition);border-radius:4px}.password-toggle:hover{color:var(--login-primary-color);background:#3b82f61a}.password-toggle:focus{outline:none;box-shadow:0 0 0 2px #3b82f64d}.field-error{margin-top:.5rem;font-size:.75rem;color:var(--login-error-color);font-family:DM Sans,sans-serif}.field-error:before{content:\"\\26a0 \";font-size:.75rem}.alert{padding:1rem;border-radius:8px;margin-bottom:1rem;display:flex;align-items:flex-start;gap:.75rem;font-size:.9rem}.alert.alert-error{background:#fef2f2;border:1px solid #fecaca;color:#991b1b}.alert.alert-error i{color:var(--login-error-color);font-size:1.1rem;margin-top:.1rem}.alert.alert-warning{background:#fffbeb;border:1px solid #fed7aa;color:#92400e}.alert.alert-warning i{color:var(--login-warning-color);font-size:1.1rem;margin-top:.1rem}.lockout-message{margin-bottom:1.5rem}.lockout-message strong{display:block;margin-bottom:.5rem}.lockout-message p{margin:.25rem 0}.login-button{width:100%;padding:.375rem .75rem;background:var(--login-primary-color);color:#fff;border:none;border-radius:.25rem;font-family:DM Sans,sans-serif;font-size:.875rem;font-weight:600;cursor:pointer;transition:var(--login-transition);position:relative;display:flex;align-items:center;justify-content:center;gap:.5rem;line-height:1.5}.login-button:hover:not(:disabled){background:var(--login-primary-hover)}.login-button:focus{outline:none;box-shadow:0 0 0 .2rem #007bff40}.login-button:disabled{background:#6c757d;cursor:not-allowed}.login-button .loading-content{display:flex;align-items:center;gap:.5rem}.login-button .icon-spinner{animation:spin 1s linear infinite}.login-links{margin-top:1.5rem;text-align:center;display:flex;align-items:center;justify-content:center;gap:.75rem;flex-wrap:wrap}.login-links .link{color:var(--login-primary-color);text-decoration:none;font-size:.875rem;font-weight:500;transition:var(--login-transition)}.login-links .link:hover{color:var(--login-primary-hover);text-decoration:underline}.login-links .link:focus{outline:2px solid var(--login-primary-color);outline-offset:2px;border-radius:4px}.login-links .separator{color:var(--login-secondary-color);font-size:.875rem}.login-footer{margin-top:2rem;padding-top:1.5rem;border-top:1px solid var(--login-border-color);text-align:center}.login-footer .footer-text{font-family:DM Sans,sans-serif;font-size:.75rem;color:var(--login-secondary-color);margin:0;font-weight:400}@media (max-width: 640px){.login-container{padding:.5rem}.login-card{padding:1.5rem}.login-header .login-title{font-size:1.5rem}.demo-buttons{grid-template-columns:1fr}.login-links{flex-direction:column;gap:.5rem}.login-links .separator{display:none}}@media (max-width: 480px){.form-input{padding:.75rem;font-size:.9rem}.login-button{padding:.8rem;font-size:.9rem}}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.login-card{animation:fadeIn .5s ease-out}@media (prefers-color-scheme: dark){:host{--login-background: #0f172a;--login-card-background: #1e293b;--login-border-color: #334155;--login-text-color: #f1f5f9;--login-secondary-color: #94a3b8}}@media (prefers-contrast: high){:host{--login-border-color: #000000;--login-text-color: #000000;--login-background: #ffffff}.form-input:focus{border-width:3px}}@media (prefers-reduced-motion: reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@media print{.login-container{min-height:auto;background:#fff}.demo-section,.loading-overlay{display:none}}\n"] }]
|
|
2116
|
+
args: [{ selector: 'lib-login', standalone: true, imports: [CommonModule, ReactiveFormsModule], template: "<!-- Container principal do login -->\n<div class=\"login-container\" [ngClass]=\"customCssClass\"\n [style.background-image]=\"options.backgroundUrl ? 'url(' + options.backgroundUrl + ')' : null\">\n\n <!-- Card de login -->\n <div class=\"login-card\">\n\n <!-- Header -->\n <div class=\"login-header\">\n <img *ngIf=\"options.logoUrl\" [src]=\"options.logoUrl\" alt=\"Logo\" class=\"login-logo\">\n\n <h1 class=\"login-title\">{{ options.title || 'Entrar' }}</h1>\n <p class=\"login-subtitle\">{{ options.subtitle || 'Acesse sua conta' }}</p>\n </div>\n\n <!-- Indicador de loading -->\n <div *ngIf=\"isLoading$ | async\" class=\"loading-overlay\">\n <div class=\"loading-spinner\"></div>\n <span class=\"loading-text\">Entrando...</span>\n </div>\n\n <!-- Estado de bloqueio removido conforme solicita\u00E7\u00E3o -->\n\n <!-- Formul\u00E1rio de login -->\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"onSubmit()\" class=\"login-form\"\n [class.disabled]=\"(isLoading$ | async)\">\n\n <!-- Campo Email -->\n <div class=\"form-group\">\n <label for=\"email\" class=\"form-label\">\n Email <span class=\"required\">*</span>\n </label>\n\n <div class=\"input-wrapper\">\n <input id=\"email\" type=\"email\" formControlName=\"email\" class=\"form-input\"\n [class.error]=\"hasFieldError('email', 'required') || hasFieldError('email', 'email')\"\n placeholder=\"Digite seu email\" autocomplete=\"email\" autocapitalize=\"off\">\n\n <i class=\"input-icon icon-email\"></i>\n </div>\n\n <!-- Erro do campo email -->\n <div *ngIf=\"getFieldErrorMessage('email')\" class=\"field-error\">\n {{ getFieldErrorMessage('email') }}\n </div>\n </div>\n\n <!-- Campo Senha -->\n <div class=\"form-group\">\n <label for=\"password\" class=\"form-label\">\n Senha <span class=\"required\">*</span>\n </label>\n\n <div class=\"input-wrapper\">\n <input id=\"password\" [type]=\"showPassword ? 'text' : 'password'\" formControlName=\"password\"\n class=\"form-input\"\n [class.error]=\"hasFieldError('password', 'required') || hasFieldError('password', 'minlength')\"\n placeholder=\"Digite sua senha\" autocomplete=\"current-password\">\n\n <button type=\"button\" class=\"password-toggle\" (click)=\"togglePasswordVisibility()\"\n [attr.aria-label]=\"showPassword ? 'Ocultar senha' : 'Mostrar senha'\">\n <i [class]=\"showPassword ? 'icon-eye-off' : 'icon-eye'\"></i>\n </button>\n </div>\n\n <!-- Erro do campo senha -->\n <div *ngIf=\"getFieldErrorMessage('password')\" class=\"field-error\">\n {{ getFieldErrorMessage('password') }}\n </div>\n </div>\n\n <!-- Checkbox removido conforme solicita\u00E7\u00E3o -->\n\n <!-- Erros gerais -->\n <div *ngIf=\"(errors$ | async)?.general\" class=\"alert alert-error\">\n <i class=\"icon-error\"></i>\n <div>\n <div *ngFor=\"let error of (errors$ | async)?.general\">\n {{ error }}\n </div>\n </div>\n </div>\n\n <!-- Bot\u00E3o de submit -->\n <button type=\"submit\" class=\"login-button\" [disabled]=\"loginForm.invalid || (isLoading$ | async)\">\n\n <span *ngIf=\"!(isLoading$ | async)\">Entrar</span>\n <span *ngIf=\"isLoading$ | async\" class=\"loading-content\">\n <i class=\"icon-spinner spin\"></i>\n Entrando...\n </span>\n </button>\n\n <!-- Contador de tentativas removido conforme solicita\u00E7\u00E3o -->\n </form>\n\n <!-- Links adicionais -->\n <div class=\"login-links\">\n <a href=\"#\" (click)=\"onForgotPassword(); $event.preventDefault()\" class=\"link\">\n Esqueci minha senha\n </a>\n\n <span class=\"separator\">\u2022</span>\n\n <a href=\"#\" (click)=\"onCreateAccount(); $event.preventDefault()\" class=\"link\">\n Criar conta\n </a>\n </div>\n\n <!-- Se\u00E7\u00E3o de demonstra\u00E7\u00E3o removida conforme solicita\u00E7\u00E3o -->\n\n <!-- Footer -->\n <div *ngIf=\"options.footerText\" class=\"login-footer\">\n <p class=\"footer-text\">\n {{ options.footerText }}\n </p>\n </div>\n </div>\n</div>", styles: ["@charset \"UTF-8\";:host{--login-primary-color: #007bff;--login-primary-hover: #0056b3;--login-secondary-color: #6c757d;--login-background: #f8f9fa;--login-card-background: #ffffff;--login-border-color: #dee2e6;--login-text-color: #343a40;--login-error-color: #dc3545;--login-success-color: #28a745;--login-warning-color: #ffc107;--login-shadow: 0 10px 25px rgba(0, 0, 0, .1);--login-border-radius: .75rem;--login-transition: all .3s ease}.login-container{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:1rem;background:var(--login-background);background-size:cover;background-position:center;background-repeat:no-repeat;position:relative;font-family:DM Sans,sans-serif}.login-container:before{content:\"\";position:absolute;inset:0;background:#0000004d;z-index:1;opacity:0;transition:opacity .3s ease}.login-container[style*=background-image]:before{opacity:1}.login-card{background:var(--login-card-background);border-radius:var(--login-border-radius);box-shadow:var(--login-shadow);padding:2rem;width:100%;max-width:420px;position:relative;border:1px solid var(--login-border-color);z-index:2}@media(max-width:480px){.login-card{padding:1.5rem;margin:.5rem}}.login-header{text-align:center;margin-bottom:2rem}.login-header .login-logo{max-width:80px;height:auto;margin-bottom:1rem}.login-header .login-title{font-family:DM Sans,sans-serif;font-size:1.75rem;font-weight:700;color:var(--login-text-color);margin:0 0 .5rem;line-height:1.2}.login-header .login-subtitle{font-size:.875rem;color:var(--login-secondary-color);margin:0;font-weight:400}.loading-overlay{position:absolute;inset:0;background:#fffffff2;display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:var(--login-border-radius);z-index:10}.loading-overlay .loading-spinner{width:40px;height:40px;border:3px solid var(--login-border-color);border-top:3px solid var(--login-primary-color);border-radius:50%;animation:spin 1s linear infinite;margin-bottom:1rem}.loading-overlay .loading-text{color:var(--login-secondary-color);font-size:.9rem;font-weight:500}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.login-form.disabled{pointer-events:none;opacity:.7}.form-group{margin-bottom:1.5rem}.form-label{display:block;font-family:DM Sans,sans-serif;font-size:.875rem;font-weight:600;color:var(--login-text-color);margin-bottom:.5rem;line-height:2.5}.form-label .required{color:var(--login-error-color);margin-left:.25rem}.input-wrapper{position:relative;display:flex;align-items:center}.form-input{font-family:DM Sans,sans-serif;font-weight:400;font-size:.875rem;border:1px solid var(--login-border-color);border-radius:.25rem;display:block;width:100%;padding:.375rem 2.75rem .375rem .75rem;line-height:1.5;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#fff;background-clip:padding-box;color:var(--login-text-color);transition:var(--login-transition);outline:none}.form-input::placeholder{color:#6c757d}.form-input:focus{border-color:#b2b9be;box-shadow:none}.form-input:focus.error{border-color:var(--login-error-color)}.form-input.error{border-color:var(--login-error-color)}.form-input:disabled{background:#f8f9fa;color:#6c757d;cursor:not-allowed}.input-icon{position:absolute;right:1rem;color:var(--login-secondary-color);font-size:1.1rem;pointer-events:none}.password-toggle{position:absolute;right:.75rem;background:none;border:none;padding:.25rem;cursor:pointer;color:var(--login-secondary-color);transition:var(--login-transition);border-radius:4px}.password-toggle:hover{color:var(--login-primary-color);background:#3b82f61a}.password-toggle:focus{outline:none;box-shadow:0 0 0 2px #3b82f64d}.field-error{margin-top:.5rem;font-size:.75rem;color:var(--login-error-color);font-family:DM Sans,sans-serif}.field-error:before{content:\"\\26a0 \";font-size:.75rem}.alert{padding:1rem;border-radius:8px;margin-bottom:1rem;display:flex;align-items:flex-start;gap:.75rem;font-size:.9rem}.alert.alert-error{background:#fef2f2;border:1px solid #fecaca;color:#991b1b}.alert.alert-error i{color:var(--login-error-color);font-size:1.1rem;margin-top:.1rem}.alert.alert-warning{background:#fffbeb;border:1px solid #fed7aa;color:#92400e}.alert.alert-warning i{color:var(--login-warning-color);font-size:1.1rem;margin-top:.1rem}.lockout-message{margin-bottom:1.5rem}.lockout-message strong{display:block;margin-bottom:.5rem}.lockout-message p{margin:.25rem 0}.login-button{width:100%;padding:.375rem .75rem;background:var(--login-primary-color);color:#fff;border:none;border-radius:.25rem;font-family:DM Sans,sans-serif;font-size:.875rem;font-weight:600;cursor:pointer;transition:var(--login-transition);position:relative;display:flex;align-items:center;justify-content:center;gap:.5rem;line-height:1.5}.login-button:hover:not(:disabled){background:var(--login-primary-hover)}.login-button:focus{outline:none;box-shadow:0 0 0 .2rem #007bff40}.login-button:disabled{background:#6c757d;cursor:not-allowed}.login-button .loading-content{display:flex;align-items:center;gap:.5rem}.login-button .icon-spinner{animation:spin 1s linear infinite}.login-links{margin-top:1.5rem;text-align:center;display:flex;align-items:center;justify-content:center;gap:.75rem;flex-wrap:wrap}.login-links .link{color:var(--login-primary-color);text-decoration:none;font-size:.875rem;font-weight:500;transition:var(--login-transition)}.login-links .link:hover{color:var(--login-primary-hover);text-decoration:underline}.login-links .link:focus{outline:2px solid var(--login-primary-color);outline-offset:2px;border-radius:4px}.login-links .separator{color:var(--login-secondary-color);font-size:.875rem}.login-footer{margin-top:2rem;padding-top:1.5rem;border-top:1px solid var(--login-border-color);text-align:center}.login-footer .footer-text{font-family:DM Sans,sans-serif;font-size:.75rem;color:var(--login-secondary-color);margin:0;font-weight:400}@media(max-width:640px){.login-container{padding:.5rem}.login-card{padding:1.5rem}.login-header .login-title{font-size:1.5rem}.demo-buttons{grid-template-columns:1fr}.login-links{flex-direction:column;gap:.5rem}.login-links .separator{display:none}}@media(max-width:480px){.form-input{padding:.75rem;font-size:.9rem}.login-button{padding:.8rem;font-size:.9rem}}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.login-card{animation:fadeIn .5s ease-out}@media(prefers-color-scheme:dark){:host{--login-background: #0f172a;--login-card-background: #1e293b;--login-border-color: #334155;--login-text-color: #f1f5f9;--login-secondary-color: #94a3b8}}@media(prefers-contrast:high){:host{--login-border-color: #000000;--login-text-color: #000000;--login-background: #ffffff}.form-input:focus{border-width:3px}}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@media print{.login-container{min-height:auto;background:#fff}.demo-section,.loading-overlay{display:none}}\n"] }]
|
|
2117
2117
|
}], ctorParameters: () => [{ type: LoginService }], propDecorators: { options: [{
|
|
2118
2118
|
type: Input
|
|
2119
2119
|
}], showHeader: [{
|
|
@@ -2167,10 +2167,10 @@ class AuthInterceptor {
|
|
|
2167
2167
|
}));
|
|
2168
2168
|
}));
|
|
2169
2169
|
}
|
|
2170
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2171
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
2170
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AuthInterceptor, deps: [{ token: AuthStorageService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2171
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AuthInterceptor });
|
|
2172
2172
|
}
|
|
2173
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2173
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AuthInterceptor, decorators: [{
|
|
2174
2174
|
type: Injectable
|
|
2175
2175
|
}], ctorParameters: () => [{ type: AuthStorageService }] });
|
|
2176
2176
|
|