@c80/ui 1.0.53 → 1.0.56
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/esm2022/index.js +5 -0
- package/esm2022/index.js.map +1 -1
- package/esm2022/lib/action-list/action-list.component.js +23 -0
- package/esm2022/lib/action-list/action-list.component.js.map +1 -0
- package/esm2022/lib/action-list/action-list.types.js +2 -0
- package/esm2022/lib/action-list/action-list.types.js.map +1 -0
- package/esm2022/lib/action-list/index.js +3 -0
- package/esm2022/lib/action-list/index.js.map +1 -0
- package/esm2022/lib/card-level/card-level.component.js +7 -0
- package/esm2022/lib/card-level/card-level.component.js.map +1 -1
- package/esm2022/lib/header/header.component.js +18 -0
- package/esm2022/lib/header/header.component.js.map +1 -0
- package/esm2022/lib/header/header.types.js +2 -0
- package/esm2022/lib/header/header.types.js.map +1 -0
- package/esm2022/lib/header/index.js +3 -0
- package/esm2022/lib/header/index.js.map +1 -0
- package/esm2022/lib/icon/icon.component.js +36 -15
- package/esm2022/lib/icon/icon.component.js.map +1 -1
- package/esm2022/lib/icon/icon.constants.js +10 -294
- package/esm2022/lib/icon/icon.constants.js.map +1 -1
- package/esm2022/lib/icon/icon.definitions.js +393 -0
- package/esm2022/lib/icon/icon.definitions.js.map +1 -0
- package/esm2022/lib/icon/icon.types.js.map +1 -1
- package/esm2022/lib/icon/icon.utils.js +17 -0
- package/esm2022/lib/icon/icon.utils.js.map +1 -1
- package/esm2022/lib/icon/index.js +1 -0
- package/esm2022/lib/icon/index.js.map +1 -1
- package/esm2022/lib/icon/theme.service.js +39 -0
- package/esm2022/lib/icon/theme.service.js.map +1 -0
- package/esm2022/lib/info-list/index.js +3 -0
- package/esm2022/lib/info-list/index.js.map +1 -0
- package/esm2022/lib/info-list/info-list.component.js +12 -0
- package/esm2022/lib/info-list/info-list.component.js.map +1 -0
- package/esm2022/lib/info-list/info-list.types.js +2 -0
- package/esm2022/lib/info-list/info-list.types.js.map +1 -0
- package/esm2022/lib/input-field/index.js +2 -0
- package/esm2022/lib/input-field/index.js.map +1 -0
- package/esm2022/lib/input-field/input-field.component.js +37 -0
- package/esm2022/lib/input-field/input-field.component.js.map +1 -0
- package/esm2022/lib/modal/modal.component.js +6 -6
- package/esm2022/lib/modal/modal.component.js.map +1 -1
- package/esm2022/lib/profile-stats/index.js +3 -0
- package/esm2022/lib/profile-stats/index.js.map +1 -0
- package/esm2022/lib/profile-stats/profile-stats.component.js +12 -0
- package/esm2022/lib/profile-stats/profile-stats.component.js.map +1 -0
- package/esm2022/lib/profile-stats/profile-stats.types.js +2 -0
- package/esm2022/lib/profile-stats/profile-stats.types.js.map +1 -0
- package/esm2022/lib/stat-card/stat-card.component.js +6 -6
- package/esm2022/lib/stat-card/stat-card.component.js.map +1 -1
- package/esm2022/lib/tab/c80-tab.component.js +6 -6
- package/esm2022/lib/tab/c80-tab.component.js.map +1 -1
- package/esm2022/lib/tab/directives/c80-tab-item.directive.js.map +1 -0
- package/esm2022/lib/tab/directives/c80-tab-label.directive.js.map +1 -0
- package/esm2022/lib/tab/index.js +3 -3
- package/esm2022/lib/tab/index.js.map +1 -1
- package/esm2022/lib/table/table-column-visibility.service.js.map +1 -1
- package/esm2022/lib/table/table-crud-state.service.js.map +1 -1
- package/esm2022/lib/table/table-data-converter.service.js.map +1 -1
- package/esm2022/lib/table/table-data-utils.service.js.map +1 -1
- package/esm2022/lib/table/table.component.js +26 -7
- package/esm2022/lib/table/table.component.js.map +1 -1
- package/esm2022/lib/table/table.types.js.map +1 -1
- package/esm2022/lib/table/table.utils.js.map +1 -1
- package/index.d.ts +5 -0
- package/lib/action-list/action-list.component.d.ts +10 -0
- package/lib/action-list/action-list.types.d.ts +8 -0
- package/lib/action-list/index.d.ts +2 -0
- package/lib/header/header.component.d.ts +9 -0
- package/lib/header/header.types.d.ts +3 -0
- package/lib/header/index.d.ts +2 -0
- package/lib/icon/icon.component.d.ts +17 -5
- package/lib/icon/icon.constants.d.ts +9 -14
- package/lib/icon/icon.definitions.d.ts +16 -0
- package/lib/icon/icon.types.d.ts +43 -6
- package/lib/icon/icon.utils.d.ts +5 -0
- package/lib/icon/index.d.ts +1 -0
- package/lib/icon/theme.service.d.ts +10 -0
- package/lib/info-list/index.d.ts +2 -0
- package/lib/info-list/info-list.component.d.ts +7 -0
- package/lib/info-list/info-list.types.d.ts +4 -0
- package/lib/input-field/index.d.ts +1 -0
- package/lib/input-field/input-field.component.d.ts +19 -0
- package/lib/modal/modal.component.d.ts +3 -3
- package/lib/profile-stats/index.d.ts +2 -0
- package/lib/profile-stats/profile-stats.component.d.ts +7 -0
- package/lib/profile-stats/profile-stats.types.d.ts +4 -0
- package/lib/stat-card/stat-card.component.d.ts +3 -3
- package/lib/tab/c80-tab.component.d.ts +5 -5
- package/lib/tab/index.d.ts +3 -3
- package/lib/table/table-column-visibility.service.d.ts +5 -5
- package/lib/table/table-crud-state.service.d.ts +3 -3
- package/lib/table/table-data-converter.service.d.ts +2 -2
- package/lib/table/table-data-utils.service.d.ts +6 -6
- package/lib/table/table.component.d.ts +14 -14
- package/lib/table/table.types.d.ts +1 -1
- package/lib/table/table.utils.d.ts +2 -2
- package/package.json +1 -1
- package/esm2022/lib/tab/c80-tab-item.directive.js.map +0 -1
- package/esm2022/lib/tab/c80-tab-label.directive.js.map +0 -1
- /package/esm2022/lib/tab/{c80-tab-item.directive.js → directives/c80-tab-item.directive.js} +0 -0
- /package/esm2022/lib/tab/{c80-tab-label.directive.js → directives/c80-tab-label.directive.js} +0 -0
- /package/lib/tab/{c80-tab-item.directive.d.ts → directives/c80-tab-item.directive.d.ts} +0 -0
- /package/lib/tab/{c80-tab-label.directive.d.ts → directives/c80-tab-label.directive.d.ts} +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, output, signal } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export class InputFieldComponent {
|
|
4
|
+
label = signal('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
5
|
+
value = signal('', ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
6
|
+
placeholder = signal('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
7
|
+
type = signal('text', ...(ngDevMode ? [{ debugName: "type" }] : []));
|
|
8
|
+
maxLength = signal(undefined, ...(ngDevMode ? [{ debugName: "maxLength" }] : []));
|
|
9
|
+
readonly = signal(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
|
|
10
|
+
required = signal(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
|
|
11
|
+
valueChange = output();
|
|
12
|
+
enterPressed = output();
|
|
13
|
+
isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : []));
|
|
14
|
+
onValueChange(event) {
|
|
15
|
+
const newValue = event.target.value;
|
|
16
|
+
this.value.set(newValue);
|
|
17
|
+
this.valueChange.emit(newValue);
|
|
18
|
+
}
|
|
19
|
+
onFocus() {
|
|
20
|
+
this.isFocused.set(true);
|
|
21
|
+
}
|
|
22
|
+
onBlur() {
|
|
23
|
+
this.isFocused.set(false);
|
|
24
|
+
}
|
|
25
|
+
onKeyDown(event) {
|
|
26
|
+
if (event.key === 'Enter') {
|
|
27
|
+
this.enterPressed.emit();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: InputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
31
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.10", type: InputFieldComponent, isStandalone: true, selector: "c80-input-field", outputs: { valueChange: "valueChange", enterPressed: "enterPressed" }, ngImport: i0, template: "<div class=\"input-field\">\n <div class=\"input-field__item\">\n <span class=\"input-field__label\">{{ label() }}</span>\n <input class=\"input-field__input\" [class.input-field__input--focused]=\"isFocused()\" [type]=\"type()\" [value]=\"value()\" [placeholder]=\"placeholder()\" [attr.maxlength]=\"maxLength()\" [readonly]=\"readonly()\" [required]=\"required()\"\n (input)=\"onValueChange($event)\" (focus)=\"onFocus()\" (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" />\n </div>\n</div>", styles: [".input-field{width:100%}.input-field__item{display:flex;justify-content:space-between;align-items:center;padding:1rem;background:var(--color-surface);border-radius:var(--radius-lg);gap:1rem;transition:all var(--transition-base)}.input-field__item:hover{background:var(--color-bg-dark)}.input-field__label{font-size:1rem;font-weight:500;color:var(--color-text-primary);min-width:fit-content}.input-field__input{flex:1;background:transparent;border:none;outline:none;font-size:1rem;color:var(--color-text-primary);text-align:right;padding:.5rem 0;min-width:0}.input-field__input::placeholder{color:var(--color-text-tertiary);font-style:italic}.input-field__input:focus{color:var(--color-primary)}.input-field__input[readonly]{cursor:default;color:var(--color-text-secondary)}.input-field__input--focused{color:var(--color-primary)}@media(max-width:768px){.input-field__item{padding:.75rem;gap:.75rem}.input-field__label,.input-field__input{font-size:.875rem}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
32
|
+
}
|
|
33
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: InputFieldComponent, decorators: [{
|
|
34
|
+
type: Component,
|
|
35
|
+
args: [{ selector: 'c80-input-field', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"input-field\">\n <div class=\"input-field__item\">\n <span class=\"input-field__label\">{{ label() }}</span>\n <input class=\"input-field__input\" [class.input-field__input--focused]=\"isFocused()\" [type]=\"type()\" [value]=\"value()\" [placeholder]=\"placeholder()\" [attr.maxlength]=\"maxLength()\" [readonly]=\"readonly()\" [required]=\"required()\"\n (input)=\"onValueChange($event)\" (focus)=\"onFocus()\" (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" />\n </div>\n</div>", styles: [".input-field{width:100%}.input-field__item{display:flex;justify-content:space-between;align-items:center;padding:1rem;background:var(--color-surface);border-radius:var(--radius-lg);gap:1rem;transition:all var(--transition-base)}.input-field__item:hover{background:var(--color-bg-dark)}.input-field__label{font-size:1rem;font-weight:500;color:var(--color-text-primary);min-width:fit-content}.input-field__input{flex:1;background:transparent;border:none;outline:none;font-size:1rem;color:var(--color-text-primary);text-align:right;padding:.5rem 0;min-width:0}.input-field__input::placeholder{color:var(--color-text-tertiary);font-style:italic}.input-field__input:focus{color:var(--color-primary)}.input-field__input[readonly]{cursor:default;color:var(--color-text-secondary)}.input-field__input--focused{color:var(--color-primary)}@media(max-width:768px){.input-field__item{padding:.75rem;gap:.75rem}.input-field__label,.input-field__input{font-size:.875rem}}\n"] }]
|
|
36
|
+
}], propDecorators: { valueChange: [{ type: i0.Output, args: ["valueChange"] }], enterPressed: [{ type: i0.Output, args: ["enterPressed"] }] } });
|
|
37
|
+
//# sourceMappingURL=input-field.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-field.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/input-field/input-field.component.ts","../../../../../libs/ui/src/lib/input-field/input-field.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;;AAUnF,MAAM,OAAO,mBAAmB;IACnB,KAAK,GAAG,MAAM,CAAS,EAAE,iDAAC,CAAC;IAC3B,KAAK,GAAG,MAAM,CAAS,EAAE,iDAAC,CAAC;IAC3B,WAAW,GAAG,MAAM,CAAS,EAAE,uDAAC,CAAC;IACjC,IAAI,GAAG,MAAM,CAAgC,MAAM,gDAAC,CAAC;IACrD,SAAS,GAAG,MAAM,CAAqB,SAAS,qDAAC,CAAC;IAClD,QAAQ,GAAG,MAAM,CAAU,KAAK,oDAAC,CAAC;IAClC,QAAQ,GAAG,MAAM,CAAU,KAAK,oDAAC,CAAC;IAE3C,WAAW,GAAG,MAAM,EAAU,CAAC;IAC/B,YAAY,GAAG,MAAM,EAAQ,CAAC;IAEX,SAAS,GAAG,MAAM,CAAC,KAAK,qDAAC,CAAC;IAEnC,aAAa,CAAC,KAAY;QAChC,MAAM,QAAQ,GAAI,KAAK,CAAC,MAA2B,CAAC,KAAK,CAAC;QAC1D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACzB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAES,OAAO;QACb,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAES,MAAM;QACZ,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAES,SAAS,CAAC,KAAoB;QACpC,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;wGAhCQ,mBAAmB;4FAAnB,mBAAmB,kJCVhC,ihBAMM;;4FDIO,mBAAmB;kBAR/B,SAAS;+BACI,iBAAiB,cACf,IAAI,WACP,EAAE,mBAGM,uBAAuB,CAAC,MAAM","sourcesContent":["import { ChangeDetectionStrategy, Component, output, signal } from '@angular/core';\n\n@Component({\n selector: 'c80-input-field',\n standalone: true,\n imports: [],\n templateUrl: './input-field.component.html',\n styleUrl: './input-field.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class InputFieldComponent {\n readonly label = signal<string>('');\n readonly value = signal<string>('');\n readonly placeholder = signal<string>('');\n readonly type = signal<'text' | 'email' | 'password'>('text');\n readonly maxLength = signal<number | undefined>(undefined);\n readonly readonly = signal<boolean>(false);\n readonly required = signal<boolean>(false);\n\n valueChange = output<string>();\n enterPressed = output<void>();\n\n protected readonly isFocused = signal(false);\n\n protected onValueChange(event: Event): void {\n const newValue = (event.target as HTMLInputElement).value;\n this.value.set(newValue);\n this.valueChange.emit(newValue);\n }\n\n protected onFocus(): void {\n this.isFocused.set(true);\n }\n\n protected onBlur(): void {\n this.isFocused.set(false);\n }\n\n protected onKeyDown(event: KeyboardEvent): void {\n if (event.key === 'Enter') {\n this.enterPressed.emit();\n }\n }\n}","<div class=\"input-field\">\n <div class=\"input-field__item\">\n <span class=\"input-field__label\">{{ label() }}</span>\n <input class=\"input-field__input\" [class.input-field__input--focused]=\"isFocused()\" [type]=\"type()\" [value]=\"value()\" [placeholder]=\"placeholder()\" [attr.maxlength]=\"maxLength()\" [readonly]=\"readonly()\" [required]=\"required()\"\n (input)=\"onValueChange($event)\" (focus)=\"onFocus()\" (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" />\n </div>\n</div>"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Component, computed, effect, inject, ChangeDetectionStrategy } from '@angular/core';
|
|
2
2
|
import { ModalService } from './modal.service';
|
|
3
|
-
import {
|
|
3
|
+
import { IconComponent } from './../icon';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
|
-
export class
|
|
5
|
+
export class ModalComponent {
|
|
6
6
|
modalService = inject(ModalService);
|
|
7
7
|
isOpen = this.modalService.modalState.isOpen;
|
|
8
8
|
config = this.modalService.modalState.config;
|
|
@@ -77,11 +77,11 @@ export class C80ModalComponent {
|
|
|
77
77
|
getNoText() {
|
|
78
78
|
return this.config().noText ?? 'No';
|
|
79
79
|
}
|
|
80
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type:
|
|
81
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type:
|
|
80
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
81
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: ModalComponent, isStandalone: true, selector: "c80-modal", ngImport: i0, template: "<!-- Modal Backdrop -->\n@if (isOpen()) {\n<div class=\"modal-backdrop\" [class.show]=\"isVisible()\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown.escape)=\"closeModal()\">\n\n <!-- Modal Container -->\n <dialog class=\"modal-container\" [class.show]=\"isVisible()\" [attr.aria-labelledby]=\"'modal-title'\" [open]=\"isVisible()\">\n\n <!-- Modal Header -->\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" id=\"modal-title\">{{ config().title }}</h4>\n <c80-icon [button]=\"true\" icon=\"close\" (iconClick)=\"closeModal()\" title=\"Cerrar\" color=\"warn\" />\n </div>\n\n <!-- Modal Body -->\n <div class=\"modal-body\">\n <p class=\"modal-message\">{{ config().message }}</p>\n </div>\n\n <!-- Modal Footer -->\n <div class=\"modal-footer\">\n\n <!-- Info Modal - Solo OK -->\n @if (showOkButton()) {\n <c80-icon [button]=\"true\" icon=\"check\" textRight=\"OK\" color=\"dark\" (iconClick)=\"onConfirm()\" [border]=\"true\" />\n }\n\n <!-- Yes/No Modal -->\n @if (showYesNoButtons()) {\n <c80-icon [button]=\"true\" icon=\"check\" [textRight]=\"getYesText()\" color=\"dark\" (iconClick)=\"onYes()\" [border]=\"true\" />\n <c80-icon [button]=\"true\" icon=\"cancel\" [textRight]=\"getNoText()\" color=\"warn\" (iconClick)=\"onNo()\" [border]=\"true\" />\n }\n\n <!-- Confirm Modal -->\n @if (showConfirmButtons()) {\n <c80-icon [button]=\"true\" icon=\"check\" [textRight]=\"getConfirmText()\" color=\"dark\" (iconClick)=\"onConfirm()\" [border]=\"true\" />\n <c80-icon [button]=\"true\" icon=\"cancel\" [textRight]=\"getCancelText()\" color=\"warn\" (iconClick)=\"onCancel()\" [border]=\"true\" />\n }\n\n </div>\n </dialog>\n</div>\n}", styles: [".modal-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);z-index:1100;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .2s ease-in-out;outline:none}.modal-backdrop.show{opacity:1}.modal-container{background:var(--color-bg-primary);border-radius:8px;box-shadow:0 4px 20px #00000026;border:1px solid var(--color-border-default);max-width:400px;width:90%;max-height:90vh;overflow:hidden;transform:scale(.9) translateY(-10px);transition:all .15s ease-out;position:relative;padding:0}.modal-container.show{transform:scale(1) translateY(0)}.modal-container::backdrop{background:transparent}.modal-header{display:flex;align-items:center;gap:8px;padding:16px 20px 12px;border-bottom:1px solid var(--color-border-default);background:var(--color-bg-secondary)}.modal-header .modal-title{flex:1;margin:0;font-size:16px;font-weight:600;color:var(--color-text-primary);line-height:1.3}.modal-body{padding:16px 20px}.modal-body .modal-message{margin:0;font-size:14px;line-height:1.5;color:var(--color-text-primary);white-space:pre-line}.modal-footer{display:flex;justify-content:flex-end;gap:8px;padding:12px 20px 16px;background:var(--color-bg-secondary);border-top:1px solid var(--color-border-default)}@media(max-width:768px){.modal-container{width:95%;margin:10px}.modal-header{padding:12px 16px 8px}.modal-header .modal-title{font-size:15px}.modal-body{padding:12px 16px}.modal-body .modal-message{font-size:13px}.modal-footer{padding:8px 16px 12px;flex-direction:column}}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "c80-icon", inputs: ["icon", "color", "customColor", "disabled", "size", "button", "border", "type", "textLeft", "textRight", "dark"], outputs: ["iconClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
82
82
|
}
|
|
83
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type:
|
|
83
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ModalComponent, decorators: [{
|
|
84
84
|
type: Component,
|
|
85
|
-
args: [{ selector: 'c80-modal', standalone: true, imports: [
|
|
85
|
+
args: [{ selector: 'c80-modal', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Modal Backdrop -->\n@if (isOpen()) {\n<div class=\"modal-backdrop\" [class.show]=\"isVisible()\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown.escape)=\"closeModal()\">\n\n <!-- Modal Container -->\n <dialog class=\"modal-container\" [class.show]=\"isVisible()\" [attr.aria-labelledby]=\"'modal-title'\" [open]=\"isVisible()\">\n\n <!-- Modal Header -->\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" id=\"modal-title\">{{ config().title }}</h4>\n <c80-icon [button]=\"true\" icon=\"close\" (iconClick)=\"closeModal()\" title=\"Cerrar\" color=\"warn\" />\n </div>\n\n <!-- Modal Body -->\n <div class=\"modal-body\">\n <p class=\"modal-message\">{{ config().message }}</p>\n </div>\n\n <!-- Modal Footer -->\n <div class=\"modal-footer\">\n\n <!-- Info Modal - Solo OK -->\n @if (showOkButton()) {\n <c80-icon [button]=\"true\" icon=\"check\" textRight=\"OK\" color=\"dark\" (iconClick)=\"onConfirm()\" [border]=\"true\" />\n }\n\n <!-- Yes/No Modal -->\n @if (showYesNoButtons()) {\n <c80-icon [button]=\"true\" icon=\"check\" [textRight]=\"getYesText()\" color=\"dark\" (iconClick)=\"onYes()\" [border]=\"true\" />\n <c80-icon [button]=\"true\" icon=\"cancel\" [textRight]=\"getNoText()\" color=\"warn\" (iconClick)=\"onNo()\" [border]=\"true\" />\n }\n\n <!-- Confirm Modal -->\n @if (showConfirmButtons()) {\n <c80-icon [button]=\"true\" icon=\"check\" [textRight]=\"getConfirmText()\" color=\"dark\" (iconClick)=\"onConfirm()\" [border]=\"true\" />\n <c80-icon [button]=\"true\" icon=\"cancel\" [textRight]=\"getCancelText()\" color=\"warn\" (iconClick)=\"onCancel()\" [border]=\"true\" />\n }\n\n </div>\n </dialog>\n</div>\n}", styles: [".modal-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);z-index:1100;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .2s ease-in-out;outline:none}.modal-backdrop.show{opacity:1}.modal-container{background:var(--color-bg-primary);border-radius:8px;box-shadow:0 4px 20px #00000026;border:1px solid var(--color-border-default);max-width:400px;width:90%;max-height:90vh;overflow:hidden;transform:scale(.9) translateY(-10px);transition:all .15s ease-out;position:relative;padding:0}.modal-container.show{transform:scale(1) translateY(0)}.modal-container::backdrop{background:transparent}.modal-header{display:flex;align-items:center;gap:8px;padding:16px 20px 12px;border-bottom:1px solid var(--color-border-default);background:var(--color-bg-secondary)}.modal-header .modal-title{flex:1;margin:0;font-size:16px;font-weight:600;color:var(--color-text-primary);line-height:1.3}.modal-body{padding:16px 20px}.modal-body .modal-message{margin:0;font-size:14px;line-height:1.5;color:var(--color-text-primary);white-space:pre-line}.modal-footer{display:flex;justify-content:flex-end;gap:8px;padding:12px 20px 16px;background:var(--color-bg-secondary);border-top:1px solid var(--color-border-default)}@media(max-width:768px){.modal-container{width:95%;margin:10px}.modal-header{padding:12px 16px 8px}.modal-header .modal-title{font-size:15px}.modal-body{padding:12px 16px}.modal-body .modal-message{font-size:13px}.modal-footer{padding:8px 16px 12px;flex-direction:column}}\n"] }]
|
|
86
86
|
}], ctorParameters: () => [] });
|
|
87
87
|
//# sourceMappingURL=modal.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/modal/modal.component.ts","../../../../../libs/ui/src/lib/modal/modal.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC7F,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"modal.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/modal/modal.component.ts","../../../../../libs/ui/src/lib/modal/modal.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, computed, effect, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { ModalService } from './modal.service';\nimport { IconComponent } from './../icon';\n\nexport type ModalType = 'info' | 'confirm' | 'yesNo' | 'warning' | 'error';\n\nexport interface ModalConfig {\n title: string;\n message: string;\n type?: ModalType;\n confirmText?: string;\n cancelText?: string;\n yesText?: string;\n noText?: string;\n showCancel?: boolean;\n}\n\nexport interface ModalResult {\n action: 'confirm' | 'cancel' | 'yes' | 'no';\n confirmed: boolean;\n}\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-modal',\n standalone: true,\n imports: [IconComponent],\n templateUrl: './modal.component.html',\n styleUrl: './modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ModalComponent {\n private readonly modalService = inject(ModalService);\n\n readonly isOpen = this.modalService.modalState.isOpen;\n readonly config = this.modalService.modalState.config;\n readonly isVisible = computed(() => this.isOpen());\n\n constructor() {\n effect(() => {\n if (this.isOpen()) {\n // Auto-focus modal when opened for accessibility\n /* v8 ignore next 8 */\n setTimeout(() => {\n const backdrop = document.querySelector(\n '.modal-backdrop'\n ) as HTMLElement;\n if (backdrop) {\n backdrop.focus();\n }\n }, 100);\n }\n });\n }\n\n onConfirm() {\n this.modalService.handleResult({ action: 'confirm', confirmed: true });\n }\n\n onCancel() {\n this.modalService.handleResult({ action: 'cancel', confirmed: false });\n }\n\n onYes() {\n this.modalService.handleResult({ action: 'yes', confirmed: true });\n }\n\n onNo() {\n this.modalService.handleResult({ action: 'no', confirmed: false });\n }\n\n closeModal() {\n this.modalService.closeModal();\n }\n\n onBackdropClick(event: Event) {\n if (event.target === event.currentTarget) {\n this.closeModal();\n }\n }\n\n getPrimaryButtonClass(): string {\n const configValue = this.config();\n switch (configValue.type) {\n case 'warning':\n return 'btn-warning';\n case 'error':\n return 'btn-danger';\n case 'confirm':\n case 'yesNo':\n return 'btn-primary';\n default:\n return 'btn-info';\n }\n }\n\n showYesNoButtons(): boolean {\n return this.config().type === 'yesNo';\n }\n\n showConfirmButtons(): boolean {\n const type = this.config().type;\n return type === 'confirm' || type === 'warning' || type === 'error';\n }\n\n showOkButton(): boolean {\n return this.config().type === 'info';\n }\n\n getConfirmText(): string {\n return this.config().confirmText ?? 'Confirmar';\n }\n\n getCancelText(): string {\n return this.config().cancelText ?? 'Cancelar';\n }\n\n getYesText(): string {\n return this.config().yesText ?? 'Sí';\n }\n\n getNoText(): string {\n return this.config().noText ?? 'No';\n }\n}\n","<!-- Modal Backdrop -->\n@if (isOpen()) {\n<div class=\"modal-backdrop\" [class.show]=\"isVisible()\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown.escape)=\"closeModal()\">\n\n <!-- Modal Container -->\n <dialog class=\"modal-container\" [class.show]=\"isVisible()\" [attr.aria-labelledby]=\"'modal-title'\" [open]=\"isVisible()\">\n\n <!-- Modal Header -->\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" id=\"modal-title\">{{ config().title }}</h4>\n <c80-icon [button]=\"true\" icon=\"close\" (iconClick)=\"closeModal()\" title=\"Cerrar\" color=\"warn\" />\n </div>\n\n <!-- Modal Body -->\n <div class=\"modal-body\">\n <p class=\"modal-message\">{{ config().message }}</p>\n </div>\n\n <!-- Modal Footer -->\n <div class=\"modal-footer\">\n\n <!-- Info Modal - Solo OK -->\n @if (showOkButton()) {\n <c80-icon [button]=\"true\" icon=\"check\" textRight=\"OK\" color=\"dark\" (iconClick)=\"onConfirm()\" [border]=\"true\" />\n }\n\n <!-- Yes/No Modal -->\n @if (showYesNoButtons()) {\n <c80-icon [button]=\"true\" icon=\"check\" [textRight]=\"getYesText()\" color=\"dark\" (iconClick)=\"onYes()\" [border]=\"true\" />\n <c80-icon [button]=\"true\" icon=\"cancel\" [textRight]=\"getNoText()\" color=\"warn\" (iconClick)=\"onNo()\" [border]=\"true\" />\n }\n\n <!-- Confirm Modal -->\n @if (showConfirmButtons()) {\n <c80-icon [button]=\"true\" icon=\"check\" [textRight]=\"getConfirmText()\" color=\"dark\" (iconClick)=\"onConfirm()\" [border]=\"true\" />\n <c80-icon [button]=\"true\" icon=\"cancel\" [textRight]=\"getCancelText()\" color=\"warn\" (iconClick)=\"onCancel()\" [border]=\"true\" />\n }\n\n </div>\n </dialog>\n</div>\n}"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/profile-stats/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC","sourcesContent":["export * from './profile-stats.component';\nexport * from './profile-stats.types';"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export class ProfileStatsComponent {
|
|
4
|
+
stats = input.required(...(ngDevMode ? [{ debugName: "stats" }] : []));
|
|
5
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ProfileStatsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: ProfileStatsComponent, isStandalone: true, selector: "c80-profile-stats", inputs: { stats: { classPropertyName: "stats", publicName: "stats", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"stats\">\n @for (stat of stats(); track $index) {\n <div class=\"stats__item\">\n <span class=\"stats__value\">{{ stat.value }}</span>\n <span class=\"stats__label\">{{ stat.label }}</span>\n </div>\n }\n</div>", styles: [".stats{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--spacing-md);text-align:center}.stats__item{display:flex;flex-direction:column;align-items:center;gap:var(--spacing-xs)}.stats__value{font-size:1.25rem;font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1}.stats__label{font-size:.8125rem;color:var(--color-text-secondary);text-transform:lowercase}@media(max-width:768px){.stats{gap:var(--spacing-sm)}.stats__value{font-size:1.125rem}.stats__label{font-size:.75rem}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7
|
+
}
|
|
8
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ProfileStatsComponent, decorators: [{
|
|
9
|
+
type: Component,
|
|
10
|
+
args: [{ selector: 'c80-profile-stats', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"stats\">\n @for (stat of stats(); track $index) {\n <div class=\"stats__item\">\n <span class=\"stats__value\">{{ stat.value }}</span>\n <span class=\"stats__label\">{{ stat.label }}</span>\n </div>\n }\n</div>", styles: [".stats{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--spacing-md);text-align:center}.stats__item{display:flex;flex-direction:column;align-items:center;gap:var(--spacing-xs)}.stats__value{font-size:1.25rem;font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1}.stats__label{font-size:.8125rem;color:var(--color-text-secondary);text-transform:lowercase}@media(max-width:768px){.stats{gap:var(--spacing-sm)}.stats__value{font-size:1.125rem}.stats__label{font-size:.75rem}}\n"] }]
|
|
11
|
+
}], propDecorators: { stats: [{ type: i0.Input, args: [{ isSignal: true, alias: "stats", required: true }] }] } });
|
|
12
|
+
//# sourceMappingURL=profile-stats.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-stats.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/profile-stats/profile-stats.component.ts","../../../../../libs/ui/src/lib/profile-stats/profile-stats.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;;AAU1E,MAAM,OAAO,qBAAqB;IAC9B,KAAK,GAAG,KAAK,CAAC,QAAQ,gDAAc,CAAC;wGAD5B,qBAAqB;4FAArB,qBAAqB,gNCVlC,2PAOM;;4FDGO,qBAAqB;kBAPjC,SAAS;+BACI,mBAAmB,cACjB,IAAI,mBAGC,uBAAuB,CAAC,MAAM","sourcesContent":["import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport type { StatItem } from './profile-stats.types';\n\n@Component({\n selector: 'c80-profile-stats',\n standalone: true,\n templateUrl: './profile-stats.component.html',\n styleUrl: './profile-stats.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ProfileStatsComponent {\n stats = input.required<StatItem[]>();\n}","<div class=\"stats\">\n @for (stat of stats(); track $index) {\n <div class=\"stats__item\">\n <span class=\"stats__value\">{{ stat.value }}</span>\n <span class=\"stats__label\">{{ stat.label }}</span>\n </div>\n }\n</div>"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-stats.types.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/profile-stats/profile-stats.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface StatItem {\n label: string;\n value: number | string;\n}"]}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Component, input, ChangeDetectionStrategy } from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { IconComponent } from '../icon';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
|
-
export class
|
|
4
|
+
export class StatCardComponent {
|
|
5
5
|
/* v8 ignore next */
|
|
6
6
|
cards = input([], ...(ngDevMode ? [{ debugName: "cards" }] : []));
|
|
7
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type:
|
|
8
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type:
|
|
7
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: StatCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: StatCardComponent, isStandalone: true, selector: "c80-stat-card", inputs: { cards: { classPropertyName: "cards", publicName: "cards", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"stats-section py-4\">\n @for (card of cards(); track card.text) {\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <div class=\"stat-card\" [style.border-left-color]=\"card.color\">\n <div class=\"stat-card-content\">\n <div class=\"stat-content\">\n <c80-icon [icon]=\"card.icon\" [color]=\"'secondary'\" [size]=\"1.1\" />\n <div class=\"stat-info\">\n <div class=\"stat-number\">{{ card.count }}</div>\n <div class=\"stat-label\">{{ card.text }}</div>\n </div>\n </div>\n </div>\n </div>\n }\n</div>", styles: [".stats-section{display:flex;flex-direction:row;flex-wrap:wrap;gap:16px}.stats-section .stat-card{flex:1;min-width:200px;box-shadow:var(--shadow-sm);transition:box-shadow .3s ease;border-left:4px solid transparent;background:var(--color-bg-primary);color:var(--color-text-primary);border-radius:4px;display:block;position:relative;padding:0;overflow:hidden}.stats-section .stat-card:hover{box-shadow:var(--shadow-md)}.stats-section .stat-card-content{display:block;padding:16px}.stat-content{display:flex;align-items:center;gap:12px}.stat-info .stat-number{font-size:24px;font-weight:700;line-height:1;margin-bottom:4px;color:var(--color-text-secondary)}.stat-info .stat-label{font-size:12px;color:var(--color-text-tertiary);text-transform:uppercase;letter-spacing:.5px}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "c80-icon", inputs: ["icon", "color", "customColor", "disabled", "size", "button", "border", "type", "textLeft", "textRight", "dark"], outputs: ["iconClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
9
9
|
}
|
|
10
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type:
|
|
10
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: StatCardComponent, decorators: [{
|
|
11
11
|
type: Component,
|
|
12
|
-
args: [{ selector: 'c80-stat-card', standalone: true, imports: [
|
|
12
|
+
args: [{ selector: 'c80-stat-card', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"stats-section py-4\">\n @for (card of cards(); track card.text) {\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <div class=\"stat-card\" [style.border-left-color]=\"card.color\">\n <div class=\"stat-card-content\">\n <div class=\"stat-content\">\n <c80-icon [icon]=\"card.icon\" [color]=\"'secondary'\" [size]=\"1.1\" />\n <div class=\"stat-info\">\n <div class=\"stat-number\">{{ card.count }}</div>\n <div class=\"stat-label\">{{ card.text }}</div>\n </div>\n </div>\n </div>\n </div>\n }\n</div>", styles: [".stats-section{display:flex;flex-direction:row;flex-wrap:wrap;gap:16px}.stats-section .stat-card{flex:1;min-width:200px;box-shadow:var(--shadow-sm);transition:box-shadow .3s ease;border-left:4px solid transparent;background:var(--color-bg-primary);color:var(--color-text-primary);border-radius:4px;display:block;position:relative;padding:0;overflow:hidden}.stats-section .stat-card:hover{box-shadow:var(--shadow-md)}.stats-section .stat-card-content{display:block;padding:16px}.stat-content{display:flex;align-items:center;gap:12px}.stat-info .stat-number{font-size:24px;font-weight:700;line-height:1;margin-bottom:4px;color:var(--color-text-secondary)}.stat-info .stat-label{font-size:12px;color:var(--color-text-tertiary);text-transform:uppercase;letter-spacing:.5px}\n"] }]
|
|
13
13
|
}], propDecorators: { cards: [{ type: i0.Input, args: [{ isSignal: true, alias: "cards", required: false }] }] } });
|
|
14
14
|
//# sourceMappingURL=stat-card.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stat-card.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/stat-card/stat-card.component.ts","../../../../../libs/ui/src/lib/stat-card/stat-card.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"stat-card.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/stat-card/stat-card.component.ts","../../../../../libs/ui/src/lib/stat-card/stat-card.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;;AAmBxC,MAAM,OAAO,iBAAiB;IAC5B,oBAAoB;IACX,KAAK,GAAG,KAAK,CAAY,EAAE,iDAAC,CAAC;wGAF3B,iBAAiB;4FAAjB,iBAAiB,6MCpB9B,+lBAeM,6zBDAM,aAAa;;4FAKZ,iBAAiB;kBAT7B,SAAS;+BAEE,eAAe,cACb,IAAI,WACP,CAAC,aAAa,CAAC,mBAGP,uBAAuB,CAAC,MAAM","sourcesContent":["import { Component, input, ChangeDetectionStrategy } from '@angular/core';\nimport { IconComponent } from '../icon';\nimport type { IconType } from '../icon/icon.types';\n\nexport interface CardDef {\n color: string; // Acepta cualquier color CSS\n icon: IconType;\n text: string;\n count: number;\n}\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-stat-card',\n standalone: true,\n imports: [IconComponent],\n templateUrl: './stat-card.component.html',\n styleUrls: ['./stat-card.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class StatCardComponent {\n /* v8 ignore next */\n readonly cards = input<CardDef[]>([]);\n}\n","<div class=\"stats-section py-4\">\n @for (card of cards(); track card.text) {\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <div class=\"stat-card\" [style.border-left-color]=\"card.color\">\n <div class=\"stat-card-content\">\n <div class=\"stat-content\">\n <c80-icon [icon]=\"card.icon\" [color]=\"'secondary'\" [size]=\"1.1\" />\n <div class=\"stat-info\">\n <div class=\"stat-number\">{{ card.count }}</div>\n <div class=\"stat-label\">{{ card.text }}</div>\n </div>\n </div>\n </div>\n </div>\n }\n</div>"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Component, output, model, ChangeDetectionStrategy, contentChildren } from '@angular/core';
|
|
2
2
|
import { NgTemplateOutlet } from '@angular/common';
|
|
3
|
-
import { C80TabItemDirective } from './c80-tab-item.directive';
|
|
4
|
-
import { C80TabLabelDirective } from './c80-tab-label.directive';
|
|
3
|
+
import { C80TabItemDirective } from './directives/c80-tab-item.directive';
|
|
4
|
+
import { C80TabLabelDirective } from './directives/c80-tab-label.directive';
|
|
5
5
|
import * as i0 from "@angular/core";
|
|
6
|
-
export class
|
|
6
|
+
export class TabComponent {
|
|
7
7
|
tabs = contentChildren(C80TabItemDirective, ...(ngDevMode ? [{ debugName: "tabs" }] : []));
|
|
8
8
|
labels = contentChildren(C80TabLabelDirective, ...(ngDevMode ? [{ debugName: "labels" }] : []));
|
|
9
9
|
/* v8 ignore next */
|
|
@@ -23,10 +23,10 @@ export class C80TabComponent {
|
|
|
23
23
|
const label = labelList[index];
|
|
24
24
|
return label?.template ?? null;
|
|
25
25
|
}
|
|
26
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type:
|
|
27
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type:
|
|
26
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
27
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: TabComponent, isStandalone: true, selector: "c80-tab", inputs: { selectedIndex: { classPropertyName: "selectedIndex", publicName: "selectedIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedIndex: "selectedIndexChange", selectedIndexChange: "selectedIndexChange" }, queries: [{ propertyName: "tabs", predicate: C80TabItemDirective, isSignal: true }, { propertyName: "labels", predicate: C80TabLabelDirective, isSignal: true }], ngImport: i0, template: "<div class=\"c80-tab-container\">\n <div class=\"c80-tab-header\">\n <div class=\"c80-tab-labels\">\n @for (tab of tabs(); track $index) {\n <button type=\"button\" class=\"c80-tab-label\" [class.active]=\"selectedIndex() === $index\" (click)=\"onTabClick($index)\">\n @if (getTabLabel($index); as labelTemplate) {\n <ng-container *ngTemplateOutlet=\"labelTemplate\" />\n }\n </button>\n }\n </div>\n </div>\n\n <div class=\"c80-tab-body\">\n @for (tab of tabs(); track $index) {\n @if (selectedIndex() === $index) {\n <div class=\"c80-tab-content\">\n <ng-container *ngTemplateOutlet=\"getTabContent($index)\" />\n </div>\n }\n }\n </div>\n</div>", styles: [".c80-tab-container{display:flex;flex-direction:column;height:100%}.c80-tab-header{border-bottom:1px solid #dee2e6;background:#f8f9fa}.c80-tab-labels{display:flex;gap:0;width:100%;max-height:40px}.c80-tab-labels button{padding:10px}.c80-tab-label{flex:1;min-width:120px;padding:16px;background:transparent;border:none;border-bottom:2px solid transparent;cursor:pointer;opacity:.7;transition:all .2s;display:flex;align-items:center;justify-content:center;gap:8px;font-family:inherit;font-size:14px;font-weight:500;color:inherit}.c80-tab-label:hover{opacity:.9;background:#0000000a}.c80-tab-label.active{opacity:1;border-bottom-color:#000;color:#000}.c80-tab-label:focus-visible{outline:none;outline-offset:-2px}.c80-tab-body{flex:1;overflow-y:auto;position:relative}.c80-tab-content{height:100%;animation:fadeIn .2s ease-in}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media(max-width:768px){.c80-tab-label{min-width:80px;padding:12px 8px}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
28
28
|
}
|
|
29
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type:
|
|
29
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TabComponent, decorators: [{
|
|
30
30
|
type: Component,
|
|
31
31
|
args: [{ selector: 'c80-tab', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"c80-tab-container\">\n <div class=\"c80-tab-header\">\n <div class=\"c80-tab-labels\">\n @for (tab of tabs(); track $index) {\n <button type=\"button\" class=\"c80-tab-label\" [class.active]=\"selectedIndex() === $index\" (click)=\"onTabClick($index)\">\n @if (getTabLabel($index); as labelTemplate) {\n <ng-container *ngTemplateOutlet=\"labelTemplate\" />\n }\n </button>\n }\n </div>\n </div>\n\n <div class=\"c80-tab-body\">\n @for (tab of tabs(); track $index) {\n @if (selectedIndex() === $index) {\n <div class=\"c80-tab-content\">\n <ng-container *ngTemplateOutlet=\"getTabContent($index)\" />\n </div>\n }\n }\n </div>\n</div>", styles: [".c80-tab-container{display:flex;flex-direction:column;height:100%}.c80-tab-header{border-bottom:1px solid #dee2e6;background:#f8f9fa}.c80-tab-labels{display:flex;gap:0;width:100%;max-height:40px}.c80-tab-labels button{padding:10px}.c80-tab-label{flex:1;min-width:120px;padding:16px;background:transparent;border:none;border-bottom:2px solid transparent;cursor:pointer;opacity:.7;transition:all .2s;display:flex;align-items:center;justify-content:center;gap:8px;font-family:inherit;font-size:14px;font-weight:500;color:inherit}.c80-tab-label:hover{opacity:.9;background:#0000000a}.c80-tab-label.active{opacity:1;border-bottom-color:#000;color:#000}.c80-tab-label:focus-visible{outline:none;outline-offset:-2px}.c80-tab-body{flex:1;overflow-y:auto;position:relative}.c80-tab-content{height:100%;animation:fadeIn .2s ease-in}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media(max-width:768px){.c80-tab-label{min-width:80px;padding:12px 8px}}\n"] }]
|
|
32
32
|
}], propDecorators: { tabs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => C80TabItemDirective), { isSignal: true }] }], labels: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => C80TabLabelDirective), { isSignal: true }] }], selectedIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIndex", required: false }] }, { type: i0.Output, args: ["selectedIndexChange"] }], selectedIndexChange: [{ type: i0.Output, args: ["selectedIndexChange"] }] } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"c80-tab.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/tab/c80-tab.component.ts","../../../../../libs/ui/src/lib/tab/c80-tab.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAoB,MAAM,eAAe,CAAC;AACrH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"c80-tab.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/tab/c80-tab.component.ts","../../../../../libs/ui/src/lib/tab/c80-tab.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAoB,MAAM,eAAe,CAAC;AACrH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;;AAW5E,MAAM,OAAO,YAAY;IACd,IAAI,GAAG,eAAe,CAAsB,mBAAmB,gDAAC,CAAC;IACjE,MAAM,GAAG,eAAe,CAAuB,oBAAoB,kDAAC,CAAC;IAE9E,oBAAoB;IACX,aAAa,GAAG,KAAK,CAAS,CAAC,yDAAC,CAAC;IACjC,mBAAmB,GAAG,MAAM,EAAU,CAAC;IAEhD,UAAU,CAAC,KAAa;QACtB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IAED,aAAa,CAAC,KAAa;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC3B,OAAO,GAAG,EAAE,OAAO,IAAI,IAAI,CAAC;IAC9B,CAAC;IAED,WAAW,CAAC,KAAa;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO,KAAK,EAAE,QAAQ,IAAI,IAAI,CAAC;IACjC,CAAC;wGAvBU,YAAY;4FAAZ,YAAY,mVAC8B,mBAAmB,yDAChB,oBAAoB,6CChB9E,mtBAsBM,u+BDbM,gBAAgB;;4FAKf,YAAY;kBATxB,SAAS;+BAEE,SAAS,cACP,IAAI,WACP,CAAC,gBAAgB,CAAC,mBAGV,uBAAuB,CAAC,MAAM;4FAGM,mBAAmB,2FAChB,oBAAoB","sourcesContent":["import { Component, output, model, ChangeDetectionStrategy, contentChildren, type TemplateRef } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { C80TabItemDirective } from './directives/c80-tab-item.directive';\nimport { C80TabLabelDirective } from './directives/c80-tab-label.directive';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-tab',\n standalone: true,\n imports: [NgTemplateOutlet],\n templateUrl: './c80-tab.component.html',\n styleUrl: './c80-tab.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class TabComponent {\n readonly tabs = contentChildren<C80TabItemDirective>(C80TabItemDirective);\n readonly labels = contentChildren<C80TabLabelDirective>(C80TabLabelDirective);\n\n /* v8 ignore next */\n readonly selectedIndex = model<number>(0);\n readonly selectedIndexChange = output<number>();\n\n onTabClick(index: number): void {\n this.selectedIndex.set(index);\n this.selectedIndexChange.emit(index);\n }\n\n getTabContent(index: number): TemplateRef<unknown> | null {\n const tabList = this.tabs();\n const tab = tabList[index];\n return tab?.content ?? null;\n }\n\n getTabLabel(index: number): TemplateRef<unknown> | null {\n const labelList = this.labels();\n const label = labelList[index];\n return label?.template ?? null;\n }\n}\n","<div class=\"c80-tab-container\">\n <div class=\"c80-tab-header\">\n <div class=\"c80-tab-labels\">\n @for (tab of tabs(); track $index) {\n <button type=\"button\" class=\"c80-tab-label\" [class.active]=\"selectedIndex() === $index\" (click)=\"onTabClick($index)\">\n @if (getTabLabel($index); as labelTemplate) {\n <ng-container *ngTemplateOutlet=\"labelTemplate\" />\n }\n </button>\n }\n </div>\n </div>\n\n <div class=\"c80-tab-body\">\n @for (tab of tabs(); track $index) {\n @if (selectedIndex() === $index) {\n <div class=\"c80-tab-content\">\n <ng-container *ngTemplateOutlet=\"getTabContent($index)\" />\n </div>\n }\n }\n </div>\n</div>"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c80-tab-item.directive.js","sourceRoot":"","sources":["../../../../../../libs/ui/src/lib/tab/directives/c80-tab-item.directive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;;AAO/D,MAAM,OAAO,mBAAmB;IACrB,OAAO,GAAG,MAAM,CAAC,CAAA,WAAoB,CAAA,CAAC,CAAC;wGADrC,mBAAmB;4FAAnB,mBAAmB;;4FAAnB,mBAAmB;kBAL/B,SAAS;mBAAC;oBACT,8DAA8D;oBAC9D,QAAQ,EAAE,WAAW;oBACrB,UAAU,EAAE,IAAI;iBACjB","sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[tabItem]',\n standalone: true,\n})\nexport class C80TabItemDirective {\n readonly content = inject(TemplateRef<unknown>);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c80-tab-label.directive.js","sourceRoot":"","sources":["../../../../../../libs/ui/src/lib/tab/directives/c80-tab-label.directive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;;AAO/D,MAAM,OAAO,oBAAoB;IACtB,QAAQ,GAAG,MAAM,CAAC,CAAA,WAAoB,CAAA,CAAC,CAAC;wGADtC,oBAAoB;4FAApB,oBAAoB;;4FAApB,oBAAoB;kBALhC,SAAS;mBAAC;oBACT,8DAA8D;oBAC9D,QAAQ,EAAE,YAAY;oBACtB,UAAU,EAAE,IAAI;iBACjB","sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[tabLabel]',\n standalone: true,\n})\nexport class C80TabLabelDirective {\n readonly template = inject(TemplateRef<unknown>);\n}\n"]}
|
package/esm2022/lib/tab/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { C80TabItemDirective } from './c80-tab-item.directive';
|
|
3
|
-
export { C80TabLabelDirective } from './c80-tab-label.directive';
|
|
1
|
+
export { TabComponent } from './c80-tab.component';
|
|
2
|
+
export { C80TabItemDirective } from './directives/c80-tab-item.directive';
|
|
3
|
+
export { C80TabLabelDirective } from './directives/c80-tab-label.directive';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/tab/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/tab/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC","sourcesContent":["export { TabComponent } from './c80-tab.component';\nexport { C80TabItemDirective } from './directives/c80-tab-item.directive';\nexport { C80TabLabelDirective } from './directives/c80-tab-label.directive';\nexport type { C80Tab } from './c80-tab.model';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-column-visibility.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-column-visibility.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;;AAEnE;;;;;;;GAOG;AAIH,MAAM,OAAO,4BAA4B;IAEtB,aAAa,GAAG,MAAM,CAAC,yBAAyB,CAAC,CAAC;IAClD,SAAS,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAE3D;;;;;;;OAOG;IACH,iBAAiB,CACf,
|
|
1
|
+
{"version":3,"file":"table-column-visibility.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-column-visibility.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, inject } from '@angular/core';\nimport type { TableColDef } from './table.types';\nimport { TableDataConverterService } from './table-data-converter.service';\nimport { TableDataUtilsService } from './table-data-utils.service';\n\n/**\n * Servicio para gestionar la lógica de visibilidad de columnas en tablas C80\n *\n * Maneja las reglas complejas de visibilidad basadas en:\n * - Configuración explícita (visible: false)\n * - Ocultación automática (hideIfAllValuesAreNull)\n * - Estado de creación y edición\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableColumnVisibilityService {\n\n private readonly dataConverter = inject(TableDataConverterService);\n private readonly dataUtils = inject(TableDataUtilsService);\n\n /**\n * Actualiza las keys de columnas visibles basándose en el estado actual\n * @param columns - Definiciones de columnas\n * @param data - Datos actuales de la tabla\n * @param creating - Si está en modo creación\n * @param editing - ID de fila en edición (null si no hay edición)\n * @returns Array de accessors de columnas visibles\n */\n updateVisibleKeys<T extends Record<string, unknown>>(\n columns: TableColDef[],\n data: T[],\n creating: boolean,\n editing: string | null\n ): string[] {\n const visibleColumns = columns.filter(col =>\n this.isColumnVisibleInHeader(col, data, creating, editing)\n );\n return visibleColumns.map(col => col.accessor);\n }\n\n /**\n * Determina si una columna debe ser visible basándose en su configuración y datos\n * Método unificado que maneja todos los casos de visibilidad\n * @param column - La definición de la columna\n * @param data - Datos actuales de la tabla\n * @param options - Opciones de contexto (creación, edición, fila específica)\n * @returns true si la columna debe ser visible\n */\n isColumnVisible<T extends Record<string, unknown>>(\n column: TableColDef,\n data: T[],\n options: {\n forceShowInCreation?: boolean;\n creating?: boolean;\n editing?: string | null;\n row?: T;\n } = {}\n ): boolean {\n // PRIORIDAD 1: Si visible está explícitamente establecido en false, SIEMPRE ocultar\n if (column.visible === false) {\n return false;\n }\n\n // Si no tiene hideIfAllValuesAreNull, mostrar siempre\n if (!column.hideIfAllValuesAreNull) {\n return true;\n }\n\n // PRIORIDAD 2: Para columnas con hideIfAllValuesAreNull, ocultar si el valor es falsy (excepto 0)\n // Esto aplica tanto en modo creación como edición\n\n // CONTEXTO: Modo creación\n if (options.creating) {\n // En creación, verificar el valor de la fila en creación si existe\n const creatingRow = options.row;\n if (creatingRow) {\n const cellValue = this.dataUtils.getCellValue(creatingRow, column.accessor);\n return !this.dataConverter.isValueEmpty(cellValue);\n }\n // Si no hay fila, ocultar (valor vacío por defecto)\n return false;\n }\n\n // CONTEXTO: Fila en edición\n if (options.editing !== undefined && options.editing !== null) {\n const editingRow = options.row ?? data.find(r => r['id'] === options.editing);\n if (editingRow) {\n const cellValue = this.dataUtils.getCellValue(editingRow, column.accessor);\n return !this.dataConverter.isValueEmpty(cellValue);\n }\n return false;\n }\n\n // CONTEXTO: Vista normal - verificar si todos los valores están vacíos\n return !this.areAllColumnValuesEmpty(column, data);\n }\n\n /**\n * Determina si una columna debe ser visible en los headers\n * Wrapper para mantener compatibilidad con API existente\n */\n isColumnVisibleInHeader<T extends Record<string, unknown>>(\n column: TableColDef,\n data: T[],\n creating: boolean,\n editing: string | null\n ): boolean {\n return this.isColumnVisible(column, data, { creating, editing });\n }\n\n /**\n * Determina si una columna debe ser visible en una fila específica\n * Wrapper para mantener compatibilidad con API existente\n */\n isColumnVisibleForRow<T extends Record<string, unknown>>(\n column: TableColDef,\n row: T,\n data: T[],\n editing: string | null\n ): boolean {\n return this.isColumnVisible(column, data, { editing, row });\n }\n\n /**\n * Verifica si todos los valores de una columna están vacíos/nulos\n */\n private areAllColumnValuesEmpty<T extends Record<string, unknown>>(\n column: TableColDef,\n data: T[]\n ): boolean {\n if (data.length === 0) {\n return true;\n }\n\n return data.every(row => {\n const value = this.dataUtils.getCellValue(row, column.accessor);\n return this.dataConverter.isValueEmpty(value);\n });\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-crud-state.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-crud-state.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE3D,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;;AAEnE;;;;;;;;GAQG;AAIH,MAAM,OAAO,qBAAqB;IAEf,iBAAiB,GAAG,MAAM,CAAC,4BAA4B,CAAC,CAAC;IACzD,SAAS,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAE3D;;OAEG;IACK,kBAAkB,CACxB,
|
|
1
|
+
{"version":3,"file":"table-crud-state.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-crud-state.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, signal, inject } from '@angular/core';\nimport type { TableColDef } from './table.types';\nimport { TableColumnVisibilityService } from './table-column-visibility.service';\nimport { TableDataUtilsService } from './table-data-utils.service';\n\n/**\n * Servicio para gestionar el estado CRUD (Crear, Leer, Actualizar, Eliminar) en tablas C80\n *\n * Maneja:\n * - Estado de creación y edición\n * - Gestión de datos temporales (newRow, editRow)\n * - Aplicación de valores dinámicos\n * - Validación y conversión de datos\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableCrudStateService {\n\n private readonly visibilityService = inject(TableColumnVisibilityService);\n private readonly dataUtils = inject(TableDataUtilsService);\n\n /**\n * Filtra columnas visibles y editables\n */\n private getEditableColumns<T extends Record<string, unknown>>(\n columns: TableColDef[],\n data: T[],\n includeHiddenIfNull: boolean\n ): TableColDef[] {\n return columns.filter(\n col => this.visibilityService.isColumnVisible(col, data, { forceShowInCreation: includeHiddenIfNull }) && !col.readOnly\n );\n }\n\n /**\n * Inicializa row para creación con valores por defecto\n */\n private initializeNewRow<T extends Record<string, unknown>>(\n columns: TableColDef[],\n data: T[]\n ): Partial<T> {\n const row: Partial<T> = {};\n for (const col of this.getEditableColumns(columns, data, true)) {\n const defaultValue = col.default === undefined ? '' : col.default;\n (row as Record<string, unknown>)[col.accessor] = defaultValue;\n }\n return row;\n }\n\n /**\n * Inicializa row para edición con valores actuales\n */\n private initializeEditRow<T extends Record<string, unknown>>(\n row: T,\n columns: TableColDef[],\n data: T[]\n ): Partial<T> {\n const edit: Partial<T> = {};\n for (const col of this.getEditableColumns(columns, data, true)) {\n const value = this.dataUtils.getCellValue(row, col.accessor);\n (edit as Record<string, unknown>)[col.accessor] = value;\n }\n return edit;\n }\n\n /**\n * Inicializa el estado CRUD para una nueva tabla\n * @returns Objeto con signals y métodos para gestión CRUD\n */\n createCrudState<T extends Record<string, unknown>>() {\n const creating = signal(false);\n const newRow = signal<Partial<T> | null>(null);\n const editing = signal<string | null>(null);\n const editRow = signal<Partial<T> | null>(null);\n\n return {\n creating: creating.asReadonly(),\n newRow: newRow.asReadonly(),\n editing: editing.asReadonly(),\n editRow: editRow.asReadonly(),\n startCreate: (columns: TableColDef[], data: T[]) => this.startCreate(creating, newRow, columns, data),\n cancelCreate: () => this.cancelCreate(creating, newRow),\n updateNewRow: (key: string, value: unknown) => this.updateRow(newRow, key, value),\n startEdit: (row: T, columns: TableColDef[], data: T[]) => this.startEdit({ editing, editRow }, row, columns, data),\n cancelEdit: () => this.cancelEdit(editing, editRow),\n updateEditRow: (key: string, value: unknown) => this.updateRow(editRow, key, value),\n applyInputValues: (partialValues: Partial<T>) => this.applyInputValues({ creating, newRow, editing, editRow }, partialValues),\n };\n }\n\n private startCreate<T extends Record<string, unknown>>(\n creating: ReturnType<typeof signal<boolean>>,\n newRow: ReturnType<typeof signal<Partial<T> | null>>,\n columns: TableColDef[],\n data: T[]\n ): void {\n creating.set(true);\n newRow.set(this.initializeNewRow(columns, data));\n }\n\n private cancelCreate<T extends Record<string, unknown>>(\n creating: ReturnType<typeof signal<boolean>>,\n newRow: ReturnType<typeof signal<Partial<T> | null>>\n ): void {\n creating.set(false);\n newRow.set(null);\n }\n\n private updateRow<T extends Record<string, unknown>>(\n rowSignal: ReturnType<typeof signal<Partial<T> | null>>,\n key: string,\n value: unknown\n ): void {\n const current = rowSignal();\n if (!current) return;\n rowSignal.set({ ...current, [key]: value });\n }\n\n private startEdit<T extends Record<string, unknown>>(\n signals: {\n editing: ReturnType<typeof signal<string | null>>;\n editRow: ReturnType<typeof signal<Partial<T> | null>>;\n },\n row: T,\n columns: TableColDef[],\n data: T[]\n ): void {\n signals.editing.set(row['id'] as string);\n signals.editRow.set(this.initializeEditRow(row, columns, data));\n }\n\n private cancelEdit<T extends Record<string, unknown>>(\n editing: ReturnType<typeof signal<string | null>>,\n editRow: ReturnType<typeof signal<Partial<T> | null>>\n ): void {\n editing.set(null);\n editRow.set(null);\n }\n\n private applyInputValues<T extends Record<string, unknown>>(\n signals: {\n creating: ReturnType<typeof signal<boolean>>;\n newRow: ReturnType<typeof signal<Partial<T> | null>>;\n editing: ReturnType<typeof signal<string | null>>;\n editRow: ReturnType<typeof signal<Partial<T> | null>>;\n },\n partialValues: Partial<T>\n ): void {\n if (!signals.creating() && signals.editing() === null) return;\n\n if (signals.creating()) {\n const currentRow = signals.newRow();\n if (currentRow) {\n signals.newRow.set({ ...currentRow, ...partialValues });\n }\n } else {\n const currentEditRow = signals.editRow();\n if (currentEditRow) {\n signals.editRow.set({ ...currentEditRow, ...partialValues });\n }\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-data-converter.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-data-converter.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;;AAG3C;;;;;GAKG;AAIH,MAAM,OAAO,yBAAyB;IAElC;;;;;;OAMG;IACH,gBAAgB,CAAC,KAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"table-data-converter.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-data-converter.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport type { TableColDef } from './table.types';\n\n/**\n * Servicio para conversión y validación de tipos de datos en tablas C80\n *\n * Maneja la conversión entre diferentes tipos de datos y la validación de valores vacíos.\n * Soporta los tipos: string, number, integer, boolean, password, enum\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableDataConverterService {\n\n /**\n * Convierte un valor de celda basándose en el tipo de columna o datos de muestra\n * @param value - Valor a convertir\n * @param col - Definición de la columna\n * @param sampleValue - Valor de muestra para inferir el tipo (opcional)\n * @returns Valor convertido al tipo apropiado\n */\n convertCellValue(value: unknown, col: TableColDef, sampleValue?: unknown): unknown {\n if (col.type === 'boolean') return this.toBoolean(value);\n if (col.type === 'number') return this.toNumber(value);\n if (col.type === 'integer') return this.toInteger(value);\n if (col.type === 'string' || col.type === 'password')\n return this.toStringValue(value);\n\n // Fallback: usar datos de muestra si están disponibles\n if (sampleValue) {\n if (typeof sampleValue === 'boolean') return this.toBoolean(value);\n if (typeof sampleValue === 'number') return this.toNumber(value);\n if (typeof sampleValue === 'string') return this.toStringValue(value);\n }\n\n return value;\n }\n\n /**\n * Convierte un valor a boolean usando mejores prácticas\n * @param value - Valor a convertir\n * @returns Valor booleano\n */\n toBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string')\n return value.trim().toLowerCase() === 'true' || value.trim() === '1';\n if (typeof value === 'number') return value === 1;\n return false;\n }\n\n /**\n * Convierte un valor a number usando mejores prácticas\n * @param value - Valor a convertir\n * @returns Número o undefined si no es válido\n */\n toNumber(value: unknown): number | undefined {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') return undefined;\n const num = Number(trimmed);\n return Number.isNaN(num) ? undefined : num;\n }\n if (typeof value === 'boolean') return value ? 1 : 0;\n return undefined;\n }\n\n /**\n * Convierte un valor a integer usando mejores prácticas\n * @param value - Valor a convertir\n * @returns Entero o undefined si no es válido\n */\n toInteger(value: unknown): number | undefined {\n if (typeof value === 'number') return Math.floor(value);\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') return undefined;\n const num = Number(trimmed);\n return Number.isNaN(num) ? undefined : Math.floor(num);\n }\n if (typeof value === 'boolean') return value ? 1 : 0;\n return undefined;\n }\n\n /**\n * Convierte un valor a string usando mejores prácticas, siempre stringifica objetos\n * @param value - Valor a convertir\n * @returns Cadena de texto\n */\n toStringValue(value: unknown): string {\n if (value == null) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean')\n return String(value);\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return '[object Object]';\n }\n }\n // Para funciones, símbolos, undefined, etc., devolver cadena vacía\n return '';\n }\n\n /**\n * Verifica si un valor individual está vacío/nulo\n * @param value - Valor a verificar\n * @returns true si el valor se considera vacío\n */\n isValueEmpty(value: unknown): boolean {\n // Considerar vacío: null, undefined, ''\n if (value === null || value === undefined || value === '') {\n return true;\n }\n\n // Para números y booleanos, siempre son valores válidos\n if (typeof value === 'number' || typeof value === 'boolean') {\n return false;\n }\n\n // Para arrays vacíos\n if (Array.isArray(value)) {\n return value.length === 0;\n }\n\n // Para objetos vacíos\n if (typeof value === 'object' && value !== null) {\n return Object.keys(value).length === 0;\n }\n\n return false;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-data-utils.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-data-utils.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport type { C80TableColDef } from './table.types';\n\n/**\n * Servicio para utilidades de manipulación de datos en tablas C80\n *\n * Proporciona métodos para:\n * - Acceso a valores de celdas (incluyendo propiedades anidadas)\n * - Formateo de valores para display\n * - Gestión de enums y colores\n * - Ordenamiento de datos\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableDataUtilsService {\n\n /**\n * Obtiene el valor de una celda usando el accessor, soportando notación de punto para propiedades anidadas\n * @param row - La fila de datos\n * @param accessor - El accessor de la columna\n * @returns El valor de la celda\n */\n getCellValue<T extends Record<string, unknown>>(row: T, accessor: string): unknown {\n if (accessor.includes('.')) {\n return this.getNestedValue(row, accessor);\n }\n return (row as Record<string, unknown>)[accessor];\n }\n\n /**\n * Obtiene el valor de un objeto usando notación de punto (ej: 'task.name')\n * @param obj - Objeto del cual obtener el valor\n * @param accessor - Ruta de acceso usando notación de punto\n * @returns El valor anidado o undefined\n */\n getNestedValue(obj: Record<string, unknown>, accessor: string): unknown {\n return accessor.split('.').reduce((current, key) => {\n return current && typeof current === 'object' ? (current as Record<string, unknown>)[key] : undefined;\n }, obj as unknown);\n }\n\n /**\n * Devuelve el valor de display para una celda, mostrando '-' para valores falsy excepto 0, false y objetos/arrays vacíos\n * @param value - Valor a formatear\n * @param col - Definición de columna (opcional) para formateo específico por tipo\n * @returns Cadena formateada para display\n */\n getDisplayValue(value: unknown, col?: C80TableColDef): string {\n return this.formatValueByType(value, col);\n }\n\n private formatValueByType(value: unknown, col?: C80TableColDef): string {\n if (value === 0) return '0';\n if (value === false) return 'false';\n if (col?.type === 'date' && value) return this.formatDateValue(value);\n if (typeof value === 'object' && value !== null) return this.formatObjectValue(value);\n if (!value) return '-';\n return this.formatPrimitiveValue(value);\n }\n\n private formatPrimitiveValue(value: unknown): string {\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n return '-';\n }\n\n /**\n * Formatea un valor de fecha a formato legible\n * @param value - Valor de fecha (Date, string ISO, timestamp)\n * @returns Fecha formateada como DD/MM/YYYY HH:MM\n */\n private formatDateValue(value: unknown): string {\n try {\n const date = this.parseDate(value);\n if (!date || Number.isNaN(date.getTime())) return '-';\n\n const day = String(date.getDate()).padStart(2, '0');\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const year = date.getFullYear();\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n\n return `${day}/${month}/${year} ${hours}:${minutes}`;\n } catch {\n return '-';\n }\n }\n\n private parseDate(value: unknown): Date | null {\n if (value instanceof Date) return value;\n if (typeof value === 'string' || typeof value === 'number') return new Date(value);\n return null;\n }\n\n private formatObjectValue(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return '[object Object]';\n }\n } /**\n * Obtiene el texto de display para un valor enum\n * @param value - Valor del enum\n * @param col - Definición de la columna\n * @returns Texto formateado del enum\n */\n getEnumDisplayValue(value: unknown, col: C80TableColDef): string {\n if (!col.enum || (value !== 0 && !value)) {\n return '-';\n }\n const displayValue = col.enum[value as string | number];\n return (\n displayValue ||\n (typeof value === 'string' || typeof value === 'number'\n ? String(value)\n : '-')\n );\n }\n\n /**\n * Obtiene las opciones del enum como array para dropdowns select\n * @param col - Definición de la columna\n * @returns Array de opciones con value y label\n */\n getEnumOptions(col: C80TableColDef): { value: string | number; label: string }[] {\n if (!col.enum) return [];\n return Object.entries(col.enum).map(([value, label]) => ({\n value: Number.isNaN(Number(value)) ? value : Number(value),\n label,\n }));\n }\n\n /**\n * Obtiene el color CSS para un valor de celda basado en la configuración de color de la columna\n * @param value - Valor de la celda\n * @param col - Definición de la columna\n * @returns Color CSS o undefined si no hay configuración\n */\n getCellColor(value: unknown, col: C80TableColDef): string | undefined {\n if (!col.color || (value !== 0 && !value)) {\n return undefined;\n }\n return col.color[value as string | number];\n }\n\n /**\n * Aplica ordenamiento a los items basándose en las columnas con configuración de orden\n * @param items - Array de items a ordenar (se modifica in-place)\n * @param columns - Definiciones de columnas\n */\n applySorting<T extends Record<string, unknown>>(items: T[], columns: C80TableColDef[]): void {\n const orderedColumns = columns.filter((col) => col.order);\n if (orderedColumns.length > 0) {\n for (const col of orderedColumns) {\n items.sort((a, b) => {\n const valueA = this.getCellValue(a, col.accessor) as string | number;\n const valueB = this.getCellValue(b, col.accessor) as string | number;\n\n if (col.order === 'ASC') {\n if (valueA > valueB) return 1;\n if (valueA < valueB) return -1;\n return 0;\n } else {\n if (valueA < valueB) return 1;\n if (valueA > valueB) return -1;\n return 0;\n }\n });\n }\n }\n }\n\n /**\n * Calcula el max-height de la tabla basado en el tamaño\n * @param size - Tamaño configurado (0 = sin límite)\n * @returns String CSS para max-height o undefined si sin límite\n */\n getTableMaxHeight(size: number): string | undefined {\n if (size <= 0) {\n return undefined; // Sin límite de altura\n }\n // Altura base de 400px * size\n const baseHeight = 400;\n const maxHeight = Math.round(baseHeight * size);\n return `${maxHeight}px`;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"table-data-utils.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-data-utils.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport type { TableColDef } from './table.types';\n\n/**\n * Servicio para utilidades de manipulación de datos en tablas C80\n *\n * Proporciona métodos para:\n * - Acceso a valores de celdas (incluyendo propiedades anidadas)\n * - Formateo de valores para display\n * - Gestión de enums y colores\n * - Ordenamiento de datos\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableDataUtilsService {\n\n /**\n * Obtiene el valor de una celda usando el accessor, soportando notación de punto para propiedades anidadas\n * @param row - La fila de datos\n * @param accessor - El accessor de la columna\n * @returns El valor de la celda\n */\n getCellValue<T extends Record<string, unknown>>(row: T, accessor: string): unknown {\n if (accessor.includes('.')) {\n return this.getNestedValue(row, accessor);\n }\n return (row as Record<string, unknown>)[accessor];\n }\n\n /**\n * Obtiene el valor de un objeto usando notación de punto (ej: 'task.name')\n * @param obj - Objeto del cual obtener el valor\n * @param accessor - Ruta de acceso usando notación de punto\n * @returns El valor anidado o undefined\n */\n getNestedValue(obj: Record<string, unknown>, accessor: string): unknown {\n return accessor.split('.').reduce((current, key) => {\n return current && typeof current === 'object' ? (current as Record<string, unknown>)[key] : undefined;\n }, obj as unknown);\n }\n\n /**\n * Devuelve el valor de display para una celda, mostrando '-' para valores falsy excepto 0, false y objetos/arrays vacíos\n * @param value - Valor a formatear\n * @param col - Definición de columna (opcional) para formateo específico por tipo\n * @returns Cadena formateada para display\n */\n getDisplayValue(value: unknown, col?: TableColDef): string {\n return this.formatValueByType(value, col);\n }\n\n private formatValueByType(value: unknown, col?: TableColDef): string {\n if (value === 0) return '0';\n if (value === false) return 'false';\n if (col?.type === 'date' && value) return this.formatDateValue(value);\n if (typeof value === 'object' && value !== null) return this.formatObjectValue(value);\n if (!value) return '-';\n return this.formatPrimitiveValue(value);\n }\n\n private formatPrimitiveValue(value: unknown): string {\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n return '-';\n }\n\n /**\n * Formatea un valor de fecha a formato legible\n * @param value - Valor de fecha (Date, string ISO, timestamp)\n * @returns Fecha formateada como DD/MM/YYYY HH:MM\n */\n private formatDateValue(value: unknown): string {\n try {\n const date = this.parseDate(value);\n if (!date || Number.isNaN(date.getTime())) return '-';\n\n const day = String(date.getDate()).padStart(2, '0');\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const year = date.getFullYear();\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n\n return `${day}/${month}/${year} ${hours}:${minutes}`;\n } catch {\n return '-';\n }\n }\n\n private parseDate(value: unknown): Date | null {\n if (value instanceof Date) return value;\n if (typeof value === 'string' || typeof value === 'number') return new Date(value);\n return null;\n }\n\n private formatObjectValue(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return '[object Object]';\n }\n } /**\n * Obtiene el texto de display para un valor enum\n * @param value - Valor del enum\n * @param col - Definición de la columna\n * @returns Texto formateado del enum\n */\n getEnumDisplayValue(value: unknown, col: TableColDef): string {\n if (!col.enum || (value !== 0 && !value)) {\n return '-';\n }\n const displayValue = col.enum[value as string | number];\n return (\n displayValue ||\n (typeof value === 'string' || typeof value === 'number'\n ? String(value)\n : '-')\n );\n }\n\n /**\n * Obtiene las opciones del enum como array para dropdowns select\n * @param col - Definición de la columna\n * @returns Array de opciones con value y label\n */\n getEnumOptions(col: TableColDef): { value: string | number; label: string }[] {\n if (!col.enum) return [];\n return Object.entries(col.enum).map(([value, label]) => ({\n value: Number.isNaN(Number(value)) ? value : Number(value),\n label,\n }));\n }\n\n /**\n * Obtiene el color CSS para un valor de celda basado en la configuración de color de la columna\n * @param value - Valor de la celda\n * @param col - Definición de la columna\n * @returns Color CSS o undefined si no hay configuración\n */\n getCellColor(value: unknown, col: TableColDef): string | undefined {\n if (!col.color || (value !== 0 && !value)) {\n return undefined;\n }\n return col.color[value as string | number];\n }\n\n /**\n * Aplica ordenamiento a los items basándose en las columnas con configuración de orden\n * @param items - Array de items a ordenar (se modifica in-place)\n * @param columns - Definiciones de columnas\n */\n applySorting<T extends Record<string, unknown>>(items: T[], columns: TableColDef[]): void {\n const orderedColumns = columns.filter((col) => col.order);\n if (orderedColumns.length > 0) {\n for (const col of orderedColumns) {\n items.sort((a, b) => {\n const valueA = this.getCellValue(a, col.accessor) as string | number;\n const valueB = this.getCellValue(b, col.accessor) as string | number;\n\n if (col.order === 'ASC') {\n if (valueA > valueB) return 1;\n if (valueA < valueB) return -1;\n return 0;\n } else {\n if (valueA < valueB) return 1;\n if (valueA > valueB) return -1;\n return 0;\n }\n });\n }\n }\n }\n\n /**\n * Calcula el max-height de la tabla basado en el tamaño\n * @param size - Tamaño configurado (0 = sin límite)\n * @returns String CSS para max-height o undefined si sin límite\n */\n getTableMaxHeight(size: number): string | undefined {\n if (size <= 0) {\n return undefined; // Sin límite de altura\n }\n // Altura base de 400px * size\n const baseHeight = 400;\n const maxHeight = Math.round(baseHeight * size);\n return `${maxHeight}px`;\n }\n}\n"]}
|