shirkasoft-ui-components 1.0.21 → 1.0.23
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.
|
@@ -18,111 +18,111 @@ const icons$6 = {
|
|
|
18
18
|
'eye-off': LucideEyeOff,
|
|
19
19
|
};
|
|
20
20
|
class TextFieldComponent {
|
|
21
|
-
cdr = inject(ChangeDetectorRef);
|
|
22
|
-
id = input('', ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
23
|
-
formatCard = input(false, ...(ngDevMode ? [{ debugName: "formatCard" }] : /* istanbul ignore next */ []));
|
|
24
|
-
preventNegative = input(false, ...(ngDevMode ? [{ debugName: "preventNegative" }] : /* istanbul ignore next */ []));
|
|
25
|
-
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
26
|
-
type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
27
|
-
numbersOnly = input(false, ...(ngDevMode ? [{ debugName: "numbersOnly" }] : /* istanbul ignore next */ []));
|
|
28
|
-
allowDecimals = input(false, ...(ngDevMode ? [{ debugName: "allowDecimals" }] : /* istanbul ignore next */ []));
|
|
29
|
-
maxLength = input(undefined, ...(ngDevMode ? [{ debugName: "maxLength" }] : /* istanbul ignore next */ []));
|
|
30
|
-
placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
31
|
-
errorMessages = input({}, ...(ngDevMode ? [{ debugName: "errorMessages" }] : /* istanbul ignore next */ []));
|
|
32
|
-
formGroup = input(undefined, ...(ngDevMode ? [{ debugName: "formGroup" }] : /* istanbul ignore next */ []));
|
|
33
|
-
control = input(undefined, ...(ngDevMode ? [{ debugName: "control" }] : /* istanbul ignore next */ []));
|
|
34
|
-
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
35
|
-
errorMessage = input('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
|
|
36
|
-
isTextArea = input(false, ...(ngDevMode ? [{ debugName: "isTextArea" }] : /* istanbul ignore next */ []));
|
|
37
|
-
textAreaHeight = input('h-28', ...(ngDevMode ? [{ debugName: "textAreaHeight" }] : /* istanbul ignore next */ []));
|
|
38
|
-
searchMode = input(false, ...(ngDevMode ? [{ debugName: "searchMode" }] : /* istanbul ignore next */ []));
|
|
39
|
-
displayValue = input('', ...(ngDevMode ? [{ debugName: "displayValue" }] : /* istanbul ignore next */ []));
|
|
40
|
-
autocomplete = input('new-password', ...(ngDevMode ? [{ debugName: "autocomplete" }] : /* istanbul ignore next */ []));
|
|
41
|
-
searchButtonClick = output();
|
|
42
|
-
getIcon = (name) => icons$6[name] ?? LucideEye;
|
|
43
|
-
inputElement = viewChild('input', ...(ngDevMode ? [{ debugName: "inputElement" }] : /* istanbul ignore next */ []));
|
|
44
|
-
textareaElement = viewChild('textarea', ...(ngDevMode ? [{ debugName: "textareaElement" }] : /* istanbul ignore next */ []));
|
|
45
|
-
_value = signal('', ...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
|
|
46
|
-
_disabledState = signal(false, ...(ngDevMode ? [{ debugName: "_disabledState" }] : /* istanbul ignore next */ []));
|
|
47
|
-
showPassword = signal(false, ...(ngDevMode ? [{ debugName: "showPassword" }] : /* istanbul ignore next */ []));
|
|
48
|
-
hadError = signal(false, ...(ngDevMode ? [{ debugName: "hadError" }] : /* istanbul ignore next */ []));
|
|
49
|
-
errorTracker = signal(0, ...(ngDevMode ? [{ debugName: "errorTracker" }] : /* istanbul ignore next */ []));
|
|
50
|
-
displayLabel = computed(() => {
|
|
51
|
-
if (this.searchMode() && this.displayValue()) {
|
|
52
|
-
return this.displayValue();
|
|
53
|
-
}
|
|
54
|
-
return '';
|
|
55
|
-
}, ...(ngDevMode ? [{ debugName: "displayLabel" }] : /* istanbul ignore next */ []));
|
|
56
|
-
subscribed = signal(false, ...(ngDevMode ? [{ debugName: "subscribed" }] : /* istanbul ignore next */ []));
|
|
57
|
-
isDisabled = computed(() => this.disabled() || this._disabledState(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
58
|
-
value = computed(() => this._value(), ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
59
|
-
actualControl = computed(() => {
|
|
60
|
-
const ctrl = this.control();
|
|
61
|
-
if (ctrl)
|
|
62
|
-
return ctrl;
|
|
63
|
-
const fg = this.formGroup();
|
|
64
|
-
const lbl = this.label();
|
|
65
|
-
if (fg && lbl) {
|
|
66
|
-
return fg.get(lbl);
|
|
67
|
-
}
|
|
68
|
-
return undefined;
|
|
69
|
-
}, ...(ngDevMode ? [{ debugName: "actualControl" }] : /* istanbul ignore next */ []));
|
|
70
|
-
shouldShowError = computed(() => {
|
|
71
|
-
this.errorTracker();
|
|
72
|
-
const ctrl = this.actualControl();
|
|
73
|
-
return ctrl?.invalid && (ctrl?.dirty || ctrl?.touched);
|
|
74
|
-
}, ...(ngDevMode ? [{ debugName: "shouldShowError" }] : /* istanbul ignore next */ []));
|
|
75
|
-
wasFixedError = computed(() => {
|
|
76
|
-
this.errorTracker();
|
|
77
|
-
const ctrl = this.actualControl();
|
|
78
|
-
return this.hadError() && ctrl?.valid && ctrl?.touched;
|
|
79
|
-
}, ...(ngDevMode ? [{ debugName: "wasFixedError" }] : /* istanbul ignore next */ []));
|
|
80
|
-
getErrorMessages = computed(() => {
|
|
81
|
-
this.errorTracker();
|
|
82
|
-
const customError = this.errorMessage();
|
|
83
|
-
if (customError) {
|
|
84
|
-
return [customError];
|
|
85
|
-
}
|
|
86
|
-
const ctrl = this.actualControl();
|
|
87
|
-
if (!ctrl?.errors)
|
|
88
|
-
return [];
|
|
89
|
-
const customErrors = this.errorMessages();
|
|
90
|
-
const t = this.transloco;
|
|
91
|
-
return Object.keys(ctrl.errors).map((errorKey) => {
|
|
92
|
-
if (customErrors[errorKey])
|
|
93
|
-
return customErrors[errorKey];
|
|
94
|
-
switch (errorKey) {
|
|
95
|
-
case 'required':
|
|
96
|
-
return t.translate('validation.required');
|
|
97
|
-
case 'email':
|
|
98
|
-
return t.translate('validation.email');
|
|
99
|
-
case 'minlength':
|
|
100
|
-
return t.translate('validation.minlength', {
|
|
101
|
-
min: ctrl.errors['minlength'].requiredLength,
|
|
102
|
-
});
|
|
103
|
-
case 'maxlength':
|
|
104
|
-
return t.translate('validation.maxlength', {
|
|
105
|
-
max: ctrl.errors['maxlength'].requiredLength,
|
|
106
|
-
});
|
|
107
|
-
case 'pattern':
|
|
108
|
-
return t.translate('validation.pattern');
|
|
109
|
-
default:
|
|
110
|
-
return t.translate('validation.invalid');
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
}, ...(ngDevMode ? [{ debugName: "getErrorMessages" }] : /* istanbul ignore next */ []));
|
|
114
|
-
effectiveType = computed(() => {
|
|
115
|
-
if (this.isTextArea())
|
|
116
|
-
return 'text';
|
|
117
|
-
if (this.type() === 'password' && this.showPassword())
|
|
118
|
-
return 'text';
|
|
119
|
-
return this.type();
|
|
120
|
-
}, ...(ngDevMode ? [{ debugName: "effectiveType" }] : /* istanbul ignore next */ []));
|
|
121
|
-
transloco = inject(TranslocoService);
|
|
122
|
-
onChange = () => { };
|
|
123
|
-
onTouched = () => { };
|
|
124
|
-
destroyRef = inject(DestroyRef);
|
|
125
21
|
constructor() {
|
|
22
|
+
this.cdr = inject(ChangeDetectorRef);
|
|
23
|
+
this.id = input('', ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
24
|
+
this.formatCard = input(false, ...(ngDevMode ? [{ debugName: "formatCard" }] : /* istanbul ignore next */ []));
|
|
25
|
+
this.preventNegative = input(false, ...(ngDevMode ? [{ debugName: "preventNegative" }] : /* istanbul ignore next */ []));
|
|
26
|
+
this.label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
27
|
+
this.type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
28
|
+
this.numbersOnly = input(false, ...(ngDevMode ? [{ debugName: "numbersOnly" }] : /* istanbul ignore next */ []));
|
|
29
|
+
this.allowDecimals = input(false, ...(ngDevMode ? [{ debugName: "allowDecimals" }] : /* istanbul ignore next */ []));
|
|
30
|
+
this.maxLength = input(undefined, ...(ngDevMode ? [{ debugName: "maxLength" }] : /* istanbul ignore next */ []));
|
|
31
|
+
this.placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
32
|
+
this.errorMessages = input({}, ...(ngDevMode ? [{ debugName: "errorMessages" }] : /* istanbul ignore next */ []));
|
|
33
|
+
this.formGroup = input(undefined, ...(ngDevMode ? [{ debugName: "formGroup" }] : /* istanbul ignore next */ []));
|
|
34
|
+
this.control = input(undefined, ...(ngDevMode ? [{ debugName: "control" }] : /* istanbul ignore next */ []));
|
|
35
|
+
this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
36
|
+
this.errorMessage = input('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
|
|
37
|
+
this.isTextArea = input(false, ...(ngDevMode ? [{ debugName: "isTextArea" }] : /* istanbul ignore next */ []));
|
|
38
|
+
this.textAreaHeight = input('h-28', ...(ngDevMode ? [{ debugName: "textAreaHeight" }] : /* istanbul ignore next */ []));
|
|
39
|
+
this.searchMode = input(false, ...(ngDevMode ? [{ debugName: "searchMode" }] : /* istanbul ignore next */ []));
|
|
40
|
+
this.displayValue = input('', ...(ngDevMode ? [{ debugName: "displayValue" }] : /* istanbul ignore next */ []));
|
|
41
|
+
this.autocomplete = input('new-password', ...(ngDevMode ? [{ debugName: "autocomplete" }] : /* istanbul ignore next */ []));
|
|
42
|
+
this.searchButtonClick = output();
|
|
43
|
+
this.getIcon = (name) => icons$6[name] ?? LucideEye;
|
|
44
|
+
this.inputElement = viewChild('input', ...(ngDevMode ? [{ debugName: "inputElement" }] : /* istanbul ignore next */ []));
|
|
45
|
+
this.textareaElement = viewChild('textarea', ...(ngDevMode ? [{ debugName: "textareaElement" }] : /* istanbul ignore next */ []));
|
|
46
|
+
this._value = signal('', ...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
|
|
47
|
+
this._disabledState = signal(false, ...(ngDevMode ? [{ debugName: "_disabledState" }] : /* istanbul ignore next */ []));
|
|
48
|
+
this.showPassword = signal(false, ...(ngDevMode ? [{ debugName: "showPassword" }] : /* istanbul ignore next */ []));
|
|
49
|
+
this.hadError = signal(false, ...(ngDevMode ? [{ debugName: "hadError" }] : /* istanbul ignore next */ []));
|
|
50
|
+
this.errorTracker = signal(0, ...(ngDevMode ? [{ debugName: "errorTracker" }] : /* istanbul ignore next */ []));
|
|
51
|
+
this.displayLabel = computed(() => {
|
|
52
|
+
if (this.searchMode() && this.displayValue()) {
|
|
53
|
+
return this.displayValue();
|
|
54
|
+
}
|
|
55
|
+
return '';
|
|
56
|
+
}, ...(ngDevMode ? [{ debugName: "displayLabel" }] : /* istanbul ignore next */ []));
|
|
57
|
+
this.subscribed = signal(false, ...(ngDevMode ? [{ debugName: "subscribed" }] : /* istanbul ignore next */ []));
|
|
58
|
+
this.isDisabled = computed(() => this.disabled() || this._disabledState(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
59
|
+
this.value = computed(() => this._value(), ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
60
|
+
this.actualControl = computed(() => {
|
|
61
|
+
const ctrl = this.control();
|
|
62
|
+
if (ctrl)
|
|
63
|
+
return ctrl;
|
|
64
|
+
const fg = this.formGroup();
|
|
65
|
+
const lbl = this.label();
|
|
66
|
+
if (fg && lbl) {
|
|
67
|
+
return fg.get(lbl);
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}, ...(ngDevMode ? [{ debugName: "actualControl" }] : /* istanbul ignore next */ []));
|
|
71
|
+
this.shouldShowError = computed(() => {
|
|
72
|
+
this.errorTracker();
|
|
73
|
+
const ctrl = this.actualControl();
|
|
74
|
+
return ctrl?.invalid && (ctrl?.dirty || ctrl?.touched);
|
|
75
|
+
}, ...(ngDevMode ? [{ debugName: "shouldShowError" }] : /* istanbul ignore next */ []));
|
|
76
|
+
this.wasFixedError = computed(() => {
|
|
77
|
+
this.errorTracker();
|
|
78
|
+
const ctrl = this.actualControl();
|
|
79
|
+
return this.hadError() && ctrl?.valid && ctrl?.touched;
|
|
80
|
+
}, ...(ngDevMode ? [{ debugName: "wasFixedError" }] : /* istanbul ignore next */ []));
|
|
81
|
+
this.getErrorMessages = computed(() => {
|
|
82
|
+
this.errorTracker();
|
|
83
|
+
const customError = this.errorMessage();
|
|
84
|
+
if (customError) {
|
|
85
|
+
return [customError];
|
|
86
|
+
}
|
|
87
|
+
const ctrl = this.actualControl();
|
|
88
|
+
if (!ctrl?.errors)
|
|
89
|
+
return [];
|
|
90
|
+
const customErrors = this.errorMessages();
|
|
91
|
+
const t = this.transloco;
|
|
92
|
+
return Object.keys(ctrl.errors).map((errorKey) => {
|
|
93
|
+
if (customErrors[errorKey])
|
|
94
|
+
return customErrors[errorKey];
|
|
95
|
+
switch (errorKey) {
|
|
96
|
+
case 'required':
|
|
97
|
+
return t.translate('validation.required');
|
|
98
|
+
case 'email':
|
|
99
|
+
return t.translate('validation.email');
|
|
100
|
+
case 'minlength':
|
|
101
|
+
return t.translate('validation.minlength', {
|
|
102
|
+
min: ctrl.errors['minlength'].requiredLength,
|
|
103
|
+
});
|
|
104
|
+
case 'maxlength':
|
|
105
|
+
return t.translate('validation.maxlength', {
|
|
106
|
+
max: ctrl.errors['maxlength'].requiredLength,
|
|
107
|
+
});
|
|
108
|
+
case 'pattern':
|
|
109
|
+
return t.translate('validation.pattern');
|
|
110
|
+
default:
|
|
111
|
+
return t.translate('validation.invalid');
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}, ...(ngDevMode ? [{ debugName: "getErrorMessages" }] : /* istanbul ignore next */ []));
|
|
115
|
+
this.effectiveType = computed(() => {
|
|
116
|
+
if (this.isTextArea())
|
|
117
|
+
return 'text';
|
|
118
|
+
if (this.type() === 'password' && this.showPassword())
|
|
119
|
+
return 'text';
|
|
120
|
+
return this.type();
|
|
121
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveType" }] : /* istanbul ignore next */ []));
|
|
122
|
+
this.transloco = inject(TranslocoService);
|
|
123
|
+
this.onChange = () => { };
|
|
124
|
+
this.onTouched = () => { };
|
|
125
|
+
this.destroyRef = inject(DestroyRef);
|
|
126
126
|
effect(() => {
|
|
127
127
|
const ctrl = this.actualControl();
|
|
128
128
|
const shouldDisable = this.isDisabled();
|
|
@@ -294,14 +294,14 @@ class TextFieldComponent {
|
|
|
294
294
|
this._disabledState.set(isDisabled);
|
|
295
295
|
this.cdr.markForCheck();
|
|
296
296
|
}
|
|
297
|
-
static
|
|
298
|
-
static
|
|
297
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TextFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
298
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: TextFieldComponent, isStandalone: true, selector: "shk-text-field", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, formatCard: { classPropertyName: "formatCard", publicName: "formatCard", isSignal: true, isRequired: false, transformFunction: null }, preventNegative: { classPropertyName: "preventNegative", publicName: "preventNegative", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, numbersOnly: { classPropertyName: "numbersOnly", publicName: "numbersOnly", isSignal: true, isRequired: false, transformFunction: null }, allowDecimals: { classPropertyName: "allowDecimals", publicName: "allowDecimals", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: true, isRequired: false, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: false, transformFunction: null }, control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, isTextArea: { classPropertyName: "isTextArea", publicName: "isTextArea", isSignal: true, isRequired: false, transformFunction: null }, textAreaHeight: { classPropertyName: "textAreaHeight", publicName: "textAreaHeight", isSignal: true, isRequired: false, transformFunction: null }, searchMode: { classPropertyName: "searchMode", publicName: "searchMode", isSignal: true, isRequired: false, transformFunction: null }, displayValue: { classPropertyName: "displayValue", publicName: "displayValue", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchButtonClick: "searchButtonClick" }, providers: [
|
|
299
299
|
{
|
|
300
300
|
provide: NG_VALUE_ACCESSOR,
|
|
301
301
|
useExisting: forwardRef(() => TextFieldComponent),
|
|
302
302
|
multi: true,
|
|
303
303
|
},
|
|
304
|
-
], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["input"], descendants: true, isSignal: true }, { propertyName: "textareaElement", first: true, predicate: ["textarea"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"relative mb-4\">\n @if (label()) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] mb-1\">\n {{ label() }}\n </div>\n }\n\n <div class=\"relative\">\n @if (!isTextArea()) {\n <div class=\"flex\">\n @if (searchMode()) {\n @let isDisabledSearch = actualControl()?.disabled || isDisabled();\n <input\n #input\n [id]=\"id()\"\n type=\"text\"\n [value]=\"displayValue() || ''\"\n [placeholder]=\"placeholder() || label()\"\n [readOnly]=\"true\"\n [disabled]=\"isDisabledSearch\"\n (click)=\"!isDisabledSearch && searchButtonClick.emit()\"\n (keydown.enter)=\"!isDisabledSearch && searchButtonClick.emit()\"\n (blur)=\"onBlur()\"\n autocomplete=\"off\"\n [class.cursor-pointer]=\"!isDisabledSearch\"\n [class.cursor-not-allowed]=\"isDisabledSearch\"\n [class._shk-bg-surface-50]=\"isDisabledSearch\"\n [class.dark:[background-color:var(--shk-surface-100)]]=\"isDisabledSearch\"\n [class._shk-text-surface-400]=\"isDisabledSearch\"\n [class.dark:[color:var(--shk-surface-400)]]=\"isDisabledSearch\"\n class=\"block w-full px-3 py-2 _shk-text-surface-700 dark:[color:var(--shk-surface-700)] _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border rounded-l-lg transition-colors placeholder:[color:var(--shk-surface-400)] dark:placeholder:[color:var(--shk-surface-400)] focus:[background-color:var(--shk-surface-50)] dark:focus:[background-color:var(--shk-surface-100)] sm:text-sm\"\n [ngClass]=\"{\n 'border-red-500': shouldShowError() && !isDisabledSearch,\n '_shk-border': !shouldShowError() || isDisabledSearch,\n 'cursor-pointer': !isDisabledSearch,\n 'cursor-not-allowed _shk-text-surface-400 dark:[color:var(--shk-surface-400)]': isDisabledSearch\n }\"\n />\n <button\n type=\"button\"\n (click)=\"searchButtonClick.emit()\"\n tabindex=\"-1\"\n [disabled]=\"isDisabledSearch\"\n class=\"px-3 flex items-center justify-center shrink-0 _shk-bg-primary hover:[background-color:var(--shk-primary-700)] text-white border _shk-border-primary rounded-r-lg transition-colors duration-200 disabled:[background-color:var(--shk-surface-300)] dark:disabled:[background-color:var(--shk-surface-200)] disabled:[border-color:var(--shk-surface-300)] dark:disabled:[border-color:var(--shk-surface-200)] disabled:cursor-not-allowed\"\n >\n <svg [lucideIcon]=\"getIcon('search')\" class=\"w-4 h-4\"></svg>\n </button>\n }\n\n @if (!searchMode()) {\n <input\n #input\n [id]=\"id()\"\n [maxlength]=\"maxLength() || (formatCard() ? 19 : null)\"\n [min]=\"type() === 'number' && preventNegative() ? '0' : null\"\n (keypress)=\"type() === 'number' || numbersOnly() ? numberValidation($event) : null\"\n [type]=\"effectiveType()\"\n [formControl]=\"$any(actualControl())\"\n [placeholder]=\"placeholder() || label()\"\n (input)=\"onInput($event)\"\n [autocomplete]=\"autocomplete()\"\n (blur)=\"onBlur()\"\n class=\"block w-full px-3 py-2 _shk-text-surface-700 dark:[color:var(--shk-surface-700)] _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border rounded-lg transition-colors placeholder:[color:var(--shk-surface-400)] dark:placeholder:[color:var(--shk-surface-400)] focus:outline-none focus:[background-color:var(--shk-surface-50)] dark:focus:[background-color:var(--shk-surface-100)] focus:ring-1 disabled:[background-color:var(--shk-surface-50)] dark:disabled:[background-color:var(--shk-surface-100)] disabled:cursor-not-allowed sm:text-sm\"\n [ngClass]=\"{\n 'border-red-500 focus:border-red-500 focus:ring-red-500': shouldShowError(),\n 'border-green-500 focus:border-green-500 focus:ring-green-500': wasFixedError(),\n '_shk-border focus:[border-color:var(--shk-primary-500)] focus:[--tw-ring-color:var(--shk-primary-500)]': !shouldShowError() && !wasFixedError()\n }\"\n [class.pr-8]=\"type() === 'password' && actualControl()?.value?.length > 0\"\n [class.pr-3]=\"type() !== 'password' || !actualControl()?.value?.length\"\n />\n\n @if (type() === 'password' && actualControl()?.value?.length > 0) {\n <button\n type=\"button\"\n (click)=\"togglePasswordVisibility()\"\n [disabled]=\"actualControl()?.disabled\"\n class=\"absolute right-3 top-1/2 -translate-y-1/2 _shk-text-surface-400 dark:[color:var(--shk-surface-400)] hover:[color:var(--shk-surface-600)] dark:hover:[color:var(--shk-surface-600)] focus:outline-none\"\n >\n @if (showPassword()) {\n <svg [lucideIcon]=\"getIcon('eye-off')\" class=\"w-4 h-4\"></svg>\n } @else {\n <svg [lucideIcon]=\"getIcon('eye')\" class=\"w-4 h-4\"></svg>\n }\n </button>\n }\n }\n </div>\n }\n\n @if (isTextArea()) {\n <textarea\n #textarea\n [id]=\"id()\"\n [formControl]=\"$any(actualControl())\"\n [placeholder]=\"placeholder() || label()\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n [class]=\"isTextArea() ? textAreaHeight() : 'h-28'\"\n class=\"block w-full px-3 py-2 _shk-text-surface-700 dark:[color:var(--shk-surface-700)] _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border rounded-lg transition-colors placeholder:[color:var(--shk-surface-400)] dark:placeholder:[color:var(--shk-surface-400)] focus:outline-none focus:[background-color:var(--shk-surface-50)] dark:focus:[background-color:var(--shk-surface-100)] focus:ring-1 resize-none disabled:[background-color:var(--shk-surface-50)] dark:disabled:[background-color:var(--shk-surface-100)] disabled:cursor-not-allowed disabled:[color:var(--shk-surface-400)] dark:disabled:[color:var(--shk-surface-400)] sm:text-sm\"\n [ngClass]=\"{\n 'border-red-500 focus:border-red-500 focus:ring-red-500': shouldShowError(),\n 'border-green-500 focus:border-green-500 focus:ring-green-500': wasFixedError(),\n '_shk-border focus:[border-color:var(--shk-primary-500)] focus:[--tw-ring-color:var(--shk-primary-500)]': !shouldShowError() && !wasFixedError()\n }\"\n ></textarea>\n }\n </div>\n\n @if (shouldShowError()) {\n <div class=\"mt-1 text-xs text-red-500 max-h-20 overflow-y-auto\" tabindex=\"-1\">\n <ul class=\"list-disc pl-4 space-y-1\">\n @for (error of getErrorMessages(); track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
304
|
+
], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["input"], descendants: true, isSignal: true }, { propertyName: "textareaElement", first: true, predicate: ["textarea"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"relative mb-4\">\n @if (label()) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] mb-1\">\n {{ label() }}\n </div>\n }\n\n <div class=\"relative\">\n @if (!isTextArea()) {\n <div class=\"flex\">\n @if (searchMode()) {\n @let isDisabledSearch = actualControl()?.disabled || isDisabled();\n <input\n #input\n [id]=\"id()\"\n type=\"text\"\n [value]=\"displayValue() || ''\"\n [placeholder]=\"placeholder() || label()\"\n [readOnly]=\"true\"\n [disabled]=\"isDisabledSearch\"\n (click)=\"!isDisabledSearch && searchButtonClick.emit()\"\n (keydown.enter)=\"!isDisabledSearch && searchButtonClick.emit()\"\n (blur)=\"onBlur()\"\n autocomplete=\"off\"\n [class.cursor-pointer]=\"!isDisabledSearch\"\n [class.cursor-not-allowed]=\"isDisabledSearch\"\n [class._shk-bg-surface-50]=\"isDisabledSearch\"\n [class.dark:[background-color:var(--shk-surface-100)]]=\"isDisabledSearch\"\n [class._shk-text-surface-400]=\"isDisabledSearch\"\n [class.dark:[color:var(--shk-surface-400)]]=\"isDisabledSearch\"\n class=\"block w-full px-3 py-2 _shk-text-surface-700 dark:[color:var(--shk-surface-700)] _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border rounded-l-lg transition-colors placeholder:[color:var(--shk-surface-400)] dark:placeholder:[color:var(--shk-surface-400)] focus:[background-color:var(--shk-surface-50)] dark:focus:[background-color:var(--shk-surface-100)] sm:text-sm\"\n [ngClass]=\"{\n 'border-red-500': shouldShowError() && !isDisabledSearch,\n '_shk-border': !shouldShowError() || isDisabledSearch,\n 'cursor-pointer': !isDisabledSearch,\n 'cursor-not-allowed _shk-text-surface-400 dark:[color:var(--shk-surface-400)]': isDisabledSearch\n }\"\n />\n <button\n type=\"button\"\n (click)=\"searchButtonClick.emit()\"\n tabindex=\"-1\"\n [disabled]=\"isDisabledSearch\"\n class=\"px-3 flex items-center justify-center shrink-0 _shk-bg-primary hover:[background-color:var(--shk-primary-700)] text-white border _shk-border-primary rounded-r-lg transition-colors duration-200 disabled:[background-color:var(--shk-surface-300)] dark:disabled:[background-color:var(--shk-surface-200)] disabled:[border-color:var(--shk-surface-300)] dark:disabled:[border-color:var(--shk-surface-200)] disabled:cursor-not-allowed\"\n >\n <svg [lucideIcon]=\"getIcon('search')\" class=\"w-4 h-4\"></svg>\n </button>\n }\n\n @if (!searchMode()) {\n <input\n #input\n [id]=\"id()\"\n [maxlength]=\"maxLength() || (formatCard() ? 19 : null)\"\n [min]=\"type() === 'number' && preventNegative() ? '0' : null\"\n (keypress)=\"type() === 'number' || numbersOnly() ? numberValidation($event) : null\"\n [type]=\"effectiveType()\"\n [formControl]=\"$any(actualControl())\"\n [placeholder]=\"placeholder() || label()\"\n (input)=\"onInput($event)\"\n [autocomplete]=\"autocomplete()\"\n (blur)=\"onBlur()\"\n class=\"block w-full px-3 py-2 _shk-text-surface-700 dark:[color:var(--shk-surface-700)] _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border rounded-lg transition-colors placeholder:[color:var(--shk-surface-400)] dark:placeholder:[color:var(--shk-surface-400)] focus:outline-none focus:[background-color:var(--shk-surface-50)] dark:focus:[background-color:var(--shk-surface-100)] focus:ring-1 disabled:[background-color:var(--shk-surface-50)] dark:disabled:[background-color:var(--shk-surface-100)] disabled:cursor-not-allowed sm:text-sm\"\n [ngClass]=\"{\n 'border-red-500 focus:border-red-500 focus:ring-red-500': shouldShowError(),\n 'border-green-500 focus:border-green-500 focus:ring-green-500': wasFixedError(),\n '_shk-border focus:[border-color:var(--shk-primary-500)] focus:[--tw-ring-color:var(--shk-primary-500)]': !shouldShowError() && !wasFixedError()\n }\"\n [class.pr-8]=\"type() === 'password' && actualControl()?.value?.length > 0\"\n [class.pr-3]=\"type() !== 'password' || !actualControl()?.value?.length\"\n />\n\n @if (type() === 'password' && actualControl()?.value?.length > 0) {\n <button\n type=\"button\"\n (click)=\"togglePasswordVisibility()\"\n [disabled]=\"actualControl()?.disabled\"\n class=\"absolute right-3 top-1/2 -translate-y-1/2 _shk-text-surface-400 dark:[color:var(--shk-surface-400)] hover:[color:var(--shk-surface-600)] dark:hover:[color:var(--shk-surface-600)] focus:outline-none\"\n >\n @if (showPassword()) {\n <svg [lucideIcon]=\"getIcon('eye-off')\" class=\"w-4 h-4\"></svg>\n } @else {\n <svg [lucideIcon]=\"getIcon('eye')\" class=\"w-4 h-4\"></svg>\n }\n </button>\n }\n }\n </div>\n }\n\n @if (isTextArea()) {\n <textarea\n #textarea\n [id]=\"id()\"\n [formControl]=\"$any(actualControl())\"\n [placeholder]=\"placeholder() || label()\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n [class]=\"isTextArea() ? textAreaHeight() : 'h-28'\"\n class=\"block w-full px-3 py-2 _shk-text-surface-700 dark:[color:var(--shk-surface-700)] _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border rounded-lg transition-colors placeholder:[color:var(--shk-surface-400)] dark:placeholder:[color:var(--shk-surface-400)] focus:outline-none focus:[background-color:var(--shk-surface-50)] dark:focus:[background-color:var(--shk-surface-100)] focus:ring-1 resize-none disabled:[background-color:var(--shk-surface-50)] dark:disabled:[background-color:var(--shk-surface-100)] disabled:cursor-not-allowed disabled:[color:var(--shk-surface-400)] dark:disabled:[color:var(--shk-surface-400)] sm:text-sm\"\n [ngClass]=\"{\n 'border-red-500 focus:border-red-500 focus:ring-red-500': shouldShowError(),\n 'border-green-500 focus:border-green-500 focus:ring-green-500': wasFixedError(),\n '_shk-border focus:[border-color:var(--shk-primary-500)] focus:[--tw-ring-color:var(--shk-primary-500)]': !shouldShowError() && !wasFixedError()\n }\"\n ></textarea>\n }\n </div>\n\n @if (shouldShowError()) {\n <div class=\"mt-1 text-xs text-red-500 max-h-20 overflow-y-auto\" tabindex=\"-1\">\n <ul class=\"list-disc pl-4 space-y-1\">\n @for (error of getErrorMessages(); track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
305
305
|
}
|
|
306
306
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TextFieldComponent, decorators: [{
|
|
307
307
|
type: Component,
|
|
@@ -315,9 +315,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
|
|
|
315
315
|
}], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], formatCard: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatCard", required: false }] }], preventNegative: [{ type: i0.Input, args: [{ isSignal: true, alias: "preventNegative", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], numbersOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "numbersOnly", required: false }] }], allowDecimals: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowDecimals", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], errorMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessages", required: false }] }], formGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "formGroup", required: false }] }], control: [{ type: i0.Input, args: [{ isSignal: true, alias: "control", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], isTextArea: [{ type: i0.Input, args: [{ isSignal: true, alias: "isTextArea", required: false }] }], textAreaHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "textAreaHeight", required: false }] }], searchMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchMode", required: false }] }], displayValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayValue", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], searchButtonClick: [{ type: i0.Output, args: ["searchButtonClick"] }], inputElement: [{ type: i0.ViewChild, args: ['input', { isSignal: true }] }], textareaElement: [{ type: i0.ViewChild, args: ['textarea', { isSignal: true }] }] } });
|
|
316
316
|
|
|
317
317
|
class NotificationService {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
318
|
+
constructor() {
|
|
319
|
+
this.notificationsSignal = signal([], ...(ngDevMode ? [{ debugName: "notificationsSignal" }] : /* istanbul ignore next */ []));
|
|
320
|
+
this.currentId = 0;
|
|
321
|
+
this.notifications = this.notificationsSignal.asReadonly();
|
|
322
|
+
}
|
|
321
323
|
addNotification(message, type = 'info', showProgress = false, duration = 5000) {
|
|
322
324
|
const id = (++this.currentId).toString();
|
|
323
325
|
const notification = {
|
|
@@ -356,8 +358,8 @@ class NotificationService {
|
|
|
356
358
|
clearAll() {
|
|
357
359
|
this.notificationsSignal.set([]);
|
|
358
360
|
}
|
|
359
|
-
static
|
|
360
|
-
static
|
|
361
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: NotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
362
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: NotificationService, providedIn: 'root' }); }
|
|
361
363
|
}
|
|
362
364
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: NotificationService, decorators: [{
|
|
363
365
|
type: Injectable,
|
|
@@ -374,40 +376,42 @@ const icons$5 = {
|
|
|
374
376
|
x: LucideX,
|
|
375
377
|
};
|
|
376
378
|
class NotificationComponent {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
379
|
+
constructor() {
|
|
380
|
+
this.position = input('center-top', ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
|
|
381
|
+
this.notificationService = inject(NotificationService);
|
|
382
|
+
this.getIcon = (name) => icons$5[name] ?? LucideInfo;
|
|
383
|
+
this.iconMap = {
|
|
384
|
+
success: 'check',
|
|
385
|
+
error: 'circle-x',
|
|
386
|
+
info: 'info',
|
|
387
|
+
warning: 'triangle-alert',
|
|
388
|
+
};
|
|
389
|
+
this.notifications = this.notificationService.notifications;
|
|
390
|
+
this.sortedNotifications = computed(() => [...this.notifications()].reverse(), ...(ngDevMode ? [{ debugName: "sortedNotifications" }] : /* istanbul ignore next */ []));
|
|
391
|
+
this.hasNotifications = computed(() => this.notifications().length > 0, ...(ngDevMode ? [{ debugName: "hasNotifications" }] : /* istanbul ignore next */ []));
|
|
392
|
+
this.positionClass = computed(() => {
|
|
393
|
+
const base = 'fixed top-4 z-[9999] space-y-4 sm:space-y-6 sm:top-6 lg:top-8';
|
|
394
|
+
switch (this.position()) {
|
|
395
|
+
case 'right-top':
|
|
396
|
+
return `${base} right-4`;
|
|
397
|
+
case 'left-top':
|
|
398
|
+
return `${base} left-4`;
|
|
399
|
+
default:
|
|
400
|
+
return `${base} left-1/2 -translate-x-1/2`;
|
|
401
|
+
}
|
|
402
|
+
}, ...(ngDevMode ? [{ debugName: "positionClass" }] : /* istanbul ignore next */ []));
|
|
403
|
+
}
|
|
386
404
|
getNotificationIcon(type) {
|
|
387
405
|
return this.iconMap[type] || 'info';
|
|
388
406
|
}
|
|
389
|
-
notifications = this.notificationService.notifications;
|
|
390
|
-
sortedNotifications = computed(() => [...this.notifications()].reverse(), ...(ngDevMode ? [{ debugName: "sortedNotifications" }] : /* istanbul ignore next */ []));
|
|
391
407
|
removeNotification(notification) {
|
|
392
408
|
this.notificationService.removeNotification(notification);
|
|
393
409
|
}
|
|
394
410
|
roundProgress(progress) {
|
|
395
411
|
return Math.round(progress || 0);
|
|
396
412
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
const base = 'fixed top-4 z-[9999] space-y-4 sm:space-y-6 sm:top-6 lg:top-8';
|
|
400
|
-
switch (this.position()) {
|
|
401
|
-
case 'right-top':
|
|
402
|
-
return `${base} right-4`;
|
|
403
|
-
case 'left-top':
|
|
404
|
-
return `${base} left-4`;
|
|
405
|
-
default:
|
|
406
|
-
return `${base} left-1/2 -translate-x-1/2`;
|
|
407
|
-
}
|
|
408
|
-
}, ...(ngDevMode ? [{ debugName: "positionClass" }] : /* istanbul ignore next */ []));
|
|
409
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: NotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
410
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: NotificationComponent, isStandalone: true, selector: "shk-notification", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [class]=\"positionClass()\">\n @for (notification of sortedNotifications(); track notification.id) {\n <div\n [ngClass]=\"{\n 'bg-green-50/80 dark:bg-green-900/30 border-green-400 dark:border-green-600 text-green-800 dark:text-green-200':\n notification.type === 'success',\n 'bg-red-50/80 dark:bg-red-900/30 border-red-400 dark:border-red-600 text-red-800 dark:text-red-200':\n notification.type === 'error',\n 'bg-blue-50/80 dark:bg-blue-900/30 border-blue-400 dark:border-blue-600 text-blue-800 dark:text-blue-200':\n notification.type === 'info',\n 'bg-yellow-50/80 dark:bg-yellow-900/30 border-yellow-400 dark:border-yellow-500 text-yellow-800 dark:text-yellow-200':\n notification.type === 'warning',\n }\"\n class=\"flex items-center w-full min-w-[320px] max-w-xs sm:max-w-sm lg:max-w-md p-4 mb-4 border-l-4 rounded-lg shadow-lg backdrop-blur-sm transition-all duration-300 transform hover:scale-105 hover:shadow-xl\"\n role=\"alert\"\n >\n <div\n [ngClass]=\"{\n 'text-green-600': notification.type === 'success',\n 'text-red-600': notification.type === 'error',\n 'text-blue-600': notification.type === 'info',\n 'text-yellow-600': notification.type === 'warning',\n }\"\n class=\"inline-flex items-center justify-center flex-shrink-0 w-10 h-10 rounded-lg bg-opacity-10\"\n >\n <svg [lucideIcon]=\"getIcon(getNotificationIcon(notification.type))\" class=\"w-6 h-6\"></svg>\n </div>\n <div class=\"ms-4 flex-1 text-sm font-medium break-words\">\n {{ notification.message }}\n </div>\n <button\n type=\"button\"\n (click)=\"removeNotification(notification)\"\n aria-label=\"Close\"\n [ngClass]=\"{\n 'text-green-600 hover:text-green-800':\n notification.type === 'success',\n 'text-red-600 hover:text-red-800': notification.type === 'error',\n 'text-blue-600 hover:text-blue-800': notification.type === 'info',\n 'text-yellow-600 hover:text-yellow-800':\n notification.type === 'warning',\n }\"\n class=\"mx-2 -my-1.5 bg-transparent focus:outline-none\"\n >\n <svg [lucideIcon]=\"getIcon('x')\" class=\"w-4 h-4\"></svg>\n </button>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
413
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: NotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
414
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: NotificationComponent, isStandalone: true, selector: "shk-notification", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [class]=\"positionClass()\">\n @for (notification of sortedNotifications(); track notification.id) {\n <div\n [ngClass]=\"{\n 'bg-green-50/80 dark:bg-green-900/30 border-green-400 dark:border-green-600 text-green-800 dark:text-green-200':\n notification.type === 'success',\n 'bg-red-50/80 dark:bg-red-900/30 border-red-400 dark:border-red-600 text-red-800 dark:text-red-200':\n notification.type === 'error',\n 'bg-blue-50/80 dark:bg-blue-900/30 border-blue-400 dark:border-blue-600 text-blue-800 dark:text-blue-200':\n notification.type === 'info',\n 'bg-yellow-50/80 dark:bg-yellow-900/30 border-yellow-400 dark:border-yellow-500 text-yellow-800 dark:text-yellow-200':\n notification.type === 'warning',\n }\"\n class=\"flex items-center w-full min-w-[320px] max-w-xs sm:max-w-sm lg:max-w-md p-4 mb-4 border-l-4 rounded-lg shadow-lg backdrop-blur-sm transition-all duration-300 transform hover:scale-105 hover:shadow-xl\"\n role=\"alert\"\n >\n <div\n [ngClass]=\"{\n 'text-green-600': notification.type === 'success',\n 'text-red-600': notification.type === 'error',\n 'text-blue-600': notification.type === 'info',\n 'text-yellow-600': notification.type === 'warning',\n }\"\n class=\"inline-flex items-center justify-center flex-shrink-0 w-10 h-10 rounded-lg bg-opacity-10\"\n >\n <svg [lucideIcon]=\"getIcon(getNotificationIcon(notification.type))\" class=\"w-6 h-6\"></svg>\n </div>\n <div class=\"ms-4 flex-1 text-sm font-medium break-words\">\n {{ notification.message }}\n </div>\n <button\n type=\"button\"\n (click)=\"removeNotification(notification)\"\n aria-label=\"Close\"\n [ngClass]=\"{\n 'text-green-600 hover:text-green-800':\n notification.type === 'success',\n 'text-red-600 hover:text-red-800': notification.type === 'error',\n 'text-blue-600 hover:text-blue-800': notification.type === 'info',\n 'text-yellow-600 hover:text-yellow-800':\n notification.type === 'warning',\n }\"\n class=\"mx-2 -my-1.5 bg-transparent focus:outline-none\"\n >\n <svg [lucideIcon]=\"getIcon('x')\" class=\"w-4 h-4\"></svg>\n </button>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
411
415
|
}
|
|
412
416
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: NotificationComponent, decorators: [{
|
|
413
417
|
type: Component,
|
|
@@ -415,15 +419,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
|
|
|
415
419
|
}], propDecorators: { position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }] } });
|
|
416
420
|
|
|
417
421
|
class ToggleComponent {
|
|
418
|
-
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
419
|
-
mode = input('toggle', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
420
|
-
checked = input(undefined, ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
|
|
421
|
-
checkedChange = output();
|
|
422
|
-
_value = signal(false, ...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
|
|
423
|
-
_disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : /* istanbul ignore next */ []));
|
|
424
|
-
onChange = () => { };
|
|
425
|
-
onTouched = () => { };
|
|
426
422
|
constructor() {
|
|
423
|
+
this.label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
424
|
+
this.mode = input('toggle', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
425
|
+
this.checked = input(undefined, ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
|
|
426
|
+
this.checkedChange = output();
|
|
427
|
+
this._value = signal(false, ...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
|
|
428
|
+
this._disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : /* istanbul ignore next */ []));
|
|
429
|
+
this.onChange = () => { };
|
|
430
|
+
this.onTouched = () => { };
|
|
427
431
|
effect(() => {
|
|
428
432
|
const manual = this.checked();
|
|
429
433
|
if (manual !== undefined) {
|
|
@@ -452,8 +456,8 @@ class ToggleComponent {
|
|
|
452
456
|
this.onTouched();
|
|
453
457
|
this.checkedChange.emit(newValue);
|
|
454
458
|
}
|
|
455
|
-
static
|
|
456
|
-
static
|
|
459
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
460
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: ToggleComponent, isStandalone: true, selector: "shk-toggle", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checkedChange: "checkedChange" }, providers: [
|
|
457
461
|
{
|
|
458
462
|
provide: NG_VALUE_ACCESSOR,
|
|
459
463
|
useExisting: forwardRef(() => ToggleComponent),
|
|
@@ -502,7 +506,7 @@ class ToggleComponent {
|
|
|
502
506
|
}
|
|
503
507
|
</label>
|
|
504
508
|
</div>
|
|
505
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
509
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
506
510
|
}
|
|
507
511
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ToggleComponent, decorators: [{
|
|
508
512
|
type: Component,
|
|
@@ -565,16 +569,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
|
|
|
565
569
|
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], checkedChange: [{ type: i0.Output, args: ["checkedChange"] }] } });
|
|
566
570
|
|
|
567
571
|
class PriceInputComponent {
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
572
|
+
constructor() {
|
|
573
|
+
this.value = model.required(...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
574
|
+
this.isPercentage = model(false, ...(ngDevMode ? [{ debugName: "isPercentage" }] : /* istanbul ignore next */ []));
|
|
575
|
+
this.label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
576
|
+
this.inputId = input('', ...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
|
|
577
|
+
this.required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
578
|
+
this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
579
|
+
this.min = input(0, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
|
|
580
|
+
this.max = input(Infinity, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
581
|
+
this.showError = input(false, ...(ngDevMode ? [{ debugName: "showError" }] : /* istanbul ignore next */ []));
|
|
582
|
+
this.errorMessage = input('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
|
|
583
|
+
}
|
|
578
584
|
toggleMode() {
|
|
579
585
|
if (this.disabled())
|
|
580
586
|
return;
|
|
@@ -584,8 +590,8 @@ class PriceInputComponent {
|
|
|
584
590
|
const input = event.target;
|
|
585
591
|
this.value.set(parseFloat(input.value) || 0);
|
|
586
592
|
}
|
|
587
|
-
static
|
|
588
|
-
static
|
|
593
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: PriceInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
594
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: PriceInputComponent, isStandalone: true, selector: "shk-price-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, isPercentage: { classPropertyName: "isPercentage", publicName: "isPercentage", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, showError: { classPropertyName: "showError", publicName: "showError", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", isPercentage: "isPercentageChange" }, ngImport: i0, template: "<div>\n @if (label()) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] mb-1\">\n {{ label() }}\n @if (required()) {\n <span class=\"text-red-400\">*</span>\n }\n </div>\n }\n <div class=\"flex\">\n <input\n [id]=\"inputId()\"\n type=\"number\"\n [ngModel]=\"value()\"\n (ngModelChange)=\"value.set($event ?? 0)\"\n (input)=\"onInput($event)\"\n [disabled]=\"disabled()\"\n [min]=\"min()\"\n [max]=\"max()\"\n step=\"0.01\"\n class=\"block w-full px-3 py-2 _shk-text-surface-700 dark:[color:var(--shk-surface-700)] _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border rounded-l-lg transition-colors placeholder:[color:var(--shk-surface-400)] dark:placeholder:[color:var(--shk-surface-400)] focus:outline-none focus:[background-color:var(--shk-surface-50)] dark:focus:[background-color:var(--shk-surface-100)] focus:ring-1 disabled:[background-color:var(--shk-surface-50)] dark:disabled:[background-color:var(--shk-surface-100)] disabled:cursor-not-allowed sm:text-sm\"\n [ngClass]=\"{\n 'border-red-500 focus:border-red-500 focus:ring-red-500': showError(),\n '_shk-border dark:[border-color:var(--shk-surface-200)] focus:[border-color:var(--shk-primary-500)] focus:[--tw-ring-color:var(--shk-primary-500)]': !showError()\n }\"\n />\n <button\n type=\"button\"\n (click)=\"toggleMode()\"\n [disabled]=\"disabled()\"\n class=\"px-3 py-2 text-sm font-medium border rounded-r-lg transition-colors shrink-0\"\n [ngClass]=\"{\n '_shk-bg-primary-soft _shk-border-primary-200 _shk-text-primary-700 dark:[background-color:var(--shk-primary-900)] dark:[border-color:var(--shk-primary-700)] dark:[color:var(--shk-primary-300)]': isPercentage(),\n '_shk-bg-white _shk-border _shk-text-surface-500 dark:[background-color:var(--shk-surface-100)] dark:[border-color:var(--shk-surface-200)] dark:[color:var(--shk-surface-400)]': !isPercentage(),\n 'cursor-not-allowed opacity-50': disabled()\n }\"\n >\n {{ isPercentage() ? '%' : '$' }}\n </button>\n </div>\n @if (showError()) {\n <div class=\"text-xs _shk-text-red-500 mt-1\">\n {{ errorMessage() }}\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i2.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
589
595
|
}
|
|
590
596
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: PriceInputComponent, decorators: [{
|
|
591
597
|
type: Component,
|
|
@@ -593,179 +599,179 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
|
|
|
593
599
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }, { type: i0.Output, args: ["valueChange"] }], isPercentage: [{ type: i0.Input, args: [{ isSignal: true, alias: "isPercentage", required: false }] }, { type: i0.Output, args: ["isPercentageChange"] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], showError: [{ type: i0.Input, args: [{ isSignal: true, alias: "showError", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }] } });
|
|
594
600
|
|
|
595
601
|
class DatePickerComponent {
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
this.
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
this.
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
this.
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
602
|
+
constructor() {
|
|
603
|
+
this.elementRef = inject(ElementRef);
|
|
604
|
+
this.cdr = inject(ChangeDetectorRef);
|
|
605
|
+
this.destroyRef = inject(DestroyRef);
|
|
606
|
+
this.transloco = inject(TranslocoService);
|
|
607
|
+
this.id = input('', ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
608
|
+
this.view = input('date', ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
|
|
609
|
+
this.label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
610
|
+
this.placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
611
|
+
this.formGroup = input(undefined, ...(ngDevMode ? [{ debugName: "formGroup" }] : /* istanbul ignore next */ []));
|
|
612
|
+
this.control = input(undefined, ...(ngDevMode ? [{ debugName: "control" }] : /* istanbul ignore next */ []));
|
|
613
|
+
this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
614
|
+
this.errorMessage = input('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
|
|
615
|
+
this.errorMessages = input({}, ...(ngDevMode ? [{ debugName: "errorMessages" }] : /* istanbul ignore next */ []));
|
|
616
|
+
this.minValue = input('', ...(ngDevMode ? [{ debugName: "minValue" }] : /* istanbul ignore next */ []));
|
|
617
|
+
this.maxValue = input('', ...(ngDevMode ? [{ debugName: "maxValue" }] : /* istanbul ignore next */ []));
|
|
618
|
+
this.locale = input('es', ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
619
|
+
this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
620
|
+
this.viewYear = signal(new Date().getFullYear(), ...(ngDevMode ? [{ debugName: "viewYear" }] : /* istanbul ignore next */ []));
|
|
621
|
+
this.viewMonth = signal(new Date().getMonth(), ...(ngDevMode ? [{ debugName: "viewMonth" }] : /* istanbul ignore next */ []));
|
|
622
|
+
this.viewDecade = signal(Math.floor(new Date().getFullYear() / 10) * 10, ...(ngDevMode ? [{ debugName: "viewDecade" }] : /* istanbul ignore next */ []));
|
|
623
|
+
this._value = signal(null, ...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
|
|
624
|
+
this._disabledState = signal(false, ...(ngDevMode ? [{ debugName: "_disabledState" }] : /* istanbul ignore next */ []));
|
|
625
|
+
this.subscribed = signal(false, ...(ngDevMode ? [{ debugName: "subscribed" }] : /* istanbul ignore next */ []));
|
|
626
|
+
this.valueSubscribed = signal(false, ...(ngDevMode ? [{ debugName: "valueSubscribed" }] : /* istanbul ignore next */ []));
|
|
627
|
+
this.errorTracker = signal(0, ...(ngDevMode ? [{ debugName: "errorTracker" }] : /* istanbul ignore next */ []));
|
|
628
|
+
this.hadError = signal(false, ...(ngDevMode ? [{ debugName: "hadError" }] : /* istanbul ignore next */ []));
|
|
629
|
+
this.onChange = () => { };
|
|
630
|
+
this.onTouched = () => { };
|
|
631
|
+
this.value = computed(() => this._value(), ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
632
|
+
this.isDisabled = computed(() => this.disabled() || this._disabledState(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
633
|
+
this.actualControl = computed(() => {
|
|
634
|
+
const ctrl = this.control();
|
|
635
|
+
if (ctrl)
|
|
636
|
+
return ctrl;
|
|
637
|
+
const fg = this.formGroup();
|
|
638
|
+
const lbl = this.label();
|
|
639
|
+
if (fg && lbl)
|
|
640
|
+
return fg.get(lbl);
|
|
641
|
+
return undefined;
|
|
642
|
+
}, ...(ngDevMode ? [{ debugName: "actualControl" }] : /* istanbul ignore next */ []));
|
|
643
|
+
this.shouldShowError = computed(() => {
|
|
644
|
+
this.errorTracker();
|
|
645
|
+
const ctrl = this.actualControl();
|
|
646
|
+
return ctrl?.invalid && (ctrl?.dirty || ctrl?.touched);
|
|
647
|
+
}, ...(ngDevMode ? [{ debugName: "shouldShowError" }] : /* istanbul ignore next */ []));
|
|
648
|
+
this.wasFixedError = computed(() => {
|
|
649
|
+
this.errorTracker();
|
|
650
|
+
const ctrl = this.actualControl();
|
|
651
|
+
return this.hadError() && ctrl?.valid && ctrl?.touched;
|
|
652
|
+
}, ...(ngDevMode ? [{ debugName: "wasFixedError" }] : /* istanbul ignore next */ []));
|
|
653
|
+
this.getErrorMessages = computed(() => {
|
|
654
|
+
this.errorTracker();
|
|
655
|
+
const customError = this.errorMessage();
|
|
656
|
+
if (customError)
|
|
657
|
+
return [customError];
|
|
658
|
+
const ctrl = this.actualControl();
|
|
659
|
+
if (!ctrl?.errors)
|
|
660
|
+
return [];
|
|
661
|
+
const customErrors = this.errorMessages();
|
|
662
|
+
const t = this.transloco;
|
|
663
|
+
return Object.keys(ctrl.errors).map((key) => {
|
|
664
|
+
if (customErrors[key])
|
|
665
|
+
return customErrors[key];
|
|
666
|
+
switch (key) {
|
|
667
|
+
case 'required':
|
|
668
|
+
return t.translate('validation.required');
|
|
669
|
+
default:
|
|
670
|
+
return t.translate('validation.invalid');
|
|
671
|
+
}
|
|
672
|
+
});
|
|
673
|
+
}, ...(ngDevMode ? [{ debugName: "getErrorMessages" }] : /* istanbul ignore next */ []));
|
|
674
|
+
this.displayLabel = computed(() => {
|
|
675
|
+
const value = this._value();
|
|
676
|
+
if (!value)
|
|
677
|
+
return '';
|
|
678
|
+
const v = this.view();
|
|
679
|
+
if (v === 'year') {
|
|
680
|
+
return value;
|
|
681
|
+
}
|
|
682
|
+
if (v === 'month') {
|
|
683
|
+
const [y, m] = value.split('-').map(Number);
|
|
684
|
+
const fmt = new Intl.DateTimeFormat(this.locale(), {
|
|
685
|
+
month: 'long',
|
|
686
|
+
year: 'numeric',
|
|
687
|
+
});
|
|
688
|
+
const label = fmt.format(new Date(y, m - 1, 1));
|
|
689
|
+
return label.charAt(0).toUpperCase() + label.slice(1);
|
|
664
690
|
}
|
|
665
|
-
});
|
|
666
|
-
}, ...(ngDevMode ? [{ debugName: "getErrorMessages" }] : /* istanbul ignore next */ []));
|
|
667
|
-
displayLabel = computed(() => {
|
|
668
|
-
const value = this._value();
|
|
669
|
-
if (!value)
|
|
670
|
-
return '';
|
|
671
|
-
const v = this.view();
|
|
672
|
-
if (v === 'year') {
|
|
673
|
-
return value;
|
|
674
|
-
}
|
|
675
|
-
if (v === 'month') {
|
|
676
|
-
const [y, m] = value.split('-').map(Number);
|
|
677
691
|
const fmt = new Intl.DateTimeFormat(this.locale(), {
|
|
678
|
-
|
|
679
|
-
year: 'numeric',
|
|
692
|
+
dateStyle: 'long',
|
|
680
693
|
});
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
return
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
}
|
|
728
|
-
if (v === 'month') {
|
|
729
|
-
const minY = min ? Number(min.split('-')[0]) : undefined;
|
|
694
|
+
return fmt.format(new Date(value + 'T12:00:00'));
|
|
695
|
+
}, ...(ngDevMode ? [{ debugName: "displayLabel" }] : /* istanbul ignore next */ []));
|
|
696
|
+
this.monthNames = computed(() => {
|
|
697
|
+
const fmt = new Intl.DateTimeFormat(this.locale(), { month: 'short' });
|
|
698
|
+
return Array.from({ length: 12 }, (_, i) => {
|
|
699
|
+
const name = fmt.format(new Date(2000, i, 1)).replace('.', '');
|
|
700
|
+
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
701
|
+
});
|
|
702
|
+
}, ...(ngDevMode ? [{ debugName: "monthNames" }] : /* istanbul ignore next */ []));
|
|
703
|
+
this.dayNames = computed(() => {
|
|
704
|
+
const fmt = new Intl.DateTimeFormat(this.locale(), { weekday: 'short' });
|
|
705
|
+
return Array.from({ length: 7 }, (_, i) => {
|
|
706
|
+
const name = fmt.format(new Date(2024, 0, i + 1));
|
|
707
|
+
return name.charAt(0).toUpperCase() + name.slice(1, 3);
|
|
708
|
+
});
|
|
709
|
+
}, ...(ngDevMode ? [{ debugName: "dayNames" }] : /* istanbul ignore next */ []));
|
|
710
|
+
this.daysInMonth = computed(() => {
|
|
711
|
+
return new Date(this.viewYear(), this.viewMonth() + 1, 0).getDate();
|
|
712
|
+
}, ...(ngDevMode ? [{ debugName: "daysInMonth" }] : /* istanbul ignore next */ []));
|
|
713
|
+
this.firstDayOfMonth = computed(() => {
|
|
714
|
+
return new Date(this.viewYear(), this.viewMonth(), 1).getDay();
|
|
715
|
+
}, ...(ngDevMode ? [{ debugName: "firstDayOfMonth" }] : /* istanbul ignore next */ []));
|
|
716
|
+
this.calendarDays = computed(() => {
|
|
717
|
+
const totalDays = this.daysInMonth();
|
|
718
|
+
const firstDay = this.firstDayOfMonth();
|
|
719
|
+
const days = [];
|
|
720
|
+
for (let i = 0; i < firstDay; i++)
|
|
721
|
+
days.push(null);
|
|
722
|
+
for (let i = 1; i <= totalDays; i++)
|
|
723
|
+
days.push(i);
|
|
724
|
+
return days;
|
|
725
|
+
}, ...(ngDevMode ? [{ debugName: "calendarDays" }] : /* istanbul ignore next */ []));
|
|
726
|
+
this.canGoPrev = computed(() => {
|
|
727
|
+
const v = this.view();
|
|
728
|
+
const min = this.minValue();
|
|
729
|
+
if (v === 'date') {
|
|
730
|
+
if (!min)
|
|
731
|
+
return true;
|
|
732
|
+
const prev = new Date(this.viewYear(), this.viewMonth() - 1, 1);
|
|
733
|
+
return prev >= new Date(min + 'T12:00:00');
|
|
734
|
+
}
|
|
735
|
+
if (v === 'month') {
|
|
736
|
+
const minY = min ? Number(min.split('-')[0]) : undefined;
|
|
737
|
+
return minY === undefined || this.viewYear() > minY;
|
|
738
|
+
}
|
|
739
|
+
const minY = min ? Number(min) : undefined;
|
|
730
740
|
return minY === undefined || this.viewYear() > minY;
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
const maxY = max ? Number(max
|
|
741
|
+
}, ...(ngDevMode ? [{ debugName: "canGoPrev" }] : /* istanbul ignore next */ []));
|
|
742
|
+
this.canGoNext = computed(() => {
|
|
743
|
+
const v = this.view();
|
|
744
|
+
const max = this.maxValue();
|
|
745
|
+
if (v === 'date') {
|
|
746
|
+
if (!max)
|
|
747
|
+
return true;
|
|
748
|
+
const next = new Date(this.viewYear(), this.viewMonth() + 1, 1);
|
|
749
|
+
return next <= new Date(max + 'T12:00:00');
|
|
750
|
+
}
|
|
751
|
+
if (v === 'month') {
|
|
752
|
+
const maxY = max ? Number(max.split('-')[0]) : undefined;
|
|
753
|
+
return maxY === undefined || this.viewYear() < maxY;
|
|
754
|
+
}
|
|
755
|
+
const maxY = max ? Number(max) : undefined;
|
|
746
756
|
return maxY === undefined || this.viewYear() < maxY;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
return Array.from({ length: 12 }, (_, i) => start + i);
|
|
766
|
-
}, ...(ngDevMode ? [{ debugName: "decadeYears" }] : /* istanbul ignore next */ []));
|
|
767
|
-
years = [];
|
|
768
|
-
constructor() {
|
|
757
|
+
}, ...(ngDevMode ? [{ debugName: "canGoNext" }] : /* istanbul ignore next */ []));
|
|
758
|
+
this.selectedYear = computed(() => {
|
|
759
|
+
const value = this._value();
|
|
760
|
+
return value ? Number(value.split('-')[0]) : null;
|
|
761
|
+
}, ...(ngDevMode ? [{ debugName: "selectedYear" }] : /* istanbul ignore next */ []));
|
|
762
|
+
this.selectedMonth = computed(() => {
|
|
763
|
+
const value = this._value();
|
|
764
|
+
return value ? Number(value.split('-')[1]) - 1 : null;
|
|
765
|
+
}, ...(ngDevMode ? [{ debugName: "selectedMonth" }] : /* istanbul ignore next */ []));
|
|
766
|
+
this.selectedDay = computed(() => {
|
|
767
|
+
const value = this._value();
|
|
768
|
+
return value && this.view() === 'date' ? Number(value.split('-')[2]) : null;
|
|
769
|
+
}, ...(ngDevMode ? [{ debugName: "selectedDay" }] : /* istanbul ignore next */ []));
|
|
770
|
+
this.decadeYears = computed(() => {
|
|
771
|
+
const start = this.viewDecade();
|
|
772
|
+
return Array.from({ length: 12 }, (_, i) => start + i);
|
|
773
|
+
}, ...(ngDevMode ? [{ debugName: "decadeYears" }] : /* istanbul ignore next */ []));
|
|
774
|
+
this.years = [];
|
|
769
775
|
effect(() => {
|
|
770
776
|
const ctrl = this.actualControl();
|
|
771
777
|
if (!ctrl) {
|
|
@@ -956,14 +962,14 @@ class DatePickerComponent {
|
|
|
956
962
|
this._disabledState.set(isDisabled);
|
|
957
963
|
this.cdr.markForCheck();
|
|
958
964
|
}
|
|
959
|
-
static
|
|
960
|
-
static
|
|
965
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: DatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
966
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: DatePickerComponent, isStandalone: true, selector: "shk-date-picker", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: false, transformFunction: null }, control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: true, isRequired: false, transformFunction: null }, minValue: { classPropertyName: "minValue", publicName: "minValue", isSignal: true, isRequired: false, transformFunction: null }, maxValue: { classPropertyName: "maxValue", publicName: "maxValue", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" } }, providers: [
|
|
961
967
|
{
|
|
962
968
|
provide: NG_VALUE_ACCESSOR,
|
|
963
969
|
useExisting: forwardRef(() => DatePickerComponent),
|
|
964
970
|
multi: true,
|
|
965
971
|
},
|
|
966
|
-
], ngImport: i0, template: "<div class=\"relative mb-4\">\n @if (label()) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] mb-1\">\n {{ label() }}\n </div>\n }\n\n <div class=\"relative\">\n <button\n type=\"button\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n (click)=\"toggle()\"\n class=\"flex items-center justify-between w-full px-3 py-2 text-left _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border rounded-lg transition-colors sm:text-sm focus:outline-none focus:ring-1 disabled:cursor-not-allowed disabled:[color:var(--shk-surface-400)] dark:disabled:[color:var(--shk-surface-500)]\"\n [ngClass]=\"{\n 'border-red-500 focus:border-red-500 focus:ring-red-500': shouldShowError(),\n 'border-green-500 focus:border-green-500 focus:ring-green-500': wasFixedError(),\n '_shk-border dark:[border-color:var(--shk-surface-200)] focus:[border-color:var(--shk-primary-500)] focus:[--tw-ring-color:var(--shk-primary-500)]': !shouldShowError() && !wasFixedError(),\n }\"\n >\n <span\n [ngClass]=\"value() ? '_shk-text-surface-700 dark:[color:var(--shk-surface-700)]' : '_shk-text-surface-400 dark:[color:var(--shk-surface-400)]'\"\n >\n {{ displayLabel() || placeholder() || label() }}\n </span>\n <svg\n class=\"w-4 h-4 _shk-text-surface-400 dark:[color:var(--shk-surface-400)] shrink-0\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"></rect>\n <path d=\"M16 2v4M8 2v4M3 10h18\"></path>\n </svg>\n </button>\n\n @if (isOpen()) {\n <div class=\"fixed inset-0 z-40 bg-black/30\" (click)=\"close()\"></div>\n <div\n class=\"fixed z-50 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-72 p-4 bg-white dark:[background-color:var(--shk-surface-100)] _shk-border dark:[border-color:var(--shk-surface-200)] rounded-lg shadow-xl\"\n (click)=\"$event.stopPropagation()\"\n >\n @if (view() === 'date') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"!canGoPrev()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ monthNames()[viewMonth()] }} {{ viewYear() }}\n </span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"!canGoNext()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (name of dayNames(); track $index) {\n <div class=\"text-center text-xs font-medium _shk-text-surface-400 dark:[color:var(--shk-surface-400)] py-1\">\n {{ name }}\n </div>\n }\n </div>\n\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day !== null) {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"py-1.5 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': isSelectedDay(day),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isToday(day) && !isSelectedDay(day),\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': !isSelectedDay(day) && !isToday(day),\n }\"\n >\n {{ day }}\n </button>\n } @else {\n <div></div>\n }\n }\n </div>\n }\n\n @if (view() === 'month') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"!canGoPrev()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">{{ viewYear() }}</span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"!canGoNext()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-3 gap-1\">\n @for (name of monthNames(); track $index) {\n <button\n type=\"button\"\n (click)=\"selectMonth($index)\"\n class=\"py-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': isSelectedMonth($index),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentMonth($index) && !isSelectedMonth($index),\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': !isSelectedMonth($index) && !isCurrentMonth($index),\n }\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @if (view() === 'year') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"!canGoPrev()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ viewDecade() }} - {{ viewDecade() + 11 }}\n </span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"!canGoNext()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-3 gap-1\">\n @for (year of decadeYears(); track year) {\n <button\n type=\"button\"\n (click)=\"selectYear(year)\"\n class=\"py-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': isSelectedYear(year),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentYear(year) && !isSelectedYear(year),\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': !isSelectedYear(year) && !isCurrentYear(year),\n }\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n\n @if (shouldShowError()) {\n <div class=\"mt-1 text-xs text-red-500 max-h-20 overflow-y-auto\">\n <ul class=\"list-disc pl-4 space-y-1\">\n @for (error of getErrorMessages(); track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
972
|
+
], ngImport: i0, template: "<div class=\"relative mb-4\">\n @if (label()) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] mb-1\">\n {{ label() }}\n </div>\n }\n\n <div class=\"relative\">\n <button\n type=\"button\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n (click)=\"toggle()\"\n class=\"flex items-center justify-between w-full px-3 py-2 text-left _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border rounded-lg transition-colors sm:text-sm focus:outline-none focus:ring-1 disabled:cursor-not-allowed disabled:[color:var(--shk-surface-400)] dark:disabled:[color:var(--shk-surface-500)]\"\n [ngClass]=\"{\n 'border-red-500 focus:border-red-500 focus:ring-red-500': shouldShowError(),\n 'border-green-500 focus:border-green-500 focus:ring-green-500': wasFixedError(),\n '_shk-border dark:[border-color:var(--shk-surface-200)] focus:[border-color:var(--shk-primary-500)] focus:[--tw-ring-color:var(--shk-primary-500)]': !shouldShowError() && !wasFixedError(),\n }\"\n >\n <span\n [ngClass]=\"value() ? '_shk-text-surface-700 dark:[color:var(--shk-surface-700)]' : '_shk-text-surface-400 dark:[color:var(--shk-surface-400)]'\"\n >\n {{ displayLabel() || placeholder() || label() }}\n </span>\n <svg\n class=\"w-4 h-4 _shk-text-surface-400 dark:[color:var(--shk-surface-400)] shrink-0\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"></rect>\n <path d=\"M16 2v4M8 2v4M3 10h18\"></path>\n </svg>\n </button>\n\n @if (isOpen()) {\n <div class=\"fixed inset-0 z-40 bg-black/30\" (click)=\"close()\"></div>\n <div\n class=\"fixed z-50 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-72 p-4 bg-white dark:[background-color:var(--shk-surface-100)] _shk-border dark:[border-color:var(--shk-surface-200)] rounded-lg shadow-xl\"\n (click)=\"$event.stopPropagation()\"\n >\n @if (view() === 'date') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"!canGoPrev()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ monthNames()[viewMonth()] }} {{ viewYear() }}\n </span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"!canGoNext()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (name of dayNames(); track $index) {\n <div class=\"text-center text-xs font-medium _shk-text-surface-400 dark:[color:var(--shk-surface-400)] py-1\">\n {{ name }}\n </div>\n }\n </div>\n\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day !== null) {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"py-1.5 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': isSelectedDay(day),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isToday(day) && !isSelectedDay(day),\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': !isSelectedDay(day) && !isToday(day),\n }\"\n >\n {{ day }}\n </button>\n } @else {\n <div></div>\n }\n }\n </div>\n }\n\n @if (view() === 'month') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"!canGoPrev()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">{{ viewYear() }}</span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"!canGoNext()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-3 gap-1\">\n @for (name of monthNames(); track $index) {\n <button\n type=\"button\"\n (click)=\"selectMonth($index)\"\n class=\"py-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': isSelectedMonth($index),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentMonth($index) && !isSelectedMonth($index),\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': !isSelectedMonth($index) && !isCurrentMonth($index),\n }\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @if (view() === 'year') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"!canGoPrev()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ viewDecade() }} - {{ viewDecade() + 11 }}\n </span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"!canGoNext()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-3 gap-1\">\n @for (year of decadeYears(); track year) {\n <button\n type=\"button\"\n (click)=\"selectYear(year)\"\n class=\"py-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': isSelectedYear(year),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentYear(year) && !isSelectedYear(year),\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': !isSelectedYear(year) && !isCurrentYear(year),\n }\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n\n @if (shouldShowError()) {\n <div class=\"mt-1 text-xs text-red-500 max-h-20 overflow-y-auto\">\n <ul class=\"list-disc pl-4 space-y-1\">\n @for (error of getErrorMessages(); track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
967
973
|
}
|
|
968
974
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: DatePickerComponent, decorators: [{
|
|
969
975
|
type: Component,
|
|
@@ -990,18 +996,20 @@ const icons$4 = {
|
|
|
990
996
|
loader: LucideLoader,
|
|
991
997
|
};
|
|
992
998
|
class ConfirmDialogComponent {
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
999
|
+
constructor() {
|
|
1000
|
+
this.getIcon = (name) => icons$4[name] ?? LucideTriangleAlert;
|
|
1001
|
+
this.title = input('Confirmar acción', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
1002
|
+
this.message = input('¿Está seguro de realizar esta acción?', ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
1003
|
+
this.confirmLabel = input('Confirmar', ...(ngDevMode ? [{ debugName: "confirmLabel" }] : /* istanbul ignore next */ []));
|
|
1004
|
+
this.cancelLabel = input('Cancelar', ...(ngDevMode ? [{ debugName: "cancelLabel" }] : /* istanbul ignore next */ []));
|
|
1005
|
+
this.loadingText = input('Procesando…', ...(ngDevMode ? [{ debugName: "loadingText" }] : /* istanbul ignore next */ []));
|
|
1006
|
+
this.type = input('danger', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
1007
|
+
this.loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
1008
|
+
this.showCancel = input(true, ...(ngDevMode ? [{ debugName: "showCancel" }] : /* istanbul ignore next */ []));
|
|
1009
|
+
this.visible = signal(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
1010
|
+
this.resolveRef = signal(null, ...(ngDevMode ? [{ debugName: "resolveRef" }] : /* istanbul ignore next */ []));
|
|
1011
|
+
this.closed = output();
|
|
1012
|
+
}
|
|
1005
1013
|
show() {
|
|
1006
1014
|
this.visible.set(true);
|
|
1007
1015
|
return new Promise((resolve) => {
|
|
@@ -1029,8 +1037,8 @@ class ConfirmDialogComponent {
|
|
|
1029
1037
|
ngOnDestroy() {
|
|
1030
1038
|
this.resolveRef.set(null);
|
|
1031
1039
|
}
|
|
1032
|
-
static
|
|
1033
|
-
static
|
|
1040
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ConfirmDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1041
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: ConfirmDialogComponent, isStandalone: true, selector: "shk-confirm-dialog", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: false, transformFunction: null }, cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: false, transformFunction: null }, loadingText: { classPropertyName: "loadingText", publicName: "loadingText", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, showCancel: { classPropertyName: "showCancel", publicName: "showCancel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, ngImport: i0, template: "@if (visible()) {\n <div\n class=\"fixed inset-0 bg-black/40 backdrop-blur-sm flex items-center justify-center z-[9999] p-4\"\n (click)=\"onCancel()\"\n >\n <div\n class=\"bg-white dark:[background-color:var(--shk-surface-100)] rounded-2xl shadow-2xl max-w-sm w-full animate-in fade-in zoom-in duration-200 overflow-hidden\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"h-1.5 w-full\"\n [class.bg-gradient-to-r]=\"type() !== 'warning'\"\n [class.from-red-400]=\"type() === 'danger'\"\n [class.to-red-600]=\"type() === 'danger'\"\n [class.from-blue-400]=\"type() === 'info'\"\n [class.to-blue-600]=\"type() === 'info'\"\n [class.bg-amber-400]=\"type() === 'warning'\"\n ></div>\n <div class=\"p-6\">\n <div class=\"flex items-start gap-4 mb-4\">\n <div\n class=\"w-12 h-12 rounded-full flex items-center justify-center shrink-0\"\n [ngClass]=\"{\n 'bg-red-50 dark:bg-red-900/30 text-red-600 dark:text-red-400': type() === 'danger',\n 'bg-blue-50 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400': type() === 'info',\n 'bg-amber-50 dark:bg-amber-900/30 text-amber-600 dark:text-amber-400': type() === 'warning',\n }\"\n >\n @if (type() === 'info') {\n <svg [lucideIcon]=\"getIcon('info')\" class=\"w-6 h-6\"></svg>\n } @else {\n <svg [lucideIcon]=\"getIcon('triangle-alert')\" class=\"w-6 h-6\"></svg>\n }\n </div>\n <div>\n <h3 class=\"text-lg font-bold _shk-text-surface-800 dark:[color:var(--shk-surface-800)]\">{{ title() }}</h3>\n <p class=\"_shk-text-surface-500 dark:[color:var(--shk-surface-400)] text-sm leading-relaxed mb-6\">{{ message() }}</p>\n </div>\n </div>\n <div class=\"flex gap-3\">\n @if (showCancel()) {\n <button\n type=\"button\"\n (click)=\"onCancel()\"\n [disabled]=\"loading()\"\n class=\"flex-1 px-4 py-2 text-sm font-semibold _shk-text-surface-600 dark:[color:var(--shk-surface-600)] _shk-bg-surface-100 dark:[background-color:var(--shk-surface-200)] hover:[background-color:var(--shk-surface-200)] dark:hover:[background-color:var(--shk-surface-300)] rounded-lg transition-colors flex items-center justify-center gap-2\"\n >\n <svg [lucideIcon]=\"getIcon('x')\" class=\"w-4 h-4\"></svg>\n {{ cancelLabel() }}\n </button>\n }\n <button\n type=\"button\"\n (click)=\"onConfirm()\"\n [disabled]=\"loading()\"\n class=\"flex-1 px-4 py-2 text-sm font-semibold text-white rounded-lg shadow-md transition-all flex items-center justify-center gap-2\"\n [class.bg-red-600]=\"type() === 'danger'\"\n [class.hover:bg-red-700]=\"type() === 'danger'\"\n [class.shadow-red-500/20]=\"type() === 'danger'\"\n [class.bg-primary-600]=\"type() === 'info'\"\n [class.hover:bg-primary-700]=\"type() === 'info'\"\n [class.shadow-primary-500/20]=\"type() === 'info'\"\n [class.bg-amber-600]=\"type() === 'warning'\"\n [class.hover:bg-amber-700]=\"type() === 'warning'\"\n [class.shadow-amber-500/20]=\"type() === 'warning'\"\n >\n @if (loading()) {\n <svg [lucideIcon]=\"getIcon('loader')\" class=\"w-4 h-4 animate-spin\"></svg>\n } @else if (type() === 'danger') {\n <svg [lucideIcon]=\"getIcon('trash-2')\" class=\"w-4 h-4\"></svg>\n }\n {{ loading() ? loadingText() : confirmLabel() }}\n </button>\n </div>\n </div>\n </div>\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1034
1042
|
}
|
|
1035
1043
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
|
|
1036
1044
|
type: Component,
|
|
@@ -1038,11 +1046,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
|
|
|
1038
1046
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], confirmLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmLabel", required: false }] }], cancelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelLabel", required: false }] }], loadingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingText", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], showCancel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCancel", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
|
|
1039
1047
|
|
|
1040
1048
|
class ConfirmDialogService {
|
|
1041
|
-
dialogRef = null;
|
|
1042
|
-
destroyRef = inject(DestroyRef);
|
|
1043
|
-
appRef = inject(ApplicationRef);
|
|
1044
|
-
injector = inject(EnvironmentInjector);
|
|
1045
1049
|
constructor() {
|
|
1050
|
+
this.dialogRef = null;
|
|
1051
|
+
this.destroyRef = inject(DestroyRef);
|
|
1052
|
+
this.appRef = inject(ApplicationRef);
|
|
1053
|
+
this.injector = inject(EnvironmentInjector);
|
|
1046
1054
|
this.destroyRef.onDestroy(() => this.cleanupDialog());
|
|
1047
1055
|
}
|
|
1048
1056
|
async confirm(config) {
|
|
@@ -1075,8 +1083,8 @@ class ConfirmDialogService {
|
|
|
1075
1083
|
this.dialogRef = null;
|
|
1076
1084
|
}
|
|
1077
1085
|
}
|
|
1078
|
-
static
|
|
1079
|
-
static
|
|
1086
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ConfirmDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1087
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ConfirmDialogService, providedIn: 'root' }); }
|
|
1080
1088
|
}
|
|
1081
1089
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ConfirmDialogService, decorators: [{
|
|
1082
1090
|
type: Injectable,
|
|
@@ -1084,22 +1092,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
|
|
|
1084
1092
|
}], ctorParameters: () => [] });
|
|
1085
1093
|
|
|
1086
1094
|
class ModalService {
|
|
1087
|
-
stackSignal = signal([], ...(ngDevMode ? [{ debugName: "stackSignal" }] : /* istanbul ignore next */ []));
|
|
1088
|
-
closeRequestSignal = signal(0, ...(ngDevMode ? [{ debugName: "closeRequestSignal" }] : /* istanbul ignore next */ []));
|
|
1089
|
-
router = inject(Router);
|
|
1090
|
-
destroyRef = inject(DestroyRef);
|
|
1091
1095
|
constructor() {
|
|
1096
|
+
this.stackSignal = signal([], ...(ngDevMode ? [{ debugName: "stackSignal" }] : /* istanbul ignore next */ []));
|
|
1097
|
+
this.closeRequestSignal = signal(0, ...(ngDevMode ? [{ debugName: "closeRequestSignal" }] : /* istanbul ignore next */ []));
|
|
1098
|
+
this.router = inject(Router);
|
|
1099
|
+
this.destroyRef = inject(DestroyRef);
|
|
1100
|
+
this.modalStack = computed(() => this.stackSignal(), ...(ngDevMode ? [{ debugName: "modalStack" }] : /* istanbul ignore next */ []));
|
|
1101
|
+
this.currentModal = computed(() => {
|
|
1102
|
+
const stack = this.stackSignal();
|
|
1103
|
+
return stack.length > 0 ? stack[stack.length - 1] : null;
|
|
1104
|
+
}, ...(ngDevMode ? [{ debugName: "currentModal" }] : /* istanbul ignore next */ []));
|
|
1105
|
+
this.closeRequest = computed(() => this.closeRequestSignal(), ...(ngDevMode ? [{ debugName: "closeRequest" }] : /* istanbul ignore next */ []));
|
|
1092
1106
|
this.router.events.subscribe(() => {
|
|
1093
1107
|
this.stackSignal.set([]);
|
|
1094
1108
|
});
|
|
1095
1109
|
this.destroyRef.onDestroy(() => this.stackSignal.set([]));
|
|
1096
1110
|
}
|
|
1097
|
-
modalStack = computed(() => this.stackSignal(), ...(ngDevMode ? [{ debugName: "modalStack" }] : /* istanbul ignore next */ []));
|
|
1098
|
-
currentModal = computed(() => {
|
|
1099
|
-
const stack = this.stackSignal();
|
|
1100
|
-
return stack.length > 0 ? stack[stack.length - 1] : null;
|
|
1101
|
-
}, ...(ngDevMode ? [{ debugName: "currentModal" }] : /* istanbul ignore next */ []));
|
|
1102
|
-
closeRequest = computed(() => this.closeRequestSignal(), ...(ngDevMode ? [{ debugName: "closeRequest" }] : /* istanbul ignore next */ []));
|
|
1103
1111
|
open(config) {
|
|
1104
1112
|
this.stackSignal.update((stack) => [...stack, config]);
|
|
1105
1113
|
}
|
|
@@ -1117,8 +1125,8 @@ class ModalService {
|
|
|
1117
1125
|
clear() {
|
|
1118
1126
|
this.stackSignal.set([]);
|
|
1119
1127
|
}
|
|
1120
|
-
static
|
|
1121
|
-
static
|
|
1128
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ModalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1129
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ModalService, providedIn: 'root' }); }
|
|
1122
1130
|
}
|
|
1123
1131
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ModalService, decorators: [{
|
|
1124
1132
|
type: Injectable,
|
|
@@ -1133,30 +1141,30 @@ const icons$3 = {
|
|
|
1133
1141
|
'loader-circle': LucideLoaderCircle,
|
|
1134
1142
|
};
|
|
1135
1143
|
class ModalComponent {
|
|
1136
|
-
getIcon = (name) => icons$3[name] ?? LucideX;
|
|
1137
|
-
notificationSrv = inject(NotificationService);
|
|
1138
|
-
destroyRef = inject(DestroyRef);
|
|
1139
|
-
modalSrv = inject(ModalService);
|
|
1140
|
-
transloco = inject(TranslocoService);
|
|
1141
|
-
cdr = inject(ChangeDetectorRef);
|
|
1142
|
-
container = viewChild('dynamicContent', { ...(ngDevMode ? { debugName: "container" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
|
|
1143
|
-
currentConfig = signal(null, ...(ngDevMode ? [{ debugName: "currentConfig" }] : /* istanbul ignore next */ []));
|
|
1144
|
-
title = signal('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
1145
|
-
visible = signal(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
1146
|
-
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
1147
|
-
isProcessing = signal(false, ...(ngDevMode ? [{ debugName: "isProcessing" }] : /* istanbul ignore next */ []));
|
|
1148
|
-
isExpanded = signal(false, ...(ngDevMode ? [{ debugName: "isExpanded" }] : /* istanbul ignore next */ []));
|
|
1149
|
-
isFormValid = signal(false, ...(ngDevMode ? [{ debugName: "isFormValid" }] : /* istanbul ignore next */ []));
|
|
1150
|
-
componentRef = null;
|
|
1151
|
-
subscriptions = [];
|
|
1152
|
-
computedModalWidth = computed(() => {
|
|
1153
|
-
return this.isExpanded() ? '100vw' : (this.currentConfig()?.width ?? '560px');
|
|
1154
|
-
}, ...(ngDevMode ? [{ debugName: "computedModalWidth" }] : /* istanbul ignore next */ []));
|
|
1155
|
-
modalButtonsVisible = computed(() => this.currentConfig()?.showButtons ?? true, ...(ngDevMode ? [{ debugName: "modalButtonsVisible" }] : /* istanbul ignore next */ []));
|
|
1156
|
-
showExpandButton = computed(() => this.currentConfig()?.showExpandButton ?? false, ...(ngDevMode ? [{ debugName: "showExpandButton" }] : /* istanbul ignore next */ []));
|
|
1157
|
-
cancelLabel = computed(() => this.currentConfig()?.cancelLabel || 'Cancelar', ...(ngDevMode ? [{ debugName: "cancelLabel" }] : /* istanbul ignore next */ []));
|
|
1158
|
-
acceptLabel = computed(() => this.currentConfig()?.acceptLabel || 'Aceptar', ...(ngDevMode ? [{ debugName: "acceptLabel" }] : /* istanbul ignore next */ []));
|
|
1159
1144
|
constructor() {
|
|
1145
|
+
this.getIcon = (name) => icons$3[name] ?? LucideX;
|
|
1146
|
+
this.notificationSrv = inject(NotificationService);
|
|
1147
|
+
this.destroyRef = inject(DestroyRef);
|
|
1148
|
+
this.modalSrv = inject(ModalService);
|
|
1149
|
+
this.transloco = inject(TranslocoService);
|
|
1150
|
+
this.cdr = inject(ChangeDetectorRef);
|
|
1151
|
+
this.container = viewChild('dynamicContent', { ...(ngDevMode ? { debugName: "container" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
|
|
1152
|
+
this.currentConfig = signal(null, ...(ngDevMode ? [{ debugName: "currentConfig" }] : /* istanbul ignore next */ []));
|
|
1153
|
+
this.title = signal('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
1154
|
+
this.visible = signal(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
1155
|
+
this.loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
1156
|
+
this.isProcessing = signal(false, ...(ngDevMode ? [{ debugName: "isProcessing" }] : /* istanbul ignore next */ []));
|
|
1157
|
+
this.isExpanded = signal(false, ...(ngDevMode ? [{ debugName: "isExpanded" }] : /* istanbul ignore next */ []));
|
|
1158
|
+
this.isFormValid = signal(false, ...(ngDevMode ? [{ debugName: "isFormValid" }] : /* istanbul ignore next */ []));
|
|
1159
|
+
this.componentRef = null;
|
|
1160
|
+
this.subscriptions = [];
|
|
1161
|
+
this.computedModalWidth = computed(() => {
|
|
1162
|
+
return this.isExpanded() ? '100vw' : (this.currentConfig()?.width ?? '560px');
|
|
1163
|
+
}, ...(ngDevMode ? [{ debugName: "computedModalWidth" }] : /* istanbul ignore next */ []));
|
|
1164
|
+
this.modalButtonsVisible = computed(() => this.currentConfig()?.showButtons ?? true, ...(ngDevMode ? [{ debugName: "modalButtonsVisible" }] : /* istanbul ignore next */ []));
|
|
1165
|
+
this.showExpandButton = computed(() => this.currentConfig()?.showExpandButton ?? false, ...(ngDevMode ? [{ debugName: "showExpandButton" }] : /* istanbul ignore next */ []));
|
|
1166
|
+
this.cancelLabel = computed(() => this.currentConfig()?.cancelLabel || 'Cancelar', ...(ngDevMode ? [{ debugName: "cancelLabel" }] : /* istanbul ignore next */ []));
|
|
1167
|
+
this.acceptLabel = computed(() => this.currentConfig()?.acceptLabel || 'Aceptar', ...(ngDevMode ? [{ debugName: "acceptLabel" }] : /* istanbul ignore next */ []));
|
|
1160
1168
|
effect(() => {
|
|
1161
1169
|
const config = this.modalSrv.currentModal();
|
|
1162
1170
|
if (config) {
|
|
@@ -1304,8 +1312,8 @@ class ModalComponent {
|
|
|
1304
1312
|
this.componentRef = null;
|
|
1305
1313
|
}
|
|
1306
1314
|
}
|
|
1307
|
-
static
|
|
1308
|
-
static
|
|
1315
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1316
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: ModalComponent, isStandalone: true, selector: "shk-modal", viewQueries: [{ propertyName: "container", first: true, predicate: ["dynamicContent"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "@if (visible()) {\n <div\n class=\"fixed inset-0 bg-black/40 backdrop-blur-sm flex items-center justify-center z-40 p-4 pt-4 overflow-y-auto\"\n (click)=\"closeModal()\"\n >\n <div\n class=\"bg-white dark:[background-color:var(--shk-surface-100)] rounded-xl shadow-2xl overflow-hidden flex flex-col animate-in fade-in zoom-in duration-200\"\n [class.w-[95vw]]=\"isExpanded()\"\n [class.h-[90vh]]=\"isExpanded()\"\n [class.w-full]=\"!isExpanded()\"\n [style.max-width]=\"isExpanded() ? undefined : computedModalWidth()\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"h-1.5 w-full _shk-gradient-emerald shrink-0\"></div>\n\n <div class=\"flex items-center justify-between px-6 pt-4 pb-2 shrink-0\">\n <span class=\"font-semibold text-lg _shk-text-surface-800 dark:[color:var(--shk-surface-800)]\">{{ title() }}</span>\n <div class=\"flex items-center gap-2\">\n @if (showExpandButton()) {\n <button\n type=\"button\"\n (click)=\"toggleExpand()\"\n class=\"p-1.5 rounded-lg hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] _shk-text-surface-500 dark:[color:var(--shk-surface-500)] transition-colors\"\n >\n @if (isExpanded()) {\n <svg [lucideIcon]=\"getIcon('minimize-2')\" class=\"w-4 h-4\"></svg>\n } @else {\n <svg [lucideIcon]=\"getIcon('maximize-2')\" class=\"w-4 h-4\"></svg>\n }\n </button>\n }\n <button\n type=\"button\"\n (click)=\"closeModal()\"\n class=\"p-1.5 rounded-lg hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] _shk-text-surface-500 dark:[color:var(--shk-surface-500)] transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('x')\" class=\"w-4 h-4\"></svg>\n </button>\n </div>\n </div>\n\n <div class=\"overflow-y-auto px-6 py-4 flex-1 max-h-[70vh]\">\n <ng-container #dynamicContent></ng-container>\n </div>\n\n @if (modalButtonsVisible()) {\n <hr class=\"border-t _shk-border dark:[border-color:var(--shk-surface-200)] shrink-0\" />\n <div class=\"flex justify-end gap-3 px-6 py-4 shrink-0\">\n <button\n type=\"button\"\n (click)=\"closeModal()\"\n [disabled]=\"loading()\"\n class=\"px-4 py-2 text-sm font-semibold _shk-text-surface-600 dark:[color:var(--shk-surface-600)] _shk-bg-surface-100 dark:[background-color:var(--shk-surface-200)] hover:[background-color:var(--shk-surface-200)] dark:hover:[background-color:var(--shk-surface-300)] rounded-lg transition-colors flex items-center gap-2 disabled:opacity-50\"\n >\n <svg [lucideIcon]=\"getIcon('x')\" class=\"w-4 h-4\"></svg>\n {{ cancelLabel() }}\n </button>\n <button\n type=\"button\"\n (click)=\"onAccept()\"\n [disabled]=\"loading()\"\n class=\"px-4 py-2 text-sm font-semibold _shk-text-white _shk-bg-emerald hover:[background-color:var(--shk-emerald-700)] rounded-lg shadow-md transition-all flex items-center gap-2 disabled:opacity-50\"\n >\n @if (loading()) {\n <svg [lucideIcon]=\"getIcon('loader-circle')\" class=\"w-4 h-4 animate-spin\"></svg>\n } @else {\n <svg [lucideIcon]=\"getIcon('check')\" class=\"w-4 h-4\"></svg>\n }\n {{ acceptLabel() }}\n </button>\n </div>\n }\n </div>\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1309
1317
|
}
|
|
1310
1318
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ModalComponent, decorators: [{
|
|
1311
1319
|
type: Component,
|
|
@@ -1318,198 +1326,197 @@ const icons$2 = {
|
|
|
1318
1326
|
'chevron-right': LucideChevronRight,
|
|
1319
1327
|
};
|
|
1320
1328
|
class SelectComponent {
|
|
1321
|
-
elementRef
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
return undefined;
|
|
1374
|
-
}, ...(ngDevMode ? [{ debugName: "actualControl" }] : /* istanbul ignore next */ []));
|
|
1375
|
-
shouldShowError = computed(() => {
|
|
1376
|
-
this.errorTracker();
|
|
1377
|
-
const ctrl = this.actualControl();
|
|
1378
|
-
return ctrl?.invalid && (ctrl?.dirty || ctrl?.touched);
|
|
1379
|
-
}, ...(ngDevMode ? [{ debugName: "shouldShowError" }] : /* istanbul ignore next */ []));
|
|
1380
|
-
wasFixedError = computed(() => {
|
|
1381
|
-
this.errorTracker();
|
|
1382
|
-
const ctrl = this.actualControl();
|
|
1383
|
-
return this.hadError() && ctrl?.valid && ctrl?.touched;
|
|
1384
|
-
}, ...(ngDevMode ? [{ debugName: "wasFixedError" }] : /* istanbul ignore next */ []));
|
|
1385
|
-
displayValue = computed(() => {
|
|
1386
|
-
const val = this._value();
|
|
1387
|
-
const opts = this.options();
|
|
1388
|
-
const isMultiple = this.multiple();
|
|
1389
|
-
const ph = this.placeholder();
|
|
1390
|
-
if (!val || (Array.isArray(val) && val.length === 0)) {
|
|
1391
|
-
return ph;
|
|
1392
|
-
}
|
|
1393
|
-
if (isMultiple) {
|
|
1394
|
-
const values = Array.isArray(val) ? val : [];
|
|
1395
|
-
const selectedLabels = opts
|
|
1396
|
-
.filter((option) => values.includes(option.value))
|
|
1397
|
-
.map((option) => option.label);
|
|
1398
|
-
if (selectedLabels.length === 0) {
|
|
1399
|
-
return values.toString();
|
|
1329
|
+
constructor(elementRef) {
|
|
1330
|
+
this.elementRef = elementRef;
|
|
1331
|
+
this.getIcon = (name) => icons$2[name] ?? LucideChevronDown;
|
|
1332
|
+
this.options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
1333
|
+
this.multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
1334
|
+
this.validCombinations = input(undefined, ...(ngDevMode ? [{ debugName: "validCombinations" }] : /* istanbul ignore next */ []));
|
|
1335
|
+
this.placeholder = input('Seleccionar...', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
1336
|
+
this.label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1337
|
+
this.isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
|
|
1338
|
+
this.isAllDataLoaded = input(false, ...(ngDevMode ? [{ debugName: "isAllDataLoaded" }] : /* istanbul ignore next */ []));
|
|
1339
|
+
this.allowCustomEntries = input(false, ...(ngDevMode ? [{ debugName: "allowCustomEntries" }] : /* istanbul ignore next */ []));
|
|
1340
|
+
this.formGroup = input(undefined, ...(ngDevMode ? [{ debugName: "formGroup" }] : /* istanbul ignore next */ []));
|
|
1341
|
+
this.isSearchable = input(false, ...(ngDevMode ? [{ debugName: "isSearchable" }] : /* istanbul ignore next */ []));
|
|
1342
|
+
this.itemsPerPage = input(10, ...(ngDevMode ? [{ debugName: "itemsPerPage" }] : /* istanbul ignore next */ []));
|
|
1343
|
+
this.control = input(undefined, ...(ngDevMode ? [{ debugName: "control" }] : /* istanbul ignore next */ []));
|
|
1344
|
+
this.usePagination = input(false, ...(ngDevMode ? [{ debugName: "usePagination" }] : /* istanbul ignore next */ []));
|
|
1345
|
+
this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
1346
|
+
this.errorMessages = input({
|
|
1347
|
+
required: 'Este campo es requerido',
|
|
1348
|
+
}, ...(ngDevMode ? [{ debugName: "errorMessages" }] : /* istanbul ignore next */ []));
|
|
1349
|
+
this.preserveSearchOnLoad = input(false, ...(ngDevMode ? [{ debugName: "preserveSearchOnLoad" }] : /* istanbul ignore next */ []));
|
|
1350
|
+
this.emptyMessageKey = input('common.no_records', ...(ngDevMode ? [{ debugName: "emptyMessageKey" }] : /* istanbul ignore next */ []));
|
|
1351
|
+
this.dropdownUpward = input(false, ...(ngDevMode ? [{ debugName: "dropdownUpward" }] : /* istanbul ignore next */ []));
|
|
1352
|
+
this.showEmptyOption = input(true, ...(ngDevMode ? [{ debugName: "showEmptyOption" }] : /* istanbul ignore next */ []));
|
|
1353
|
+
this.selectionChange = output();
|
|
1354
|
+
this.search = output();
|
|
1355
|
+
this.filterInput = viewChild('filterInput', ...(ngDevMode ? [{ debugName: "filterInput" }] : /* istanbul ignore next */ []));
|
|
1356
|
+
this.selectContainer = viewChild('selectContainer', ...(ngDevMode ? [{ debugName: "selectContainer" }] : /* istanbul ignore next */ []));
|
|
1357
|
+
this.selectTrigger = viewChild('selectTrigger', ...(ngDevMode ? [{ debugName: "selectTrigger" }] : /* istanbul ignore next */ []));
|
|
1358
|
+
this.dropdownContainer = viewChild('dropdownContainer', ...(ngDevMode ? [{ debugName: "dropdownContainer" }] : /* istanbul ignore next */ []));
|
|
1359
|
+
this._value = signal(null, ...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
|
|
1360
|
+
this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
1361
|
+
this.focusedIndex = signal(-1, ...(ngDevMode ? [{ debugName: "focusedIndex" }] : /* istanbul ignore next */ []));
|
|
1362
|
+
this.searchTerm = signal('', ...(ngDevMode ? [{ debugName: "searchTerm" }] : /* istanbul ignore next */ []));
|
|
1363
|
+
this.currentPage = signal(1, ...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
|
|
1364
|
+
this.searchTermChanged = signal(false, ...(ngDevMode ? [{ debugName: "searchTermChanged" }] : /* istanbul ignore next */ []));
|
|
1365
|
+
this._isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_isDisabled" }] : /* istanbul ignore next */ []));
|
|
1366
|
+
this.debounceTimer = null;
|
|
1367
|
+
this.errorTracker = signal(0, ...(ngDevMode ? [{ debugName: "errorTracker" }] : /* istanbul ignore next */ []));
|
|
1368
|
+
this.hadError = signal(false, ...(ngDevMode ? [{ debugName: "hadError" }] : /* istanbul ignore next */ []));
|
|
1369
|
+
this.subscribed = signal(false, ...(ngDevMode ? [{ debugName: "subscribed" }] : /* istanbul ignore next */ []));
|
|
1370
|
+
this.valueSubscribed = signal(false, ...(ngDevMode ? [{ debugName: "valueSubscribed" }] : /* istanbul ignore next */ []));
|
|
1371
|
+
this.value = computed(() => this._value(), ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
1372
|
+
this.isDisabled = computed(() => this.disabled() || this._isDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
1373
|
+
this.actualControl = computed(() => {
|
|
1374
|
+
const ctrl = this.control();
|
|
1375
|
+
if (ctrl)
|
|
1376
|
+
return ctrl;
|
|
1377
|
+
const fg = this.formGroup();
|
|
1378
|
+
const lbl = this.label();
|
|
1379
|
+
if (fg && lbl) {
|
|
1380
|
+
return fg.get(lbl);
|
|
1400
1381
|
}
|
|
1401
|
-
return
|
|
1402
|
-
}
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1382
|
+
return undefined;
|
|
1383
|
+
}, ...(ngDevMode ? [{ debugName: "actualControl" }] : /* istanbul ignore next */ []));
|
|
1384
|
+
this.shouldShowError = computed(() => {
|
|
1385
|
+
this.errorTracker();
|
|
1386
|
+
const ctrl = this.actualControl();
|
|
1387
|
+
return ctrl?.invalid && (ctrl?.dirty || ctrl?.touched);
|
|
1388
|
+
}, ...(ngDevMode ? [{ debugName: "shouldShowError" }] : /* istanbul ignore next */ []));
|
|
1389
|
+
this.wasFixedError = computed(() => {
|
|
1390
|
+
this.errorTracker();
|
|
1391
|
+
const ctrl = this.actualControl();
|
|
1392
|
+
return this.hadError() && ctrl?.valid && ctrl?.touched;
|
|
1393
|
+
}, ...(ngDevMode ? [{ debugName: "wasFixedError" }] : /* istanbul ignore next */ []));
|
|
1394
|
+
this.displayValue = computed(() => {
|
|
1395
|
+
const val = this._value();
|
|
1396
|
+
const opts = this.options();
|
|
1397
|
+
const isMultiple = this.multiple();
|
|
1398
|
+
const ph = this.placeholder();
|
|
1399
|
+
if (!val || (Array.isArray(val) && val.length === 0)) {
|
|
1400
|
+
return ph;
|
|
1401
|
+
}
|
|
1402
|
+
if (isMultiple) {
|
|
1403
|
+
const values = Array.isArray(val) ? val : [];
|
|
1404
|
+
const selectedLabels = opts
|
|
1405
|
+
.filter((option) => values.includes(option.value))
|
|
1406
|
+
.map((option) => option.label);
|
|
1407
|
+
if (selectedLabels.length === 0) {
|
|
1408
|
+
return values.toString();
|
|
1409
|
+
}
|
|
1410
|
+
return selectedLabels.join(', ');
|
|
1411
|
+
}
|
|
1412
|
+
const selectedOption = opts.find((opt) => opt.value === val);
|
|
1413
|
+
return selectedOption ? selectedOption.label : val;
|
|
1414
|
+
}, ...(ngDevMode ? [{ debugName: "displayValue" }] : /* istanbul ignore next */ []));
|
|
1415
|
+
this.getErrorMessages = computed(() => {
|
|
1416
|
+
this.errorTracker();
|
|
1417
|
+
const ctrl = this.actualControl();
|
|
1418
|
+
if (!ctrl?.errors)
|
|
1419
|
+
return [];
|
|
1420
|
+
const customErrors = this.errorMessages();
|
|
1421
|
+
const t = this.transloco;
|
|
1422
|
+
return Object.keys(ctrl.errors).map((errorKey) => {
|
|
1423
|
+
if (customErrors[errorKey])
|
|
1424
|
+
return customErrors[errorKey];
|
|
1425
|
+
switch (errorKey) {
|
|
1426
|
+
case 'required':
|
|
1427
|
+
return t.translate('validation.required');
|
|
1428
|
+
case 'email':
|
|
1429
|
+
return t.translate('validation.email');
|
|
1430
|
+
case 'minlength':
|
|
1431
|
+
return t.translate('validation.minlength', {
|
|
1432
|
+
min: ctrl.errors['minlength'].requiredLength,
|
|
1433
|
+
});
|
|
1434
|
+
case 'maxlength':
|
|
1435
|
+
return t.translate('validation.maxlength', {
|
|
1436
|
+
max: ctrl.errors['maxlength'].requiredLength,
|
|
1437
|
+
});
|
|
1438
|
+
case 'pattern':
|
|
1439
|
+
return t.translate('validation.pattern');
|
|
1440
|
+
default:
|
|
1441
|
+
return t.translate('validation.invalid');
|
|
1442
|
+
}
|
|
1443
|
+
});
|
|
1444
|
+
}, ...(ngDevMode ? [{ debugName: "getErrorMessages" }] : /* istanbul ignore next */ []));
|
|
1445
|
+
this.filteredOptions = computed(() => {
|
|
1446
|
+
const opts = this.options();
|
|
1447
|
+
const term = this.searchTerm();
|
|
1448
|
+
if (!term)
|
|
1449
|
+
return opts;
|
|
1450
|
+
const normalizedSearchTerm = this.normalizeText(term);
|
|
1451
|
+
const matched = opts.filter((option) => this.normalizeText(option.label).includes(normalizedSearchTerm));
|
|
1452
|
+
return matched.sort((a, b) => {
|
|
1453
|
+
const aLbl = this.normalizeText(a.label);
|
|
1454
|
+
const bLbl = this.normalizeText(b.label);
|
|
1455
|
+
const aStarts = aLbl.startsWith(normalizedSearchTerm);
|
|
1456
|
+
const bStarts = bLbl.startsWith(normalizedSearchTerm);
|
|
1457
|
+
if (aStarts && !bStarts)
|
|
1458
|
+
return -1;
|
|
1459
|
+
if (!aStarts && bStarts)
|
|
1460
|
+
return 1;
|
|
1461
|
+
return 0;
|
|
1462
|
+
});
|
|
1463
|
+
}, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : /* istanbul ignore next */ []));
|
|
1464
|
+
this.paginatedOptions = computed(() => {
|
|
1465
|
+
let filtered = this.filteredOptions();
|
|
1466
|
+
const term = this.searchTerm();
|
|
1467
|
+
const allowCustom = this.allowCustomEntries();
|
|
1468
|
+
if (allowCustom && term && !filtered.some((o) => o.value === term)) {
|
|
1469
|
+
filtered = [
|
|
1470
|
+
{
|
|
1471
|
+
label: `${term} (nuevo)`,
|
|
1472
|
+
value: term,
|
|
1473
|
+
custom: true,
|
|
1474
|
+
},
|
|
1475
|
+
...filtered,
|
|
1476
|
+
];
|
|
1477
|
+
}
|
|
1478
|
+
if (!this.usePagination()) {
|
|
1479
|
+
return filtered;
|
|
1480
|
+
}
|
|
1481
|
+
const page = this.currentPage();
|
|
1482
|
+
const perPage = this.itemsPerPage();
|
|
1483
|
+
const startIndex = (page - 1) * perPage;
|
|
1484
|
+
const endIndex = startIndex + perPage;
|
|
1485
|
+
return filtered.slice(startIndex, endIndex);
|
|
1486
|
+
}, ...(ngDevMode ? [{ debugName: "paginatedOptions" }] : /* istanbul ignore next */ []));
|
|
1487
|
+
this.regularOptions = computed(() => {
|
|
1488
|
+
const opts = this.paginatedOptions().filter((option) => !option.custom);
|
|
1489
|
+
if (!this.multiple() && this.showEmptyOption()) {
|
|
1490
|
+
return [{ label: '- Sin selección -', value: null }, ...opts];
|
|
1433
1491
|
}
|
|
1434
|
-
});
|
|
1435
|
-
}, ...(ngDevMode ? [{ debugName: "getErrorMessages" }] : /* istanbul ignore next */ []));
|
|
1436
|
-
filteredOptions = computed(() => {
|
|
1437
|
-
const opts = this.options();
|
|
1438
|
-
const term = this.searchTerm();
|
|
1439
|
-
if (!term)
|
|
1440
1492
|
return opts;
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
const aLbl = this.normalizeText(a.label);
|
|
1445
|
-
const bLbl = this.normalizeText(b.label);
|
|
1446
|
-
const aStarts = aLbl.startsWith(normalizedSearchTerm);
|
|
1447
|
-
const bStarts = bLbl.startsWith(normalizedSearchTerm);
|
|
1448
|
-
if (aStarts && !bStarts)
|
|
1449
|
-
return -1;
|
|
1450
|
-
if (!aStarts && bStarts)
|
|
1493
|
+
}, ...(ngDevMode ? [{ debugName: "regularOptions" }] : /* istanbul ignore next */ []));
|
|
1494
|
+
this.totalPages = computed(() => {
|
|
1495
|
+
if (!this.usePagination()) {
|
|
1451
1496
|
return 1;
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
const endIndex = startIndex + perPage;
|
|
1476
|
-
return filtered.slice(startIndex, endIndex);
|
|
1477
|
-
}, ...(ngDevMode ? [{ debugName: "paginatedOptions" }] : /* istanbul ignore next */ []));
|
|
1478
|
-
regularOptions = computed(() => {
|
|
1479
|
-
const opts = this.paginatedOptions().filter((option) => !option.custom);
|
|
1480
|
-
if (!this.multiple() && this.showEmptyOption()) {
|
|
1481
|
-
return [{ label: '- Sin selección -', value: null }, ...opts];
|
|
1482
|
-
}
|
|
1483
|
-
return opts;
|
|
1484
|
-
}, ...(ngDevMode ? [{ debugName: "regularOptions" }] : /* istanbul ignore next */ []));
|
|
1485
|
-
totalPages = computed(() => {
|
|
1486
|
-
if (!this.usePagination()) {
|
|
1487
|
-
return 1;
|
|
1488
|
-
}
|
|
1489
|
-
const filtered = this.filteredOptions();
|
|
1490
|
-
const perPage = this.itemsPerPage();
|
|
1491
|
-
return Math.ceil(filtered.length / perPage);
|
|
1492
|
-
}, ...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
|
|
1493
|
-
hasSelectedValues = computed(() => {
|
|
1494
|
-
const val = this._value();
|
|
1495
|
-
if (this.multiple()) {
|
|
1496
|
-
return val && val.length > 0;
|
|
1497
|
-
}
|
|
1498
|
-
return !!val;
|
|
1499
|
-
}, ...(ngDevMode ? [{ debugName: "hasSelectedValues" }] : /* istanbul ignore next */ []));
|
|
1500
|
-
showCustomOption = computed(() => {
|
|
1501
|
-
const term = this.searchTerm();
|
|
1502
|
-
const opts = this.options();
|
|
1503
|
-
return (this.allowCustomEntries() &&
|
|
1504
|
-
term !== '' &&
|
|
1505
|
-
!opts.some((o) => o.value === term));
|
|
1506
|
-
}, ...(ngDevMode ? [{ debugName: "showCustomOption" }] : /* istanbul ignore next */ []));
|
|
1507
|
-
transloco = inject(TranslocoService);
|
|
1508
|
-
onChange = (_) => { };
|
|
1509
|
-
onTouched = () => { };
|
|
1510
|
-
destroyRef = inject(DestroyRef);
|
|
1511
|
-
constructor(elementRef) {
|
|
1512
|
-
this.elementRef = elementRef;
|
|
1497
|
+
}
|
|
1498
|
+
const filtered = this.filteredOptions();
|
|
1499
|
+
const perPage = this.itemsPerPage();
|
|
1500
|
+
return Math.ceil(filtered.length / perPage);
|
|
1501
|
+
}, ...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
|
|
1502
|
+
this.hasSelectedValues = computed(() => {
|
|
1503
|
+
const val = this._value();
|
|
1504
|
+
if (this.multiple()) {
|
|
1505
|
+
return val && val.length > 0;
|
|
1506
|
+
}
|
|
1507
|
+
return !!val;
|
|
1508
|
+
}, ...(ngDevMode ? [{ debugName: "hasSelectedValues" }] : /* istanbul ignore next */ []));
|
|
1509
|
+
this.showCustomOption = computed(() => {
|
|
1510
|
+
const term = this.searchTerm();
|
|
1511
|
+
const opts = this.options();
|
|
1512
|
+
return (this.allowCustomEntries() &&
|
|
1513
|
+
term !== '' &&
|
|
1514
|
+
!opts.some((o) => o.value === term));
|
|
1515
|
+
}, ...(ngDevMode ? [{ debugName: "showCustomOption" }] : /* istanbul ignore next */ []));
|
|
1516
|
+
this.transloco = inject(TranslocoService);
|
|
1517
|
+
this.onChange = (_) => { };
|
|
1518
|
+
this.onTouched = () => { };
|
|
1519
|
+
this.destroyRef = inject(DestroyRef);
|
|
1513
1520
|
effect(() => {
|
|
1514
1521
|
const term = this.searchTerm();
|
|
1515
1522
|
if (term !== '' && this.isSearchable()) {
|
|
@@ -1919,14 +1926,14 @@ class SelectComponent {
|
|
|
1919
1926
|
registerOnTouched(fn) {
|
|
1920
1927
|
this.onTouched = fn;
|
|
1921
1928
|
}
|
|
1922
|
-
static
|
|
1923
|
-
static
|
|
1929
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: SelectComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1930
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: SelectComponent, isStandalone: true, selector: "shk-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, validCombinations: { classPropertyName: "validCombinations", publicName: "validCombinations", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, isAllDataLoaded: { classPropertyName: "isAllDataLoaded", publicName: "isAllDataLoaded", isSignal: true, isRequired: false, transformFunction: null }, allowCustomEntries: { classPropertyName: "allowCustomEntries", publicName: "allowCustomEntries", isSignal: true, isRequired: false, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: false, transformFunction: null }, isSearchable: { classPropertyName: "isSearchable", publicName: "isSearchable", isSignal: true, isRequired: false, transformFunction: null }, itemsPerPage: { classPropertyName: "itemsPerPage", publicName: "itemsPerPage", isSignal: true, isRequired: false, transformFunction: null }, control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, usePagination: { classPropertyName: "usePagination", publicName: "usePagination", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: true, isRequired: false, transformFunction: null }, preserveSearchOnLoad: { classPropertyName: "preserveSearchOnLoad", publicName: "preserveSearchOnLoad", isSignal: true, isRequired: false, transformFunction: null }, emptyMessageKey: { classPropertyName: "emptyMessageKey", publicName: "emptyMessageKey", isSignal: true, isRequired: false, transformFunction: null }, dropdownUpward: { classPropertyName: "dropdownUpward", publicName: "dropdownUpward", isSignal: true, isRequired: false, transformFunction: null }, showEmptyOption: { classPropertyName: "showEmptyOption", publicName: "showEmptyOption", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", search: "search" }, host: { listeners: { "document:mousedown": "onClickOutside($event)" } }, providers: [
|
|
1924
1931
|
{
|
|
1925
1932
|
provide: NG_VALUE_ACCESSOR,
|
|
1926
1933
|
useExisting: forwardRef(() => SelectComponent),
|
|
1927
1934
|
multi: true,
|
|
1928
1935
|
},
|
|
1929
|
-
], viewQueries: [{ propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true, isSignal: true }, { propertyName: "selectContainer", first: true, predicate: ["selectContainer"], descendants: true, isSignal: true }, { propertyName: "selectTrigger", first: true, predicate: ["selectTrigger"], descendants: true, isSignal: true }, { propertyName: "dropdownContainer", first: true, predicate: ["dropdownContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n #selectContainer\n class=\"relative w-full font-sans outline-none\"\n>\n @if (label()) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] mb-1\">\n {{ label() }}\n </div>\n }\n\n <div\n #selectTrigger\n class=\"flex justify-between items-center w-full px-3 py-2 border _shk-border rounded-lg _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] transition-colors duration-150 cursor-pointer min-h-[2.5rem] _shk-text-surface-700 dark:[color:var(--shk-surface-700)] focus-within:outline-none focus-within:[background-color:var(--shk-surface-50)] dark:focus-within:[background-color:var(--shk-surface-100)] focus-within:ring-1 focus-within:[--tw-ring-color:var(--shk-primary-500)] focus-within:[border-color:var(--shk-primary-500)] focus:outline-none focus:ring-1 focus:[--tw-ring-color:var(--shk-primary-500)] focus:[border-color:var(--shk-primary-500)] sm:text-sm\"\n [attr.tabindex]=\"isDisabled() ? -1 : 0\"\n (keydown)=\"onKeydown($event)\"\n (click)=\"toggleDropdown()\"\n [class.open]=\"isOpen()\"\n [class.disabled-select]=\"isDisabled()\"\n [class._shk-border-red]=\"shouldShowError()\"\n >\n <div class=\"selected-value truncate\">\n @if (isSearchable() && isOpen()) {\n <input\n #filterInput\n type=\"text\"\n class=\"w-full bg-transparent border-0 outline-none p-0 _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\"\n placeholder=\"Buscar...\"\n [value]=\"searchTerm()\"\n (input)=\"onInputChange($event)\"\n (keydown)=\"handleKeyDown($event)\"\n (click)=\"$event.stopPropagation()\"\n />\n } @else {\n <span\n [class._shk-text-surface-400]=\"!hasSelectedValues()\"\n [class._shk-text-surface-800]=\"hasSelectedValues()\"\n >\n {{ displayValue() }}\n </span>\n }\n </div>\n <div\n class=\"text-xs transition-transform duration-200 shrink-0 ml-2\"\n [class.rotate-180]=\"isOpen()\"\n >\n <svg\n [lucideIcon]=\"getIcon('chevron-down')\"\n class=\"w-4 h-4 _shk-text-surface-400 dark:[color:var(--shk-surface-400)]\"\n ></svg>\n </div>\n </div>\n\n @if (isOpen()) {\n <div\n #dropdownContainer\n (keydown)=\"onKeydown($event)\"\n class=\"absolute left-0 right-0 _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border _shk-border rounded-lg max-h-[240px] overflow-y-auto z-50 shadow-lg\"\n [class.top-full]=\"!dropdownUpward()\"\n [class.bottom-full]=\"dropdownUpward()\"\n [class.mt-1]=\"!dropdownUpward()\"\n [class.mb-1]=\"dropdownUpward()\"\n >\n @if (showCustomOption()) {\n <div\n class=\"flex items-center gap-2 px-3 py-2 cursor-pointer hover:[background-color:var(--shk-surface-50)] dark:hover:[background-color:var(--shk-surface-200)] text-sm\"\n (click)=\"onCustomOptionClick()\"\n >\n <span class=\"font-semibold _shk-text-primary\">Crear nuevo:</span>\n <span class=\"_shk-text-surface-700 dark:[color:var(--shk-surface-700)] ml-1\">{{ searchTerm() }}</span>\n </div>\n }\n\n @for (option of regularOptions(); track trackByFn($index, option); let i = $index) {\n <div\n class=\"flex items-center gap-2 px-3 py-2 cursor-pointer hover:[background-color:var(--shk-surface-50)] dark:hover:[background-color:var(--shk-surface-200)] text-sm _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\"\n [class.opacity-50]=\"isOptionDisabled(option)\"\n [class.select-option-active]=\"focusedIndex() === i\"\n [class._shk-text-surface-400]=\"option.value === null\"\n (click)=\"!isOptionDisabled(option) && onOptionClick(option)\"\n >\n @if (multiple()) {\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(option)\"\n [disabled]=\"isOptionDisabled(option)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"!isOptionDisabled(option) && toggleOption(option)\"\n class=\"flex-shrink-0 [accent-color:var(--shk-primary-600)]\"\n />\n {{ option.label }}\n } @else {\n {{ option.label }}\n }\n </div>\n }\n\n <div class=\"px-3 py-2 text-center\">\n @if (isLoading() && regularOptions().length === 0) {\n <div class=\"flex items-center justify-center gap-2 text-sm _shk-text-surface-500\">\n <svg class=\"spinner\" viewBox=\"0 0 50 50\">\n <circle\n class=\"path\"\n cx=\"25\"\n cy=\"25\"\n r=\"20\"\n fill=\"none\"\n stroke-width=\"5\"\n ></circle>\n </svg>\n Cargando m\u00E1s resultados...\n </div>\n }\n\n @if (!isLoading() && isAllDataLoaded() && regularOptions().length === 0) {\n <div class=\"text-sm _shk-text-surface-400 italic\">\n No se encontraron coincidencias\n </div>\n }\n\n @if (options().length === 0) {\n <div class=\"text-sm _shk-text-surface-400 italic\">\n {{ emptyMessageKey() | transloco }}\n </div>\n }\n </div>\n\n @if (usePagination() && totalPages() > 1) {\n <div class=\"flex justify-between items-center px-3 py-2 border-t _shk-border\">\n <button\n class=\"bg-transparent border-0 cursor-pointer px-2 py-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-50 disabled:cursor-not-allowed _shk-text-surface-600 dark:[color:var(--shk-surface-600)]\"\n [disabled]=\"currentPage() === 1\"\n (click)=\"$event.stopPropagation(); previousPage()\"\n >\n <svg [lucideIcon]=\"getIcon('chevron-left')\" class=\"w-4 h-4\"></svg>\n </button>\n <span class=\"text-sm _shk-text-surface-600 dark:[color:var(--shk-surface-600)]\">\n {{ currentPage() }} de {{ totalPages() }}\n </span>\n <button\n class=\"bg-transparent border-0 cursor-pointer px-2 py-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-50 disabled:cursor-not-allowed _shk-text-surface-600 dark:[color:var(--shk-surface-600)]\"\n [disabled]=\"currentPage() === totalPages()\"\n (click)=\"$event.stopPropagation(); nextPage()\"\n >\n <svg [lucideIcon]=\"getIcon('chevron-right')\" class=\"w-4 h-4\"></svg>\n </button>\n </div>\n }\n </div>\n }\n\n @if (shouldShowError()) {\n <div class=\"mt-1 text-xs text-red-500 max-h-20 overflow-y-auto\" tabindex=\"-1\">\n <ul class=\"list-disc pl-4 space-y-1\">\n @for (error of getErrorMessages(); track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </div>\n }\n</div>", styles: [".select-option-active{background-color:var(--shk-primary-50);outline:2px solid var(--shk-primary-500);outline-offset:-2px;color:var(--shk-primary-700)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TranslocoModule }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }, { kind: "pipe", type: i1$1.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1936
|
+
], viewQueries: [{ propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true, isSignal: true }, { propertyName: "selectContainer", first: true, predicate: ["selectContainer"], descendants: true, isSignal: true }, { propertyName: "selectTrigger", first: true, predicate: ["selectTrigger"], descendants: true, isSignal: true }, { propertyName: "dropdownContainer", first: true, predicate: ["dropdownContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n #selectContainer\n class=\"relative w-full font-sans outline-none\"\n>\n @if (label()) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] mb-1\">\n {{ label() }}\n </div>\n }\n\n <div\n #selectTrigger\n class=\"flex justify-between items-center w-full px-3 py-2 border _shk-border rounded-lg _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] transition-colors duration-150 cursor-pointer min-h-[2.5rem] _shk-text-surface-700 dark:[color:var(--shk-surface-700)] focus-within:outline-none focus-within:[background-color:var(--shk-surface-50)] dark:focus-within:[background-color:var(--shk-surface-100)] focus-within:ring-1 focus-within:[--tw-ring-color:var(--shk-primary-500)] focus-within:[border-color:var(--shk-primary-500)] focus:outline-none focus:ring-1 focus:[--tw-ring-color:var(--shk-primary-500)] focus:[border-color:var(--shk-primary-500)] sm:text-sm\"\n [attr.tabindex]=\"isDisabled() ? -1 : 0\"\n (keydown)=\"onKeydown($event)\"\n (click)=\"toggleDropdown()\"\n [class.open]=\"isOpen()\"\n [class.disabled-select]=\"isDisabled()\"\n [class._shk-border-red]=\"shouldShowError()\"\n >\n <div class=\"selected-value truncate\">\n @if (isSearchable() && isOpen()) {\n <input\n #filterInput\n type=\"text\"\n class=\"w-full bg-transparent border-0 outline-none p-0 _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\"\n placeholder=\"Buscar...\"\n [value]=\"searchTerm()\"\n (input)=\"onInputChange($event)\"\n (keydown)=\"handleKeyDown($event)\"\n (click)=\"$event.stopPropagation()\"\n />\n } @else {\n <span\n [class._shk-text-surface-400]=\"!hasSelectedValues()\"\n [class._shk-text-surface-800]=\"hasSelectedValues()\"\n >\n {{ displayValue() }}\n </span>\n }\n </div>\n <div\n class=\"text-xs transition-transform duration-200 shrink-0 ml-2\"\n [class.rotate-180]=\"isOpen()\"\n >\n <svg\n [lucideIcon]=\"getIcon('chevron-down')\"\n class=\"w-4 h-4 _shk-text-surface-400 dark:[color:var(--shk-surface-400)]\"\n ></svg>\n </div>\n </div>\n\n @if (isOpen()) {\n <div\n #dropdownContainer\n (keydown)=\"onKeydown($event)\"\n class=\"absolute left-0 right-0 _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border _shk-border rounded-lg max-h-[240px] overflow-y-auto z-50 shadow-lg\"\n [class.top-full]=\"!dropdownUpward()\"\n [class.bottom-full]=\"dropdownUpward()\"\n [class.mt-1]=\"!dropdownUpward()\"\n [class.mb-1]=\"dropdownUpward()\"\n >\n @if (showCustomOption()) {\n <div\n class=\"flex items-center gap-2 px-3 py-2 cursor-pointer hover:[background-color:var(--shk-surface-50)] dark:hover:[background-color:var(--shk-surface-200)] text-sm\"\n (click)=\"onCustomOptionClick()\"\n >\n <span class=\"font-semibold _shk-text-primary\">Crear nuevo:</span>\n <span class=\"_shk-text-surface-700 dark:[color:var(--shk-surface-700)] ml-1\">{{ searchTerm() }}</span>\n </div>\n }\n\n @for (option of regularOptions(); track trackByFn($index, option); let i = $index) {\n <div\n class=\"flex items-center gap-2 px-3 py-2 cursor-pointer hover:[background-color:var(--shk-surface-50)] dark:hover:[background-color:var(--shk-surface-200)] text-sm _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\"\n [class.opacity-50]=\"isOptionDisabled(option)\"\n [class.select-option-active]=\"focusedIndex() === i\"\n [class._shk-text-surface-400]=\"option.value === null\"\n (click)=\"!isOptionDisabled(option) && onOptionClick(option)\"\n >\n @if (multiple()) {\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(option)\"\n [disabled]=\"isOptionDisabled(option)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"!isOptionDisabled(option) && toggleOption(option)\"\n class=\"flex-shrink-0 [accent-color:var(--shk-primary-600)]\"\n />\n {{ option.label }}\n } @else {\n {{ option.label }}\n }\n </div>\n }\n\n <div class=\"px-3 py-2 text-center\">\n @if (isLoading() && regularOptions().length === 0) {\n <div class=\"flex items-center justify-center gap-2 text-sm _shk-text-surface-500\">\n <svg class=\"spinner\" viewBox=\"0 0 50 50\">\n <circle\n class=\"path\"\n cx=\"25\"\n cy=\"25\"\n r=\"20\"\n fill=\"none\"\n stroke-width=\"5\"\n ></circle>\n </svg>\n Cargando m\u00E1s resultados...\n </div>\n }\n\n @if (!isLoading() && isAllDataLoaded() && regularOptions().length === 0) {\n <div class=\"text-sm _shk-text-surface-400 italic\">\n No se encontraron coincidencias\n </div>\n }\n\n @if (options().length === 0) {\n <div class=\"text-sm _shk-text-surface-400 italic\">\n {{ emptyMessageKey() | transloco }}\n </div>\n }\n </div>\n\n @if (usePagination() && totalPages() > 1) {\n <div class=\"flex justify-between items-center px-3 py-2 border-t _shk-border\">\n <button\n class=\"bg-transparent border-0 cursor-pointer px-2 py-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-50 disabled:cursor-not-allowed _shk-text-surface-600 dark:[color:var(--shk-surface-600)]\"\n [disabled]=\"currentPage() === 1\"\n (click)=\"$event.stopPropagation(); previousPage()\"\n >\n <svg [lucideIcon]=\"getIcon('chevron-left')\" class=\"w-4 h-4\"></svg>\n </button>\n <span class=\"text-sm _shk-text-surface-600 dark:[color:var(--shk-surface-600)]\">\n {{ currentPage() }} de {{ totalPages() }}\n </span>\n <button\n class=\"bg-transparent border-0 cursor-pointer px-2 py-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-50 disabled:cursor-not-allowed _shk-text-surface-600 dark:[color:var(--shk-surface-600)]\"\n [disabled]=\"currentPage() === totalPages()\"\n (click)=\"$event.stopPropagation(); nextPage()\"\n >\n <svg [lucideIcon]=\"getIcon('chevron-right')\" class=\"w-4 h-4\"></svg>\n </button>\n </div>\n }\n </div>\n }\n\n @if (shouldShowError()) {\n <div class=\"mt-1 text-xs text-red-500 max-h-20 overflow-y-auto\" tabindex=\"-1\">\n <ul class=\"list-disc pl-4 space-y-1\">\n @for (error of getErrorMessages(); track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </div>\n }\n</div>", styles: [".select-option-active{background-color:var(--shk-primary-50);outline:2px solid var(--shk-primary-500);outline-offset:-2px;color:var(--shk-primary-700)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TranslocoModule }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }, { kind: "pipe", type: i1$1.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1930
1937
|
}
|
|
1931
1938
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: SelectComponent, decorators: [{
|
|
1932
1939
|
type: Component,
|
|
@@ -1954,38 +1961,40 @@ const icons$1 = {
|
|
|
1954
1961
|
x: LucideX,
|
|
1955
1962
|
};
|
|
1956
1963
|
class FileUploadComponent {
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1964
|
+
constructor() {
|
|
1965
|
+
this.getIcon = (name) => icons$1[name] ?? LucideUpload;
|
|
1966
|
+
this.transloco = inject(TranslocoService);
|
|
1967
|
+
this.label = input('Cargar archivo', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1968
|
+
this.accept = input('image/*', ...(ngDevMode ? [{ debugName: "accept" }] : /* istanbul ignore next */ []));
|
|
1969
|
+
this.maxFileSize = input(2 * 1024 * 1024, ...(ngDevMode ? [{ debugName: "maxFileSize" }] : /* istanbul ignore next */ []));
|
|
1970
|
+
this.maxFiles = input(0, ...(ngDevMode ? [{ debugName: "maxFiles" }] : /* istanbul ignore next */ []));
|
|
1971
|
+
this.fileUploadText = input('Seleccionar archivo', ...(ngDevMode ? [{ debugName: "fileUploadText" }] : /* istanbul ignore next */ []));
|
|
1972
|
+
this.fileRecommendation = input('', ...(ngDevMode ? [{ debugName: "fileRecommendation" }] : /* istanbul ignore next */ []));
|
|
1973
|
+
this.changeFilesText = input('Cambiar archivos', ...(ngDevMode ? [{ debugName: "changeFilesText" }] : /* istanbul ignore next */ []));
|
|
1974
|
+
this.multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
1975
|
+
this.fileSelected = output();
|
|
1976
|
+
this.fileRemoved = output();
|
|
1977
|
+
this.fileError = output();
|
|
1978
|
+
this.fileWarning = output();
|
|
1979
|
+
this.selectedFiles = signal([], ...(ngDevMode ? [{ debugName: "selectedFiles" }] : /* istanbul ignore next */ []));
|
|
1980
|
+
this.errorMessage = signal('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
|
|
1981
|
+
this.isDragOver = signal(false, ...(ngDevMode ? [{ debugName: "isDragOver" }] : /* istanbul ignore next */ []));
|
|
1982
|
+
this.previewUrls = new Map();
|
|
1983
|
+
this.canAddMore = computed(() => {
|
|
1984
|
+
if (!this.multiple())
|
|
1985
|
+
return this.selectedFiles().length === 0;
|
|
1986
|
+
const max = this.maxFiles();
|
|
1987
|
+
if (max <= 0)
|
|
1988
|
+
return true;
|
|
1989
|
+
return this.selectedFiles().length < max;
|
|
1990
|
+
}, ...(ngDevMode ? [{ debugName: "canAddMore" }] : /* istanbul ignore next */ []));
|
|
1991
|
+
this.maxReached = computed(() => {
|
|
1992
|
+
const max = this.maxFiles();
|
|
1993
|
+
if (max <= 0)
|
|
1994
|
+
return false;
|
|
1995
|
+
return this.selectedFiles().length >= max;
|
|
1996
|
+
}, ...(ngDevMode ? [{ debugName: "maxReached" }] : /* istanbul ignore next */ []));
|
|
1997
|
+
}
|
|
1989
1998
|
isImageFile(file) {
|
|
1990
1999
|
return file.type.startsWith('image/');
|
|
1991
2000
|
}
|
|
@@ -2132,8 +2141,8 @@ class FileUploadComponent {
|
|
|
2132
2141
|
return (bytes / 1024).toFixed(1) + ' KB';
|
|
2133
2142
|
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
|
2134
2143
|
}
|
|
2135
|
-
static
|
|
2136
|
-
static
|
|
2144
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FileUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2145
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: FileUploadComponent, isStandalone: true, selector: "shk-file-upload", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, maxFiles: { classPropertyName: "maxFiles", publicName: "maxFiles", isSignal: true, isRequired: false, transformFunction: null }, fileUploadText: { classPropertyName: "fileUploadText", publicName: "fileUploadText", isSignal: true, isRequired: false, transformFunction: null }, fileRecommendation: { classPropertyName: "fileRecommendation", publicName: "fileRecommendation", isSignal: true, isRequired: false, transformFunction: null }, changeFilesText: { classPropertyName: "changeFilesText", publicName: "changeFilesText", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileSelected: "fileSelected", fileRemoved: "fileRemoved", fileError: "fileError", fileWarning: "fileWarning" }, ngImport: i0, template: "<div class=\"flex flex-col gap-2\">\n @if (label()) {\n <label class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-300)]\">\n {{ label() }}\n </label>\n }\n\n @if (canAddMore()) {\n <div\n class=\"relative border-2 border-dashed _shk-border dark:[border-color:var(--shk-surface-700)] rounded-lg p-4 transition-colors hover:[border-color:var(--shk-primary-400)] dark:hover:[border-color:var(--shk-primary-500)]\"\n [class.border-red-400]=\"errorMessage()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n >\n <input\n #fileInput\n type=\"file\"\n [accept]=\"accept()\"\n [multiple]=\"multiple()\"\n (change)=\"onFileChange($event)\"\n class=\"hidden\"\n />\n\n <div\n class=\"flex flex-col items-center gap-2 cursor-pointer\"\n (click)=\"fileInput.click()\"\n [class.drag-over]=\"isDragOver()\"\n >\n <svg [lucideIcon]=\"getIcon('upload')\" class=\"w-8 h-8 _shk-icon-subtle dark:[color:var(--shk-surface-600)]\"></svg>\n <span class=\"text-sm _shk-text-surface-700 dark:[color:var(--shk-surface-300)]\">\n {{ fileUploadText() }}\n </span>\n @if (fileRecommendation()) {\n <span class=\"text-xs _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\">\n {{ fileRecommendation() }}\n </span>\n }\n </div>\n </div>\n }\n\n @if (maxReached()) {\n <div class=\"text-xs _shk-text-surface-400 dark:[color:var(--shk-surface-500)] text-center py-2\">\n M\u00E1ximo {{ maxFiles() }} archivos alcanzado\n </div>\n }\n\n @if (selectedFiles().length > 0) {\n <div class=\"flex flex-wrap gap-3\">\n @for (file of selectedFiles(); track file.name + file.size + file.lastModified) {\n <div class=\"relative group\">\n @if (isImageFile(file)) {\n <img\n [src]=\"previewUrl(file)\"\n [alt]=\"file.name\"\n class=\"w-20 h-20 object-cover rounded-lg _shk-border dark:[border-color:var(--shk-surface-700)]\"\n />\n } @else {\n <div class=\"w-20 h-20 rounded-lg _shk-border dark:[border-color:var(--shk-surface-700)] flex flex-col items-center justify-center _shk-bg-surface-50 dark:[background-color:var(--shk-surface-800)] gap-1\">\n <svg [lucideIcon]=\"getIcon('file')\" class=\"w-6 h-6 _shk-text-surface-400\"></svg>\n <span class=\"text-[10px] _shk-text-surface-400 truncate max-w-[70px] px-1 text-center\">{{ file.name }}</span>\n </div>\n }\n <button\n type=\"button\"\n (click)=\"removeFile(file)\"\n class=\"absolute -top-1.5 -right-1.5 w-5 h-5 bg-red-500 text-white rounded-full text-xs flex items-center justify-center opacity-0 group-hover:opacity-100 transition shadow\"\n >\n <svg [lucideIcon]=\"getIcon('x')\" class=\"w-3 h-3\"></svg>\n </button>\n </div>\n }\n </div>\n @if (!multiple()) {\n <button\n type=\"button\"\n (click)=\"changeFiles()\"\n class=\"text-xs _shk-text-primary hover:[color:var(--shk-primary-700)] dark:[color:var(--shk-primary-400)] dark:hover:[color:var(--shk-primary-300)] underline cursor-pointer bg-transparent border-0\"\n >\n {{ changeFilesText() }}\n </button>\n }\n }\n\n @if (errorMessage()) {\n <p class=\"text-xs _shk-text-red-500\">{{ errorMessage() }}</p>\n }\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2137
2146
|
}
|
|
2138
2147
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FileUploadComponent, decorators: [{
|
|
2139
2148
|
type: Component,
|
|
@@ -2221,93 +2230,92 @@ function getIcon(name) {
|
|
|
2221
2230
|
return icons[name] ?? LucidePlus;
|
|
2222
2231
|
}
|
|
2223
2232
|
class TableComponent {
|
|
2224
|
-
fb = inject(FormBuilder);
|
|
2225
|
-
cdr = inject(ChangeDetectorRef);
|
|
2226
|
-
transloco = inject(TranslocoService);
|
|
2227
|
-
getIcon = getIcon;
|
|
2228
|
-
actionsHeaderLabel = toSignal(this.transloco.selectTranslate('common.actions'), { initialValue: 'Acciones' });
|
|
2229
|
-
data = input([], ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
2230
|
-
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
2231
|
-
rowsPerPage = input(10, ...(ngDevMode ? [{ debugName: "rowsPerPage" }] : /* istanbul ignore next */ []));
|
|
2232
|
-
rowsPerPageOptions = input([10, 25, 50], ...(ngDevMode ? [{ debugName: "rowsPerPageOptions" }] : /* istanbul ignore next */ []));
|
|
2233
|
-
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
2234
|
-
showActionRow = input(true, ...(ngDevMode ? [{ debugName: "showActionRow" }] : /* istanbul ignore next */ []));
|
|
2235
|
-
customTemplates = input({}, ...(ngDevMode ? [{ debugName: "customTemplates" }] : /* istanbul ignore next */ []));
|
|
2236
|
-
headerActions = input([], ...(ngDevMode ? [{ debugName: "headerActions" }] : /* istanbul ignore next */ []));
|
|
2237
|
-
rowActions = input([], ...(ngDevMode ? [{ debugName: "rowActions" }] : /* istanbul ignore next */ []));
|
|
2238
|
-
hasShadow = input(true, ...(ngDevMode ? [{ debugName: "hasShadow" }] : /* istanbul ignore next */ []));
|
|
2239
|
-
defaultSortField = input('', ...(ngDevMode ? [{ debugName: "defaultSortField" }] : /* istanbul ignore next */ []));
|
|
2240
|
-
defaultSortOrder = input(1, ...(ngDevMode ? [{ debugName: "defaultSortOrder" }] : /* istanbul ignore next */ []));
|
|
2241
|
-
showSearch = input(true, ...(ngDevMode ? [{ debugName: "showSearch" }] : /* istanbul ignore next */ []));
|
|
2242
|
-
searchPlaceholder = input('', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : /* istanbul ignore next */ []));
|
|
2243
|
-
emptyMessage = input('', ...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []));
|
|
2244
|
-
serverSide = input(false, ...(ngDevMode ? [{ debugName: "serverSide" }] : /* istanbul ignore next */ []));
|
|
2245
|
-
totalRecords = input(0, ...(ngDevMode ? [{ debugName: "totalRecords" }] : /* istanbul ignore next */ []));
|
|
2246
|
-
filters = input([], ...(ngDevMode ? [{ debugName: "filters" }] : /* istanbul ignore next */ []));
|
|
2247
|
-
activeFilter = input('', ...(ngDevMode ? [{ debugName: "activeFilter" }] : /* istanbul ignore next */ []));
|
|
2248
|
-
refresh = output();
|
|
2249
|
-
pageChange = output();
|
|
2250
|
-
filterChange = output();
|
|
2251
|
-
searchChange = output();
|
|
2252
|
-
filterClick = output();
|
|
2253
|
-
originalData = signal([], ...(ngDevMode ? [{ debugName: "originalData" }] : /* istanbul ignore next */ []));
|
|
2254
|
-
searchedData = signal([], ...(ngDevMode ? [{ debugName: "searchedData" }] : /* istanbul ignore next */ []));
|
|
2255
|
-
filteredData = signal([], ...(ngDevMode ? [{ debugName: "filteredData" }] : /* istanbul ignore next */ []));
|
|
2256
|
-
displayedData = signal([], ...(ngDevMode ? [{ debugName: "displayedData" }] : /* istanbul ignore next */ []));
|
|
2257
|
-
localTotalRecords = signal(0, ...(ngDevMode ? [{ debugName: "localTotalRecords" }] : /* istanbul ignore next */ []));
|
|
2258
|
-
first = signal(0, ...(ngDevMode ? [{ debugName: "first" }] : /* istanbul ignore next */ []));
|
|
2259
|
-
showFilterInput = signal({}, ...(ngDevMode ? [{ debugName: "showFilterInput" }] : /* istanbul ignore next */ []));
|
|
2260
|
-
searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : /* istanbul ignore next */ []));
|
|
2261
|
-
sortField = signal('', ...(ngDevMode ? [{ debugName: "sortField" }] : /* istanbul ignore next */ []));
|
|
2262
|
-
sortOrder = signal(1, ...(ngDevMode ? [{ debugName: "sortOrder" }] : /* istanbul ignore next */ []));
|
|
2263
|
-
rowsPerPageLocal = signal(10, ...(ngDevMode ? [{ debugName: "rowsPerPageLocal" }] : /* istanbul ignore next */ []));
|
|
2264
|
-
totalPages = computed(() => Math.max(1, Math.ceil(this.effectiveTotalRecords() / this.rowsPerPageLocal())), ...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
|
|
2265
|
-
currentPage = computed(() => Math.floor(this.first() / this.rowsPerPageLocal()) + 1, ...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
|
|
2266
|
-
columnFiltersForm;
|
|
2267
|
-
filterSubject = new Subject();
|
|
2268
|
-
columnsWithActions = computed(() => {
|
|
2269
|
-
const columnsArray = this.columns();
|
|
2270
|
-
const showAction = this.showActionRow();
|
|
2271
|
-
const rowActionsArray = this.rowActions();
|
|
2272
|
-
const translatedHeader = this.actionsHeaderLabel();
|
|
2273
|
-
if (showAction && rowActionsArray.length > 0) {
|
|
2274
|
-
const actionsWidth = rowActionsArray.length <= 2
|
|
2275
|
-
? '110px'
|
|
2276
|
-
: rowActionsArray.length <= 3
|
|
2277
|
-
? '130px'
|
|
2278
|
-
: '170px';
|
|
2279
|
-
return [
|
|
2280
|
-
{
|
|
2281
|
-
field: 'actions',
|
|
2282
|
-
header: translatedHeader || 'Acciones',
|
|
2283
|
-
width: actionsWidth,
|
|
2284
|
-
defaultSort: true,
|
|
2285
|
-
},
|
|
2286
|
-
...columnsArray,
|
|
2287
|
-
];
|
|
2288
|
-
}
|
|
2289
|
-
return [...columnsArray];
|
|
2290
|
-
}, ...(ngDevMode ? [{ debugName: "columnsWithActions" }] : /* istanbul ignore next */ []));
|
|
2291
|
-
effectiveTotalRecords = computed(() => {
|
|
2292
|
-
return this.serverSide() ? this.totalRecords() : this.localTotalRecords();
|
|
2293
|
-
}, ...(ngDevMode ? [{ debugName: "effectiveTotalRecords" }] : /* istanbul ignore next */ []));
|
|
2294
|
-
effectiveDisplayedData = computed(() => {
|
|
2295
|
-
return this.serverSide() ? this.data() : this.displayedData();
|
|
2296
|
-
}, ...(ngDevMode ? [{ debugName: "effectiveDisplayedData" }] : /* istanbul ignore next */ []));
|
|
2297
|
-
activeFilters = computed(() => {
|
|
2298
|
-
const form = this.columnFiltersForm;
|
|
2299
|
-
if (!form)
|
|
2300
|
-
return {};
|
|
2301
|
-
const active = {};
|
|
2302
|
-
Object.keys(form.controls).forEach((field) => {
|
|
2303
|
-
const value = form.get(field)?.value;
|
|
2304
|
-
if (value !== null && value !== undefined && value !== '') {
|
|
2305
|
-
active[field] = value;
|
|
2306
|
-
}
|
|
2307
|
-
});
|
|
2308
|
-
return active;
|
|
2309
|
-
}, ...(ngDevMode ? [{ debugName: "activeFilters" }] : /* istanbul ignore next */ []));
|
|
2310
2233
|
constructor() {
|
|
2234
|
+
this.fb = inject(FormBuilder);
|
|
2235
|
+
this.cdr = inject(ChangeDetectorRef);
|
|
2236
|
+
this.transloco = inject(TranslocoService);
|
|
2237
|
+
this.getIcon = getIcon;
|
|
2238
|
+
this.actionsHeaderLabel = toSignal(this.transloco.selectTranslate('common.actions'), { initialValue: 'Acciones' });
|
|
2239
|
+
this.data = input([], ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
2240
|
+
this.columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
2241
|
+
this.rowsPerPage = input(10, ...(ngDevMode ? [{ debugName: "rowsPerPage" }] : /* istanbul ignore next */ []));
|
|
2242
|
+
this.rowsPerPageOptions = input([10, 25, 50], ...(ngDevMode ? [{ debugName: "rowsPerPageOptions" }] : /* istanbul ignore next */ []));
|
|
2243
|
+
this.loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
2244
|
+
this.showActionRow = input(true, ...(ngDevMode ? [{ debugName: "showActionRow" }] : /* istanbul ignore next */ []));
|
|
2245
|
+
this.customTemplates = input({}, ...(ngDevMode ? [{ debugName: "customTemplates" }] : /* istanbul ignore next */ []));
|
|
2246
|
+
this.headerActions = input([], ...(ngDevMode ? [{ debugName: "headerActions" }] : /* istanbul ignore next */ []));
|
|
2247
|
+
this.rowActions = input([], ...(ngDevMode ? [{ debugName: "rowActions" }] : /* istanbul ignore next */ []));
|
|
2248
|
+
this.hasShadow = input(true, ...(ngDevMode ? [{ debugName: "hasShadow" }] : /* istanbul ignore next */ []));
|
|
2249
|
+
this.defaultSortField = input('', ...(ngDevMode ? [{ debugName: "defaultSortField" }] : /* istanbul ignore next */ []));
|
|
2250
|
+
this.defaultSortOrder = input(1, ...(ngDevMode ? [{ debugName: "defaultSortOrder" }] : /* istanbul ignore next */ []));
|
|
2251
|
+
this.showSearch = input(true, ...(ngDevMode ? [{ debugName: "showSearch" }] : /* istanbul ignore next */ []));
|
|
2252
|
+
this.searchPlaceholder = input('', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : /* istanbul ignore next */ []));
|
|
2253
|
+
this.emptyMessage = input('', ...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []));
|
|
2254
|
+
this.serverSide = input(false, ...(ngDevMode ? [{ debugName: "serverSide" }] : /* istanbul ignore next */ []));
|
|
2255
|
+
this.totalRecords = input(0, ...(ngDevMode ? [{ debugName: "totalRecords" }] : /* istanbul ignore next */ []));
|
|
2256
|
+
this.filters = input([], ...(ngDevMode ? [{ debugName: "filters" }] : /* istanbul ignore next */ []));
|
|
2257
|
+
this.activeFilter = input('', ...(ngDevMode ? [{ debugName: "activeFilter" }] : /* istanbul ignore next */ []));
|
|
2258
|
+
this.refresh = output();
|
|
2259
|
+
this.pageChange = output();
|
|
2260
|
+
this.filterChange = output();
|
|
2261
|
+
this.searchChange = output();
|
|
2262
|
+
this.filterClick = output();
|
|
2263
|
+
this.originalData = signal([], ...(ngDevMode ? [{ debugName: "originalData" }] : /* istanbul ignore next */ []));
|
|
2264
|
+
this.searchedData = signal([], ...(ngDevMode ? [{ debugName: "searchedData" }] : /* istanbul ignore next */ []));
|
|
2265
|
+
this.filteredData = signal([], ...(ngDevMode ? [{ debugName: "filteredData" }] : /* istanbul ignore next */ []));
|
|
2266
|
+
this.displayedData = signal([], ...(ngDevMode ? [{ debugName: "displayedData" }] : /* istanbul ignore next */ []));
|
|
2267
|
+
this.localTotalRecords = signal(0, ...(ngDevMode ? [{ debugName: "localTotalRecords" }] : /* istanbul ignore next */ []));
|
|
2268
|
+
this.first = signal(0, ...(ngDevMode ? [{ debugName: "first" }] : /* istanbul ignore next */ []));
|
|
2269
|
+
this.showFilterInput = signal({}, ...(ngDevMode ? [{ debugName: "showFilterInput" }] : /* istanbul ignore next */ []));
|
|
2270
|
+
this.searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : /* istanbul ignore next */ []));
|
|
2271
|
+
this.sortField = signal('', ...(ngDevMode ? [{ debugName: "sortField" }] : /* istanbul ignore next */ []));
|
|
2272
|
+
this.sortOrder = signal(1, ...(ngDevMode ? [{ debugName: "sortOrder" }] : /* istanbul ignore next */ []));
|
|
2273
|
+
this.rowsPerPageLocal = signal(10, ...(ngDevMode ? [{ debugName: "rowsPerPageLocal" }] : /* istanbul ignore next */ []));
|
|
2274
|
+
this.totalPages = computed(() => Math.max(1, Math.ceil(this.effectiveTotalRecords() / this.rowsPerPageLocal())), ...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
|
|
2275
|
+
this.currentPage = computed(() => Math.floor(this.first() / this.rowsPerPageLocal()) + 1, ...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
|
|
2276
|
+
this.filterSubject = new Subject();
|
|
2277
|
+
this.columnsWithActions = computed(() => {
|
|
2278
|
+
const columnsArray = this.columns();
|
|
2279
|
+
const showAction = this.showActionRow();
|
|
2280
|
+
const rowActionsArray = this.rowActions();
|
|
2281
|
+
const translatedHeader = this.actionsHeaderLabel();
|
|
2282
|
+
if (showAction && rowActionsArray.length > 0) {
|
|
2283
|
+
const actionsWidth = rowActionsArray.length <= 2
|
|
2284
|
+
? '110px'
|
|
2285
|
+
: rowActionsArray.length <= 3
|
|
2286
|
+
? '130px'
|
|
2287
|
+
: '170px';
|
|
2288
|
+
return [
|
|
2289
|
+
{
|
|
2290
|
+
field: 'actions',
|
|
2291
|
+
header: translatedHeader || 'Acciones',
|
|
2292
|
+
width: actionsWidth,
|
|
2293
|
+
defaultSort: true,
|
|
2294
|
+
},
|
|
2295
|
+
...columnsArray,
|
|
2296
|
+
];
|
|
2297
|
+
}
|
|
2298
|
+
return [...columnsArray];
|
|
2299
|
+
}, ...(ngDevMode ? [{ debugName: "columnsWithActions" }] : /* istanbul ignore next */ []));
|
|
2300
|
+
this.effectiveTotalRecords = computed(() => {
|
|
2301
|
+
return this.serverSide() ? this.totalRecords() : this.localTotalRecords();
|
|
2302
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveTotalRecords" }] : /* istanbul ignore next */ []));
|
|
2303
|
+
this.effectiveDisplayedData = computed(() => {
|
|
2304
|
+
return this.serverSide() ? this.data() : this.displayedData();
|
|
2305
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveDisplayedData" }] : /* istanbul ignore next */ []));
|
|
2306
|
+
this.activeFilters = computed(() => {
|
|
2307
|
+
const form = this.columnFiltersForm;
|
|
2308
|
+
if (!form)
|
|
2309
|
+
return {};
|
|
2310
|
+
const active = {};
|
|
2311
|
+
Object.keys(form.controls).forEach((field) => {
|
|
2312
|
+
const value = form.get(field)?.value;
|
|
2313
|
+
if (value !== null && value !== undefined && value !== '') {
|
|
2314
|
+
active[field] = value;
|
|
2315
|
+
}
|
|
2316
|
+
});
|
|
2317
|
+
return active;
|
|
2318
|
+
}, ...(ngDevMode ? [{ debugName: "activeFilters" }] : /* istanbul ignore next */ []));
|
|
2311
2319
|
this.columnFiltersForm = this.fb.group({});
|
|
2312
2320
|
this.filterSubject.pipe(debounceTime(300)).subscribe(() => {
|
|
2313
2321
|
if (this.serverSide()) {
|
|
@@ -2680,8 +2688,8 @@ class TableComponent {
|
|
|
2680
2688
|
return '_shk-bg-surface-100 _shk-text-surface-700 dark:[background-color:var(--shk-surface-700)] dark:[color:var(--shk-surface-300)]';
|
|
2681
2689
|
}
|
|
2682
2690
|
}
|
|
2683
|
-
static
|
|
2684
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: TableComponent, isStandalone: true, selector: "shk-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, rowsPerPage: { classPropertyName: "rowsPerPage", publicName: "rowsPerPage", isSignal: true, isRequired: false, transformFunction: null }, rowsPerPageOptions: { classPropertyName: "rowsPerPageOptions", publicName: "rowsPerPageOptions", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, showActionRow: { classPropertyName: "showActionRow", publicName: "showActionRow", isSignal: true, isRequired: false, transformFunction: null }, customTemplates: { classPropertyName: "customTemplates", publicName: "customTemplates", isSignal: true, isRequired: false, transformFunction: null }, headerActions: { classPropertyName: "headerActions", publicName: "headerActions", isSignal: true, isRequired: false, transformFunction: null }, rowActions: { classPropertyName: "rowActions", publicName: "rowActions", isSignal: true, isRequired: false, transformFunction: null }, hasShadow: { classPropertyName: "hasShadow", publicName: "hasShadow", isSignal: true, isRequired: false, transformFunction: null }, defaultSortField: { classPropertyName: "defaultSortField", publicName: "defaultSortField", isSignal: true, isRequired: false, transformFunction: null }, defaultSortOrder: { classPropertyName: "defaultSortOrder", publicName: "defaultSortOrder", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, serverSide: { classPropertyName: "serverSide", publicName: "serverSide", isSignal: true, isRequired: false, transformFunction: null }, totalRecords: { classPropertyName: "totalRecords", publicName: "totalRecords", isSignal: true, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, activeFilter: { classPropertyName: "activeFilter", publicName: "activeFilter", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { refresh: "refresh", pageChange: "pageChange", filterChange: "filterChange", searchChange: "searchChange", filterClick: "filterClick" }, ngImport: i0, template: "<div class=\"space-y-2 min-[1440px]:space-y-3 mt-2 min-[1440px]:mt-3 animate-fade-in pb-8\">\n\n @if (showSearch() || filters().length > 0 || headerActions().length > 0) {\n <div class=\"card p-2 min-[1440px]:p-2.5 flex flex-row items-center justify-between gap-2\">\n\n <div class=\"flex items-center gap-2 min-[1440px]:gap-3 flex-1 min-w-0\">\n @if (showSearch()) {\n <div class=\"relative w-full md:w-52 min-[1440px]:w-56\">\n <div class=\"absolute inset-y-0 left-0 pl-2.5 flex items-center pointer-events-none\">\n <svg [lucideIcon]=\"getIcon('search')\" class=\"w-3.5 h-3.5 _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\"></svg>\n </div>\n <input\n type=\"text\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($any($event.target).value)\"\n [placeholder]=\"searchPlaceholder() || ('common.search_placeholder' | transloco)\"\n class=\"block w-full pl-8 pr-3 py-1.5 text-xs border _shk-border dark:[border-color:var(--shk-surface-200)] rounded-md leading-5\n _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] placeholder:[color:var(--shk-surface-400)] dark:placeholder:[color:var(--shk-surface-500)]\n _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\n focus:outline-none focus:bg-white dark:focus:[background-color:var(--shk-surface-800)] focus:[border-color:var(--shk-primary-500)] focus:ring-1\n focus:[--tw-ring-color:var(--shk-primary-500)]\"\n />\n </div>\n }\n\n @if (filters().length > 0) {\n <div class=\"flex _shk-bg-surface-100 dark:[background-color:var(--shk-surface-100)] p-0.5 rounded-md ml-auto\">\n @for (f of filters(); track f.value) {\n <button\n type=\"button\"\n (click)=\"onFilterClick(f.value)\"\n class=\"px-2.5 min-[1440px]:px-3 py-1 text-xs font-medium rounded _shk-text-surface-700 dark:[color:var(--shk-surface-700)] transition-all\"\n [class]=\"f.value === activeFilter() ? 'bg-white shadow-sm dark:[background-color:var(--shk-surface-700)]' : ''\"\n >\n {{ f.label }}\n </button>\n }\n </div>\n }\n </div>\n\n @if (headerActions().length > 0) {\n <div class=\"flex items-center gap-1.5 shrink-0\">\n @for (action of headerActions(); track $index) {\n @if (isHeaderActionVisible(action)) {\n <button\n type=\"button\"\n [class]=\"action.class || 'inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md _shk-bg-primary text-white hover:[background-color:var(--shk-primary-700)] transition-colors disabled:opacity-50 disabled:cursor-not-allowed'\"\n [disabled]=\"isHeaderActionDisabled(action)\"\n (click)=\"action.onClick()\"\n >\n @if (action.icon) {\n <svg\n [lucideIcon]=\"getIcon(action.icon)\"\n class=\"w-3.5 h-3.5\"\n ></svg>\n }\n {{ action.label }}\n </button>\n }\n }\n </div>\n }\n\n </div>\n }\n\n <div\n class=\"card p-0 overflow-hidden\"\n [class.shadow-lg]=\"hasShadow()\"\n >\n\n <div class=\"table-scroll-wrapper _shk-scrollbar\">\n <table class=\"w-full\">\n <thead>\n <tr>\n @for (col of columnsWithActions(); track col.field) {\n <th\n (click)=\"col.field !== 'actions' && col.sortable && toggleSort(col.field)\"\n [style.cursor]=\"col.field !== 'actions' && col.sortable ? 'pointer' : 'default'\"\n [style.width]=\"col.width || 'auto'\"\n [style.min-width]=\"col.field === 'actions' ? '130px' : 'auto'\"\n class=\"px-2 min-[1440px]:px-3 py-2 min-[1440px]:py-2.5 text-left text-[10px] min-[1440px]:text-xs font-bold _shk-text-surface-500 dark:[color:var(--shk-surface-400)] uppercase tracking-wider\n _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border-b _shk-border dark:[border-color:var(--shk-surface-200)]\"\n >\n @if (col.field !== 'actions') {\n <div class=\"flex items-center justify-between gap-2\">\n <span>{{ col.header }}</span>\n <div class=\"flex items-center gap-1\">\n @if (col.sortable) {\n <div class=\"relative group\">\n @if (sortField() === col.field) {\n <svg [lucideIcon]=\"getIcon(sortOrder() === 1 ? 'arrow-up' : 'arrow-down')\"\n class=\"w-3.5 h-3.5 _shk-text-primary\"></svg>\n } @else {\n <svg [lucideIcon]=\"getIcon('arrow-up-down')\"\n class=\"w-3.5 h-3.5 _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\"></svg>\n }\n <span class=\"absolute top-full left-1/2 -translate-x-1/2 mt-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ 'table.tooltips.sort' | transloco }}\n </span>\n </div>\n }\n @if (col.filter) {\n <div class=\"relative group\">\n <button\n type=\"button\"\n (click)=\"$event.stopPropagation(); toggleFilter(col.field)\"\n class=\"_shk-text-surface-400 dark:[color:var(--shk-surface-500)] hover:[color:var(--shk-surface-600)] dark:hover:[color:var(--shk-surface-300)] transition-colors\"\n >\n <svg\n [lucideIcon]=\"getIcon('filter')\"\n class=\"w-3.5 h-3.5\"\n [class._shk-text-primary]=\"columnFiltersForm.get(col.field)?.value\"\n ></svg>\n <span class=\"absolute top-full left-1/2 -translate-x-1/2 mt-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ 'table.tooltips.filter' | transloco }}\n </span>\n </button>\n </div>\n }\n </div>\n </div>\n\n @if (col.filter && showFilterInput()[col.field]) {\n <div\n class=\"mt-2\"\n [formGroup]=\"columnFiltersForm\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"relative\">\n @if (col.filterType !== 'select') {\n <input\n type=\"text\"\n [formControlName]=\"col.field\"\n class=\"w-full px-3 py-1.5 text-sm rounded-md border _shk-border dark:[border-color:var(--shk-surface-200)] bg-white dark:[background-color:var(--shk-surface-100)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\n focus:[border-color:var(--shk-primary-500)] focus:ring-1 focus:[--tw-ring-color:var(--shk-primary-500)]\n placeholder:[color:var(--shk-surface-400)] dark:placeholder:[color:var(--shk-surface-500)]\"\n [placeholder]=\"col.filterPlaceholder || ('common.search_placeholder' | transloco)\"\n />\n }\n @if (col.filterType === 'select') {\n <select\n [formControlName]=\"col.field\"\n class=\"w-full px-2 py-1 text-xs rounded-md border _shk-border dark:[border-color:var(--shk-surface-200)] bg-white dark:[background-color:var(--shk-surface-100)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)] focus:[border-color:var(--shk-primary-500)] focus:ring-1 focus:[--tw-ring-color:var(--shk-primary-500)] appearance-none\"\n >\n <option [ngValue]=\"null\">A/D</option>\n @for (opt of col.filterOptions || []; track opt.value) {\n <option [ngValue]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @if (columnFiltersForm.get(col.field)?.value && col.filterType !== 'select') {\n <button\n type=\"button\"\n class=\"absolute right-2 top-1/2 -translate-y-1/2 _shk-text-surface-400 dark:[color:var(--shk-surface-500)] hover:[color:var(--shk-surface-600)] dark:hover:[color:var(--shk-surface-300)]\"\n (click)=\"clearFilter(col.field)\"\n >\n <svg [lucideIcon]=\"getIcon('x')\" class=\"w-3.5 h-3.5\"></svg>\n </button>\n }\n </div>\n </div>\n }\n } @else {\n <div class=\"flex items-center justify-center\">\n <span>{{ col.header }}</span>\n </div>\n }\n </th>\n }\n </tr>\n </thead>\n\n @if (loading()) {\n <tbody class=\"border-b _shk-border dark:[border-color:var(--shk-surface-100)]\">\n <tr>\n <td [attr.colspan]=\"columnsWithActions().length\" class=\"text-center py-12\">\n <div class=\"flex items-center justify-center\">\n <svg [lucideIcon]=\"getIcon('loader')\" class=\"w-6 h-6 animate-spin _shk-text-primary\"></svg>\n </div>\n </td>\n </tr>\n </tbody>\n } @else if (effectiveDisplayedData().length === 0) {\n <tbody class=\"border-b _shk-border dark:[border-color:var(--shk-surface-100)]\">\n <tr>\n <td [attr.colspan]=\"columnsWithActions().length\" class=\"text-center py-12\">\n <div class=\"flex flex-col items-center\">\n <div class=\"w-16 h-16 _shk-bg-surface-100 dark:[background-color:var(--shk-surface-100)] rounded-full flex items-center justify-center mb-4\">\n <svg [lucideIcon]=\"getIcon('inbox')\" class=\"w-8 h-8 _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\"></svg>\n </div>\n <p class=\"text-lg font-semibold _shk-text-surface-600 dark:[color:var(--shk-surface-300)]\">\n {{ emptyMessage() || ('common.no_records' | transloco) }}\n </p>\n </div>\n </td>\n </tr>\n </tbody>\n } @else {\n <tbody>\n @for (rowData of effectiveDisplayedData(); track $index) {\n <tr class=\"hover:[background-color:color-mix(in srgb,var(--shk-primary-50)30%,transparent)] dark:hover:[background-color:color-mix(in srgb,var(--shk-primary-900)10%,transparent)] transition-colors duration-200 border-b _shk-border dark:[border-color:var(--shk-surface-100)]\">\n @for (col of columnsWithActions(); track col.field) {\n <td\n class=\"px-2 min-[1440px]:px-3 py-2 min-[1440px]:py-2.5 text-xs font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-700)] whitespace-nowrap\"\n [style.overflow]=\"col.field === 'actions' ? 'visible' : 'hidden'\"\n [style.text-overflow]=\"col.field === 'actions' ? 'clip' : 'ellipsis'\"\n >\n @if (col.field !== 'actions') {\n @if (col.template === 'tag') {\n <span\n class=\"inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium\"\n [class]=\"getTagClass(col.tagSeverity ? col.tagSeverity(rowData) : undefined)\"\n [style]=\"col.tagStyle ? col.tagStyle(rowData) : undefined\"\n >\n {{ col.tagValue ? col.tagValue(rowData) : rowData[col.field] }}\n </span>\n } @else if (col.format) {\n <span>{{ col.format(rowData) }}</span>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"\n customTemplates()[col.field] || defaultTemplate;\n context: { $implicit: rowData, field: col.field }\n \"\n ></ng-container>\n }\n } @else {\n <div class=\"flex items-center justify-start gap-px\">\n @for (action of rowActions(); track $index) {\n @if (isRowActionVisible(action, rowData)) {\n <div class=\"relative group\">\n <button\n type=\"button\"\n (click)=\"action.onClick(rowData)\"\n [class]=\"'table-action-btn hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] rounded-md ' + getRowActionClass(action, rowData)\"\n [disabled]=\"isRowActionDisabled(action, rowData) || false\"\n >\n <svg\n [lucideIcon]=\"getIcon(getRowActionIconName(action, rowData))\"\n class=\"w-4 h-4\"\n ></svg>\n </button>\n <span class=\"absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ getRowActionLabel(action, rowData) }}\n </span>\n </div>\n }\n }\n </div>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n }\n </table>\n\n <ng-template #defaultTemplate let-rowData let-field=\"field\">\n {{ truncate(rowData[field], 30) }}\n </ng-template>\n </div>\n\n <div class=\"flex items-center justify-between gap-4 px-2 min-[1440px]:px-3 py-2 border-t _shk-border dark:[border-color:var(--shk-surface-100)]\">\n <div class=\"text-xs _shk-text-surface-600 dark:[color:var(--shk-surface-400)]\">{{ getPageReport() }}</div>\n <div class=\"flex items-center gap-0.5\">\n <button\n type=\"button\"\n (click)=\"goToFirst()\"\n [disabled]=\"isFirstPage()\"\n class=\"p-1 _shk-text-surface-500 hover:[color:var(--shk-surface-700)] dark:[color:var(--shk-surface-400)] dark:hover:[color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed rounded transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('chevrons-left')\" class=\"w-4 h-4\"></svg>\n </button>\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"isFirstPage()\"\n class=\"p-1 _shk-text-surface-500 hover:[color:var(--shk-surface-700)] dark:[color:var(--shk-surface-400)] dark:hover:[color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed rounded transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('chevron-left')\" class=\"w-4 h-4\"></svg>\n </button>\n <span class=\"px-2 text-xs font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\">{{ currentPage() }} / {{ totalPages() }}</span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"isLastPage()\"\n class=\"p-1 _shk-text-surface-500 hover:[color:var(--shk-surface-700)] dark:[color:var(--shk-surface-400)] dark:hover:[color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed rounded transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('chevron-right')\" class=\"w-4 h-4\"></svg>\n </button>\n <button\n type=\"button\"\n (click)=\"goToLast()\"\n [disabled]=\"isLastPage()\"\n class=\"p-1 _shk-text-surface-500 hover:[color:var(--shk-surface-700)] dark:[color:var(--shk-surface-400)] dark:hover:[color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed rounded transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('chevrons-right')\" class=\"w-4 h-4\"></svg>\n </button>\n </div>\n <div class=\"flex items-center gap-1.5 text-xs _shk-text-surface-600 dark:[color:var(--shk-surface-400)]\">\n <span>{{ 'table.rows' | transloco }}</span>\n <select\n [value]=\"rowsPerPageLocal()\"\n (change)=\"onRowsPerPageChange($any($event.target).value)\"\n class=\"border _shk-border dark:[border-color:var(--shk-surface-200)] rounded px-2 py-1 text-xs bg-white dark:[background-color:var(--shk-surface-100)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)] focus:outline-none focus:[border-color:var(--shk-primary-500)]\"\n >\n @for (opt of rowsPerPageOptions(); track opt) {\n <option [value]=\"opt\">{{ opt }}</option>\n }\n </select>\n </div>\n </div>\n </div>\n\n</div>\n", styles: ["input:focus{outline:none}input[type=text]{font-weight:400!important}table th{white-space:nowrap}table td{white-space:nowrap;text-overflow:ellipsis}td button svg{width:1.125rem!important;height:1.125rem!important}td button:disabled{opacity:.4;cursor:not-allowed}.table-action-btn svg{width:1rem!important;height:1rem!important;min-width:1rem!important;min-height:1rem!important}.table-action-btn{padding:.5rem!important;min-width:2rem!important;min-height:2rem!important;display:inline-flex!important;align-items:center!important;justify-content:center!important}.table-scroll-wrapper{width:100%}.table-scroll-wrapper table{table-layout:fixed}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.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: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }, { kind: "pipe", type: i1$1.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2691
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2692
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: TableComponent, isStandalone: true, selector: "shk-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, rowsPerPage: { classPropertyName: "rowsPerPage", publicName: "rowsPerPage", isSignal: true, isRequired: false, transformFunction: null }, rowsPerPageOptions: { classPropertyName: "rowsPerPageOptions", publicName: "rowsPerPageOptions", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, showActionRow: { classPropertyName: "showActionRow", publicName: "showActionRow", isSignal: true, isRequired: false, transformFunction: null }, customTemplates: { classPropertyName: "customTemplates", publicName: "customTemplates", isSignal: true, isRequired: false, transformFunction: null }, headerActions: { classPropertyName: "headerActions", publicName: "headerActions", isSignal: true, isRequired: false, transformFunction: null }, rowActions: { classPropertyName: "rowActions", publicName: "rowActions", isSignal: true, isRequired: false, transformFunction: null }, hasShadow: { classPropertyName: "hasShadow", publicName: "hasShadow", isSignal: true, isRequired: false, transformFunction: null }, defaultSortField: { classPropertyName: "defaultSortField", publicName: "defaultSortField", isSignal: true, isRequired: false, transformFunction: null }, defaultSortOrder: { classPropertyName: "defaultSortOrder", publicName: "defaultSortOrder", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, serverSide: { classPropertyName: "serverSide", publicName: "serverSide", isSignal: true, isRequired: false, transformFunction: null }, totalRecords: { classPropertyName: "totalRecords", publicName: "totalRecords", isSignal: true, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, activeFilter: { classPropertyName: "activeFilter", publicName: "activeFilter", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { refresh: "refresh", pageChange: "pageChange", filterChange: "filterChange", searchChange: "searchChange", filterClick: "filterClick" }, ngImport: i0, template: "<div class=\"space-y-2 min-[1440px]:space-y-3 mt-2 min-[1440px]:mt-3 animate-fade-in pb-8\">\n\n @if (showSearch() || filters().length > 0 || headerActions().length > 0) {\n <div class=\"card p-2 min-[1440px]:p-2.5 flex flex-row items-center justify-between gap-2\">\n\n <div class=\"flex items-center gap-2 min-[1440px]:gap-3 flex-1 min-w-0\">\n @if (showSearch()) {\n <div class=\"relative w-full md:w-52 min-[1440px]:w-56\">\n <div class=\"absolute inset-y-0 left-0 pl-2.5 flex items-center pointer-events-none\">\n <svg [lucideIcon]=\"getIcon('search')\" class=\"w-3.5 h-3.5 _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\"></svg>\n </div>\n <input\n type=\"text\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($any($event.target).value)\"\n [placeholder]=\"searchPlaceholder() || ('common.search_placeholder' | transloco)\"\n class=\"block w-full pl-8 pr-3 py-1.5 text-xs border _shk-border dark:[border-color:var(--shk-surface-200)] rounded-md leading-5\n _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] placeholder:[color:var(--shk-surface-400)] dark:placeholder:[color:var(--shk-surface-500)]\n _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\n focus:outline-none focus:bg-white dark:focus:[background-color:var(--shk-surface-800)] focus:[border-color:var(--shk-primary-500)] focus:ring-1\n focus:[--tw-ring-color:var(--shk-primary-500)]\"\n />\n </div>\n }\n\n @if (filters().length > 0) {\n <div class=\"flex _shk-bg-surface-100 dark:[background-color:var(--shk-surface-100)] p-0.5 rounded-md ml-auto\">\n @for (f of filters(); track f.value) {\n <button\n type=\"button\"\n (click)=\"onFilterClick(f.value)\"\n class=\"px-2.5 min-[1440px]:px-3 py-1 text-xs font-medium rounded _shk-text-surface-700 dark:[color:var(--shk-surface-700)] transition-all\"\n [class]=\"f.value === activeFilter() ? 'bg-white shadow-sm dark:[background-color:var(--shk-surface-700)]' : ''\"\n >\n {{ f.label }}\n </button>\n }\n </div>\n }\n </div>\n\n @if (headerActions().length > 0) {\n <div class=\"flex items-center gap-1.5 shrink-0\">\n @for (action of headerActions(); track $index) {\n @if (isHeaderActionVisible(action)) {\n <button\n type=\"button\"\n [class]=\"action.class || 'inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md _shk-bg-primary text-white hover:[background-color:var(--shk-primary-700)] transition-colors disabled:opacity-50 disabled:cursor-not-allowed'\"\n [disabled]=\"isHeaderActionDisabled(action)\"\n (click)=\"action.onClick()\"\n >\n @if (action.icon) {\n <svg\n [lucideIcon]=\"getIcon(action.icon)\"\n class=\"w-3.5 h-3.5\"\n ></svg>\n }\n {{ action.label }}\n </button>\n }\n }\n </div>\n }\n\n </div>\n }\n\n <div\n class=\"card p-0 overflow-hidden\"\n [class.shadow-lg]=\"hasShadow()\"\n >\n\n <div class=\"table-scroll-wrapper _shk-scrollbar\">\n <table class=\"w-full\">\n <thead>\n <tr>\n @for (col of columnsWithActions(); track col.field) {\n <th\n (click)=\"col.field !== 'actions' && col.sortable && toggleSort(col.field)\"\n [style.cursor]=\"col.field !== 'actions' && col.sortable ? 'pointer' : 'default'\"\n [style.width]=\"col.width || 'auto'\"\n [style.min-width]=\"col.field === 'actions' ? '130px' : 'auto'\"\n class=\"px-2 min-[1440px]:px-3 py-2 min-[1440px]:py-2.5 text-left text-[10px] min-[1440px]:text-xs font-bold _shk-text-surface-500 dark:[color:var(--shk-surface-400)] uppercase tracking-wider\n _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border-b _shk-border dark:[border-color:var(--shk-surface-200)]\"\n >\n @if (col.field !== 'actions') {\n <div class=\"flex items-center justify-between gap-2\">\n <span>{{ col.header }}</span>\n <div class=\"flex items-center gap-1\">\n @if (col.sortable) {\n <div class=\"relative group\">\n @if (sortField() === col.field) {\n <svg [lucideIcon]=\"getIcon(sortOrder() === 1 ? 'arrow-up' : 'arrow-down')\"\n class=\"w-3.5 h-3.5 _shk-text-primary\"></svg>\n } @else {\n <svg [lucideIcon]=\"getIcon('arrow-up-down')\"\n class=\"w-3.5 h-3.5 _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\"></svg>\n }\n <span class=\"absolute top-full left-1/2 -translate-x-1/2 mt-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ 'table.tooltips.sort' | transloco }}\n </span>\n </div>\n }\n @if (col.filter) {\n <div class=\"relative group\">\n <button\n type=\"button\"\n (click)=\"$event.stopPropagation(); toggleFilter(col.field)\"\n class=\"_shk-text-surface-400 dark:[color:var(--shk-surface-500)] hover:[color:var(--shk-surface-600)] dark:hover:[color:var(--shk-surface-300)] transition-colors\"\n >\n <svg\n [lucideIcon]=\"getIcon('filter')\"\n class=\"w-3.5 h-3.5\"\n [class._shk-text-primary]=\"columnFiltersForm.get(col.field)?.value\"\n ></svg>\n <span class=\"absolute top-full left-1/2 -translate-x-1/2 mt-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ 'table.tooltips.filter' | transloco }}\n </span>\n </button>\n </div>\n }\n </div>\n </div>\n\n @if (col.filter && showFilterInput()[col.field]) {\n <div\n class=\"mt-2\"\n [formGroup]=\"columnFiltersForm\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"relative\">\n @if (col.filterType !== 'select') {\n <input\n type=\"text\"\n [formControlName]=\"col.field\"\n class=\"w-full px-3 py-1.5 text-sm rounded-md border _shk-border dark:[border-color:var(--shk-surface-200)] bg-white dark:[background-color:var(--shk-surface-100)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\n focus:[border-color:var(--shk-primary-500)] focus:ring-1 focus:[--tw-ring-color:var(--shk-primary-500)]\n placeholder:[color:var(--shk-surface-400)] dark:placeholder:[color:var(--shk-surface-500)]\"\n [placeholder]=\"col.filterPlaceholder || ('common.search_placeholder' | transloco)\"\n />\n }\n @if (col.filterType === 'select') {\n <select\n [formControlName]=\"col.field\"\n class=\"w-full px-2 py-1 text-xs rounded-md border _shk-border dark:[border-color:var(--shk-surface-200)] bg-white dark:[background-color:var(--shk-surface-100)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)] focus:[border-color:var(--shk-primary-500)] focus:ring-1 focus:[--tw-ring-color:var(--shk-primary-500)] appearance-none\"\n >\n <option [ngValue]=\"null\">A/D</option>\n @for (opt of col.filterOptions || []; track opt.value) {\n <option [ngValue]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @if (columnFiltersForm.get(col.field)?.value && col.filterType !== 'select') {\n <button\n type=\"button\"\n class=\"absolute right-2 top-1/2 -translate-y-1/2 _shk-text-surface-400 dark:[color:var(--shk-surface-500)] hover:[color:var(--shk-surface-600)] dark:hover:[color:var(--shk-surface-300)]\"\n (click)=\"clearFilter(col.field)\"\n >\n <svg [lucideIcon]=\"getIcon('x')\" class=\"w-3.5 h-3.5\"></svg>\n </button>\n }\n </div>\n </div>\n }\n } @else {\n <div class=\"flex items-center justify-center\">\n <span>{{ col.header }}</span>\n </div>\n }\n </th>\n }\n </tr>\n </thead>\n\n @if (loading()) {\n <tbody class=\"border-b _shk-border dark:[border-color:var(--shk-surface-100)]\">\n <tr>\n <td [attr.colspan]=\"columnsWithActions().length\" class=\"text-center py-12\">\n <div class=\"flex items-center justify-center\">\n <svg [lucideIcon]=\"getIcon('loader')\" class=\"w-6 h-6 animate-spin _shk-text-primary\"></svg>\n </div>\n </td>\n </tr>\n </tbody>\n } @else if (effectiveDisplayedData().length === 0) {\n <tbody class=\"border-b _shk-border dark:[border-color:var(--shk-surface-100)]\">\n <tr>\n <td [attr.colspan]=\"columnsWithActions().length\" class=\"text-center py-12\">\n <div class=\"flex flex-col items-center\">\n <div class=\"w-16 h-16 _shk-bg-surface-100 dark:[background-color:var(--shk-surface-100)] rounded-full flex items-center justify-center mb-4\">\n <svg [lucideIcon]=\"getIcon('inbox')\" class=\"w-8 h-8 _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\"></svg>\n </div>\n <p class=\"text-lg font-semibold _shk-text-surface-600 dark:[color:var(--shk-surface-300)]\">\n {{ emptyMessage() || ('common.no_records' | transloco) }}\n </p>\n </div>\n </td>\n </tr>\n </tbody>\n } @else {\n <tbody>\n @for (rowData of effectiveDisplayedData(); track $index) {\n <tr class=\"hover:[background-color:color-mix(in srgb,var(--shk-primary-50)30%,transparent)] dark:hover:[background-color:color-mix(in srgb,var(--shk-primary-900)10%,transparent)] transition-colors duration-200 border-b _shk-border dark:[border-color:var(--shk-surface-100)]\">\n @for (col of columnsWithActions(); track col.field) {\n <td\n class=\"px-2 min-[1440px]:px-3 py-2 min-[1440px]:py-2.5 text-xs font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-700)] whitespace-nowrap\"\n [style.overflow]=\"col.field === 'actions' ? 'visible' : 'hidden'\"\n [style.text-overflow]=\"col.field === 'actions' ? 'clip' : 'ellipsis'\"\n >\n @if (col.field !== 'actions') {\n @if (col.template === 'tag') {\n <span\n class=\"inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium\"\n [class]=\"getTagClass(col.tagSeverity ? col.tagSeverity(rowData) : undefined)\"\n [style]=\"col.tagStyle ? col.tagStyle(rowData) : undefined\"\n >\n {{ col.tagValue ? col.tagValue(rowData) : rowData[col.field] }}\n </span>\n } @else if (col.format) {\n <span>{{ col.format(rowData) }}</span>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"\n customTemplates()[col.field] || defaultTemplate;\n context: { $implicit: rowData, field: col.field }\n \"\n ></ng-container>\n }\n } @else {\n <div class=\"flex items-center justify-start gap-px\">\n @for (action of rowActions(); track $index) {\n @if (isRowActionVisible(action, rowData)) {\n <div class=\"relative group\">\n <button\n type=\"button\"\n (click)=\"action.onClick(rowData)\"\n [class]=\"'table-action-btn hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] rounded-md ' + getRowActionClass(action, rowData)\"\n [disabled]=\"isRowActionDisabled(action, rowData) || false\"\n >\n <svg\n [lucideIcon]=\"getIcon(getRowActionIconName(action, rowData))\"\n class=\"w-4 h-4\"\n ></svg>\n </button>\n <span class=\"absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ getRowActionLabel(action, rowData) }}\n </span>\n </div>\n }\n }\n </div>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n }\n </table>\n\n <ng-template #defaultTemplate let-rowData let-field=\"field\">\n {{ truncate(rowData[field], 30) }}\n </ng-template>\n </div>\n\n <div class=\"flex items-center justify-between gap-4 px-2 min-[1440px]:px-3 py-2 border-t _shk-border dark:[border-color:var(--shk-surface-100)]\">\n <div class=\"text-xs _shk-text-surface-600 dark:[color:var(--shk-surface-400)]\">{{ getPageReport() }}</div>\n <div class=\"flex items-center gap-0.5\">\n <button\n type=\"button\"\n (click)=\"goToFirst()\"\n [disabled]=\"isFirstPage()\"\n class=\"p-1 _shk-text-surface-500 hover:[color:var(--shk-surface-700)] dark:[color:var(--shk-surface-400)] dark:hover:[color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed rounded transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('chevrons-left')\" class=\"w-4 h-4\"></svg>\n </button>\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"isFirstPage()\"\n class=\"p-1 _shk-text-surface-500 hover:[color:var(--shk-surface-700)] dark:[color:var(--shk-surface-400)] dark:hover:[color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed rounded transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('chevron-left')\" class=\"w-4 h-4\"></svg>\n </button>\n <span class=\"px-2 text-xs font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\">{{ currentPage() }} / {{ totalPages() }}</span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"isLastPage()\"\n class=\"p-1 _shk-text-surface-500 hover:[color:var(--shk-surface-700)] dark:[color:var(--shk-surface-400)] dark:hover:[color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed rounded transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('chevron-right')\" class=\"w-4 h-4\"></svg>\n </button>\n <button\n type=\"button\"\n (click)=\"goToLast()\"\n [disabled]=\"isLastPage()\"\n class=\"p-1 _shk-text-surface-500 hover:[color:var(--shk-surface-700)] dark:[color:var(--shk-surface-400)] dark:hover:[color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed rounded transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('chevrons-right')\" class=\"w-4 h-4\"></svg>\n </button>\n </div>\n <div class=\"flex items-center gap-1.5 text-xs _shk-text-surface-600 dark:[color:var(--shk-surface-400)]\">\n <span>{{ 'table.rows' | transloco }}</span>\n <select\n [value]=\"rowsPerPageLocal()\"\n (change)=\"onRowsPerPageChange($any($event.target).value)\"\n class=\"border _shk-border dark:[border-color:var(--shk-surface-200)] rounded px-2 py-1 text-xs bg-white dark:[background-color:var(--shk-surface-100)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)] focus:outline-none focus:[border-color:var(--shk-primary-500)]\"\n >\n @for (opt of rowsPerPageOptions(); track opt) {\n <option [value]=\"opt\">{{ opt }}</option>\n }\n </select>\n </div>\n </div>\n </div>\n\n</div>\n", styles: ["input:focus{outline:none}input[type=text]{font-weight:400!important}table th{white-space:nowrap}table td{white-space:nowrap;text-overflow:ellipsis}td button svg{width:1.125rem!important;height:1.125rem!important}td button:disabled{opacity:.4;cursor:not-allowed}.table-action-btn svg{width:1rem!important;height:1rem!important;min-width:1rem!important;min-height:1rem!important}.table-action-btn{padding:.5rem!important;min-width:2rem!important;min-height:2rem!important;display:inline-flex!important;align-items:center!important;justify-content:center!important}.table-scroll-wrapper{width:100%}.table-scroll-wrapper table{table-layout:fixed}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.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: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }, { kind: "pipe", type: i1$1.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2685
2693
|
}
|
|
2686
2694
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TableComponent, decorators: [{
|
|
2687
2695
|
type: Component,
|
|
@@ -2694,13 +2702,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
|
|
|
2694
2702
|
}], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], rowsPerPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowsPerPage", required: false }] }], rowsPerPageOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowsPerPageOptions", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], showActionRow: [{ type: i0.Input, args: [{ isSignal: true, alias: "showActionRow", required: false }] }], customTemplates: [{ type: i0.Input, args: [{ isSignal: true, alias: "customTemplates", required: false }] }], headerActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerActions", required: false }] }], rowActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowActions", required: false }] }], hasShadow: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasShadow", required: false }] }], defaultSortField: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultSortField", required: false }] }], defaultSortOrder: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultSortOrder", required: false }] }], showSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSearch", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], serverSide: [{ type: i0.Input, args: [{ isSignal: true, alias: "serverSide", required: false }] }], totalRecords: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalRecords", required: false }] }], filters: [{ type: i0.Input, args: [{ isSignal: true, alias: "filters", required: false }] }], activeFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeFilter", required: false }] }], refresh: [{ type: i0.Output, args: ["refresh"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], searchChange: [{ type: i0.Output, args: ["searchChange"] }], filterClick: [{ type: i0.Output, args: ["filterClick"] }] } });
|
|
2695
2703
|
|
|
2696
2704
|
class TooltipComponent {
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2705
|
+
constructor() {
|
|
2706
|
+
this.text = input('', ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
|
|
2707
|
+
this.position = input('bottom', ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
|
|
2708
|
+
this.mode = input('hover', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
2709
|
+
this.offset = input(8, ...(ngDevMode ? [{ debugName: "offset" }] : /* istanbul ignore next */ []));
|
|
2710
|
+
this.elementRef = inject(ElementRef);
|
|
2711
|
+
this.tooltipX = signal(0, ...(ngDevMode ? [{ debugName: "tooltipX" }] : /* istanbul ignore next */ []));
|
|
2712
|
+
this.tooltipY = signal(0, ...(ngDevMode ? [{ debugName: "tooltipY" }] : /* istanbul ignore next */ []));
|
|
2713
|
+
}
|
|
2704
2714
|
onMouseEnter() {
|
|
2705
2715
|
if (this.mode() !== 'fixed')
|
|
2706
2716
|
return;
|
|
@@ -2723,8 +2733,8 @@ class TooltipComponent {
|
|
|
2723
2733
|
this.tooltipY.set(rect.top - off);
|
|
2724
2734
|
}
|
|
2725
2735
|
}
|
|
2726
|
-
static
|
|
2727
|
-
static
|
|
2736
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2737
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: TooltipComponent, isStandalone: true, selector: "shk-tooltip", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "onMouseEnter()" } }, ngImport: i0, template: `
|
|
2728
2738
|
<div class="relative group inline-flex">
|
|
2729
2739
|
<ng-content></ng-content>
|
|
2730
2740
|
@if (text() && mode() === 'hover') {
|
|
@@ -2755,7 +2765,7 @@ class TooltipComponent {
|
|
|
2755
2765
|
</span>
|
|
2756
2766
|
}
|
|
2757
2767
|
</div>
|
|
2758
|
-
`, isInline: true });
|
|
2768
|
+
`, isInline: true }); }
|
|
2759
2769
|
}
|
|
2760
2770
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TooltipComponent, decorators: [{
|
|
2761
2771
|
type: Component,
|
|
@@ -2800,14 +2810,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
|
|
|
2800
2810
|
args: ['mouseenter']
|
|
2801
2811
|
}] } });
|
|
2802
2812
|
|
|
2803
|
-
Chart.register(...registerables);
|
|
2804
2813
|
class ChartComponent {
|
|
2805
|
-
|
|
2806
|
-
data = input({ datasets: [] }, ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
2807
|
-
options = input({}, ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
2808
|
-
canvasRef = viewChild.required('canvas');
|
|
2809
|
-
chartInstance = null;
|
|
2810
|
-
initialized = false;
|
|
2814
|
+
static { this.registered = false; }
|
|
2811
2815
|
ngAfterViewInit() {
|
|
2812
2816
|
this.initialized = true;
|
|
2813
2817
|
this.initChart();
|
|
@@ -2826,6 +2830,16 @@ class ChartComponent {
|
|
|
2826
2830
|
});
|
|
2827
2831
|
}
|
|
2828
2832
|
constructor() {
|
|
2833
|
+
this.type = input('bar', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
2834
|
+
this.data = input({ datasets: [] }, ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
2835
|
+
this.options = input({}, ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
2836
|
+
this.canvasRef = viewChild.required('canvas');
|
|
2837
|
+
this.chartInstance = null;
|
|
2838
|
+
this.initialized = false;
|
|
2839
|
+
if (!ChartComponent.registered) {
|
|
2840
|
+
Chart.register(...registerables);
|
|
2841
|
+
ChartComponent.registered = true;
|
|
2842
|
+
}
|
|
2829
2843
|
effect(() => {
|
|
2830
2844
|
const t = this.type();
|
|
2831
2845
|
const d = this.data();
|
|
@@ -2853,12 +2867,12 @@ class ChartComponent {
|
|
|
2853
2867
|
this.chartInstance.options = options;
|
|
2854
2868
|
this.chartInstance.update();
|
|
2855
2869
|
}
|
|
2856
|
-
static
|
|
2857
|
-
static
|
|
2870
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2871
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.18", type: ChartComponent, isStandalone: true, selector: "shk-chart", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
2858
2872
|
<div class="relative h-full w-full">
|
|
2859
2873
|
<canvas #canvas></canvas>
|
|
2860
2874
|
</div>
|
|
2861
|
-
`, isInline: true });
|
|
2875
|
+
`, isInline: true }); }
|
|
2862
2876
|
}
|
|
2863
2877
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ChartComponent, decorators: [{
|
|
2864
2878
|
type: Component,
|