@tinya-code/gas-admin-ui 0.0.0-stage → 0.1.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -2
- package/fesm2022/tinya-code-gas-admin-ui-api.service-CZrUeclM.mjs +281 -0
- package/fesm2022/tinya-code-gas-admin-ui-api.service-CZrUeclM.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-badge-EeCA_l-o.mjs +84 -0
- package/fesm2022/tinya-code-gas-admin-ui-badge-EeCA_l-o.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-bar-chart-G7sEMSBY.mjs +140 -0
- package/fesm2022/tinya-code-gas-admin-ui-bar-chart-G7sEMSBY.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-boolean-B2ASKL0E.mjs +113 -0
- package/fesm2022/tinya-code-gas-admin-ui-boolean-B2ASKL0E.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-button-BQjNW8KB.mjs +163 -0
- package/fesm2022/tinya-code-gas-admin-ui-button-BQjNW8KB.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-calendar-view-r-RXDE37.mjs +1022 -0
- package/fesm2022/tinya-code-gas-admin-ui-calendar-view-r-RXDE37.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-chart-line-BjdlKHoH.mjs +278 -0
- package/fesm2022/tinya-code-gas-admin-ui-chart-line-BjdlKHoH.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-condition-evaluator-BBzWUuHl.mjs +101 -0
- package/fesm2022/tinya-code-gas-admin-ui-condition-evaluator-BBzWUuHl.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-currency-BvuF3Z63.mjs +141 -0
- package/fesm2022/tinya-code-gas-admin-ui-currency-BvuF3Z63.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-data-source.service-LD8AM3Rn.mjs +89 -0
- package/fesm2022/tinya-code-gas-admin-ui-data-source.service-LD8AM3Rn.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-date-1SJGXZrd.mjs +107 -0
- package/fesm2022/tinya-code-gas-admin-ui-date-1SJGXZrd.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-badge-fwk6sDU7.mjs +140 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-badge-fwk6sDU7.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-date-D7zLiDiG.mjs +119 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-date-D7zLiDiG.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-file-BiIhqvQC.mjs +125 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-file-BiIhqvQC.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-image-C1dhnZi1.mjs +152 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-image-C1dhnZi1.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-list-DOEuUbGe.mjs +211 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-list-DOEuUbGe.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-number-DDMzr4Hn.mjs +116 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-number-DDMzr4Hn.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-text-B8CdVNpv.mjs +111 -0
- package/fesm2022/tinya-code-gas-admin-ui-display-text-B8CdVNpv.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-email-CT_O5ihA.mjs +107 -0
- package/fesm2022/tinya-code-gas-admin-ui-email-CT_O5ihA.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-empty-state-BMc0QtoT.mjs +109 -0
- package/fesm2022/tinya-code-gas-admin-ui-empty-state-BMc0QtoT.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-error-mapper.service-Ci0UpXtV.mjs +45 -0
- package/fesm2022/tinya-code-gas-admin-ui-error-mapper.service-Ci0UpXtV.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-field-aria-BD1Wiggc.mjs +50 -0
- package/fesm2022/tinya-code-gas-admin-ui-field-aria-BD1Wiggc.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-field-node-CIK6KNN_.mjs +24 -0
- package/fesm2022/tinya-code-gas-admin-ui-field-node-CIK6KNN_.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-field-path-B4-FTBGZ.mjs +27 -0
- package/fesm2022/tinya-code-gas-admin-ui-field-path-B4-FTBGZ.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-file-Dg2N3XQ2.mjs +408 -0
- package/fesm2022/tinya-code-gas-admin-ui-file-Dg2N3XQ2.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-form-view-BwGupSbi.mjs +4514 -0
- package/fesm2022/tinya-code-gas-admin-ui-form-view-BwGupSbi.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-badge-CK8ct5Wk.mjs +82 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-badge-CK8ct5Wk.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-boolean-ClzezZz-.mjs +105 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-boolean-ClzezZz-.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-currency-CVmniKml.mjs +65 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-currency-CVmniKml.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-date-Dr1YsDd_.mjs +65 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-date-Dr1YsDd_.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-number-CWCjpI4n.mjs +65 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-number-CWCjpI4n.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-text-DBOgJkH0.mjs +59 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-text-DBOgJkH0.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-thumbnail-PCRvxWKt.mjs +94 -0
- package/fesm2022/tinya-code-gas-admin-ui-format-thumbnail-PCRvxWKt.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-gap-sorting-iTdy_DYG.mjs +72 -0
- package/fesm2022/tinya-code-gas-admin-ui-gap-sorting-iTdy_DYG.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-group-h7-O8tt4.mjs +238 -0
- package/fesm2022/tinya-code-gas-admin-ui-group-h7-O8tt4.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-image-Bjw9ImlS.mjs +416 -0
- package/fesm2022/tinya-code-gas-admin-ui-image-Bjw9ImlS.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-kanban-view-CeGueI57.mjs +439 -0
- package/fesm2022/tinya-code-gas-admin-ui-kanban-view-CeGueI57.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-key-value-nVdgg5at.mjs +513 -0
- package/fesm2022/tinya-code-gas-admin-ui-key-value-nVdgg5at.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-list-CMzl9MkX.mjs +637 -0
- package/fesm2022/tinya-code-gas-admin-ui-list-CMzl9MkX.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs +127 -0
- package/fesm2022/tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-multiselect-CuWwAfdY.mjs +251 -0
- package/fesm2022/tinya-code-gas-admin-ui-multiselect-CuWwAfdY.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs +66 -0
- package/fesm2022/tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-number-JNr7glc8.mjs +114 -0
- package/fesm2022/tinya-code-gas-admin-ui-number-JNr7glc8.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-phone-jR417hPf.mjs +116 -0
- package/fesm2022/tinya-code-gas-admin-ui-phone-jR417hPf.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-quick-actions-DCQ6emmF.mjs +235 -0
- package/fesm2022/tinya-code-gas-admin-ui-quick-actions-DCQ6emmF.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-radio-mode-DxvN07DY.mjs +8 -0
- package/fesm2022/tinya-code-gas-admin-ui-radio-mode-DxvN07DY.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-readonly-text-BL7-4qie.mjs +124 -0
- package/fesm2022/tinya-code-gas-admin-ui-readonly-text-BL7-4qie.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-record-list-BiZfnd_7.mjs +249 -0
- package/fesm2022/tinya-code-gas-admin-ui-record-list-BiZfnd_7.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-relation-B3W3Ynsp.mjs +309 -0
- package/fesm2022/tinya-code-gas-admin-ui-relation-B3W3Ynsp.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-relation-drawer.service-B0kT8EiW.mjs +39 -0
- package/fesm2022/tinya-code-gas-admin-ui-relation-drawer.service-B0kT8EiW.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-render-registry-B_D5Jhp9.mjs +546 -0
- package/fesm2022/tinya-code-gas-admin-ui-render-registry-B_D5Jhp9.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-rolldown-runtime-DpJrqANO.mjs +11 -0
- package/fesm2022/tinya-code-gas-admin-ui-schema-catalog-CDrz9pVN.mjs +131 -0
- package/fesm2022/tinya-code-gas-admin-ui-schema-catalog-CDrz9pVN.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-seed-CNbQtREA.mjs +80 -0
- package/fesm2022/tinya-code-gas-admin-ui-seed-CNbQtREA.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-select-DzaRfHXO.mjs +292 -0
- package/fesm2022/tinya-code-gas-admin-ui-select-DzaRfHXO.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-skeleton-DnWK0tcZ.mjs +119 -0
- package/fesm2022/tinya-code-gas-admin-ui-skeleton-DnWK0tcZ.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-slug-DU58cbiY.mjs +158 -0
- package/fesm2022/tinya-code-gas-admin-ui-slug-DU58cbiY.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-source-options-B9R4mw8-.mjs +26 -0
- package/fesm2022/tinya-code-gas-admin-ui-source-options-B9R4mw8-.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-status-progress-DmeG8htE.mjs +205 -0
- package/fesm2022/tinya-code-gas-admin-ui-status-progress-DmeG8htE.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-string-list-gleasqzD.mjs +432 -0
- package/fesm2022/tinya-code-gas-admin-ui-string-list-gleasqzD.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-template-interpolator-ewv7CkNX.mjs +36 -0
- package/fesm2022/tinya-code-gas-admin-ui-template-interpolator-ewv7CkNX.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-text-CUPmL7W_.mjs +107 -0
- package/fesm2022/tinya-code-gas-admin-ui-text-CUPmL7W_.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-textarea-CGLSIW13.mjs +223 -0
- package/fesm2022/tinya-code-gas-admin-ui-textarea-CGLSIW13.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-time-BcHzsTWf.mjs +107 -0
- package/fesm2022/tinya-code-gas-admin-ui-time-BcHzsTWf.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-upload.service-C1g545w5.mjs +60 -0
- package/fesm2022/tinya-code-gas-admin-ui-upload.service-C1g545w5.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-url-GO4LZi__.mjs +141 -0
- package/fesm2022/tinya-code-gas-admin-ui-url-GO4LZi__.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui.mjs +4403 -0
- package/fesm2022/tinya-code-gas-admin-ui.mjs.map +1 -0
- package/package.json +31 -3
- package/types/tinya-code-gas-admin-ui.d.ts +3099 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { Component, computed, input } from "@angular/core";
|
|
3
|
+
var MetricCard = class MetricCard {
|
|
4
|
+
label = input.required(...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
|
|
5
|
+
value = input(null, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
|
|
6
|
+
hint = input("", ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
|
|
7
|
+
empty = computed(() => this.value() === null || this.value() === void 0, ...ngDevMode ? [{ debugName: "empty" }] : /* istanbul ignore next */ []);
|
|
8
|
+
display = computed(() => {
|
|
9
|
+
const value = this.value();
|
|
10
|
+
return typeof value === "number" ? new Intl.NumberFormat("es-PE").format(value) : String(value);
|
|
11
|
+
}, ...ngDevMode ? [{ debugName: "display" }] : /* istanbul ignore next */ []);
|
|
12
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
13
|
+
minVersion: "12.0.0",
|
|
14
|
+
version: "22.2.3",
|
|
15
|
+
ngImport: i0,
|
|
16
|
+
type: MetricCard,
|
|
17
|
+
deps: [],
|
|
18
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
19
|
+
});
|
|
20
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
21
|
+
minVersion: "17.0.0",
|
|
22
|
+
version: "22.2.3",
|
|
23
|
+
type: MetricCard,
|
|
24
|
+
isStandalone: true,
|
|
25
|
+
selector: "app-metric-card",
|
|
26
|
+
inputs: {
|
|
27
|
+
label: {
|
|
28
|
+
classPropertyName: "label",
|
|
29
|
+
publicName: "label",
|
|
30
|
+
isSignal: true,
|
|
31
|
+
isRequired: true,
|
|
32
|
+
transformFunction: null
|
|
33
|
+
},
|
|
34
|
+
value: {
|
|
35
|
+
classPropertyName: "value",
|
|
36
|
+
publicName: "value",
|
|
37
|
+
isSignal: true,
|
|
38
|
+
isRequired: false,
|
|
39
|
+
transformFunction: null
|
|
40
|
+
},
|
|
41
|
+
hint: {
|
|
42
|
+
classPropertyName: "hint",
|
|
43
|
+
publicName: "hint",
|
|
44
|
+
isSignal: true,
|
|
45
|
+
isRequired: false,
|
|
46
|
+
transformFunction: null
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
ngImport: i0,
|
|
50
|
+
template: `
|
|
51
|
+
<article class="rounded-lg border border-neutral/20 bg-surface p-4">
|
|
52
|
+
<p class="text-sm text-neutral">{{ label() }}</p>
|
|
53
|
+
|
|
54
|
+
@if (empty()) {
|
|
55
|
+
<p class="font-display text-3xl font-semibold text-neutral/40" data-testid="value-empty">
|
|
56
|
+
—
|
|
57
|
+
</p>
|
|
58
|
+
} @else {
|
|
59
|
+
<p class="font-display text-3xl font-semibold" data-testid="value">{{ display() }}</p>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@if (hint()) {
|
|
63
|
+
<p class="mt-1 text-xs text-neutral">{{ hint() }}</p>
|
|
64
|
+
}
|
|
65
|
+
</article>
|
|
66
|
+
`,
|
|
67
|
+
isInline: true
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
71
|
+
minVersion: "12.0.0",
|
|
72
|
+
version: "22.2.3",
|
|
73
|
+
ngImport: i0,
|
|
74
|
+
type: MetricCard,
|
|
75
|
+
decorators: [{
|
|
76
|
+
type: Component,
|
|
77
|
+
args: [{
|
|
78
|
+
selector: "app-metric-card",
|
|
79
|
+
template: `
|
|
80
|
+
<article class="rounded-lg border border-neutral/20 bg-surface p-4">
|
|
81
|
+
<p class="text-sm text-neutral">{{ label() }}</p>
|
|
82
|
+
|
|
83
|
+
@if (empty()) {
|
|
84
|
+
<p class="font-display text-3xl font-semibold text-neutral/40" data-testid="value-empty">
|
|
85
|
+
—
|
|
86
|
+
</p>
|
|
87
|
+
} @else {
|
|
88
|
+
<p class="font-display text-3xl font-semibold" data-testid="value">{{ display() }}</p>
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@if (hint()) {
|
|
92
|
+
<p class="mt-1 text-xs text-neutral">{{ hint() }}</p>
|
|
93
|
+
}
|
|
94
|
+
</article>
|
|
95
|
+
`
|
|
96
|
+
}]
|
|
97
|
+
}],
|
|
98
|
+
propDecorators: {
|
|
99
|
+
label: [{
|
|
100
|
+
type: i0.Input,
|
|
101
|
+
args: [{
|
|
102
|
+
isSignal: true,
|
|
103
|
+
alias: "label",
|
|
104
|
+
required: true
|
|
105
|
+
}]
|
|
106
|
+
}],
|
|
107
|
+
value: [{
|
|
108
|
+
type: i0.Input,
|
|
109
|
+
args: [{
|
|
110
|
+
isSignal: true,
|
|
111
|
+
alias: "value",
|
|
112
|
+
required: false
|
|
113
|
+
}]
|
|
114
|
+
}],
|
|
115
|
+
hint: [{
|
|
116
|
+
type: i0.Input,
|
|
117
|
+
args: [{
|
|
118
|
+
isSignal: true,
|
|
119
|
+
alias: "hint",
|
|
120
|
+
required: false
|
|
121
|
+
}]
|
|
122
|
+
}]
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
export { MetricCard };
|
|
126
|
+
|
|
127
|
+
//# sourceMappingURL=tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs","names":[],"sources":["../../../projects/gas-admin-ui/src/lib/widgets/metric-card/metric-card.ts"],"sourcesContent":["import { Component, computed, input } from '@angular/core';\n\n/**\n * KPI de una cifra suelta («3 pendientes»).\n *\n * Cero dependencias: es sólo presentación — el valor lo trae el\n * orquestador del panel desde el endpoint de métricas.\n *\n * Sin `icon`: el schema no tiene hoy un registro de nombres de icono\n * (los Lucide se importan estáticamente), así que un `icon?: string` no\n * podría resolverse declarativamente. Se añade cuando exista ese registro.\n */\n@Component({\n selector: 'app-metric-card',\n template: `\n <article class=\"rounded-lg border border-neutral/20 bg-surface p-4\">\n <p class=\"text-sm text-neutral\">{{ label() }}</p>\n\n @if (empty()) {\n <p class=\"font-display text-3xl font-semibold text-neutral/40\" data-testid=\"value-empty\">\n —\n </p>\n } @else {\n <p class=\"font-display text-3xl font-semibold\" data-testid=\"value\">{{ display() }}</p>\n }\n\n @if (hint()) {\n <p class=\"mt-1 text-xs text-neutral\">{{ hint() }}</p>\n }\n </article>\n `,\n})\nexport class MetricCard {\n /** Rótulo del KPI. */\n readonly label = input.required<string>();\n /** Cifra a mostrar; `null`/`undefined` ⇒ estado vacío. */\n readonly value = input<unknown>(null);\n /** Texto secundario estático bajo la cifra. */\n readonly hint = input('');\n\n /** `0` es un valor, no un vacío: sólo `null`/`undefined` vacían la tarjeta. */\n protected readonly empty = computed(() => this.value() === null || this.value() === undefined);\n\n protected readonly display = computed(() => {\n const value = this.value();\n return typeof value === 'number' ? new Intl.NumberFormat('es-PE').format(value) : String(value);\n });\n}\n"],"mappings":";;AAgCA,IAAa,aAAb,MAAa,WAAU;CAEZ,QAAQ,MAAM,SAAkB,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAEhC,QAAQ,MAAe,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAE5B,OAAO,MAAM,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAGN,QAAQ,eAAe,KAAK,MAAK,MAAO,QAAQ,KAAK,MAAK,MAAO,QAAU,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAE3E,UAAU,eAAc;EACzC,MAAM,QAAQ,KAAK,MAAK;EACxB,OAAO,OAAO,UAAU,WAAW,IAAI,KAAK,aAAa,OAAO,CAAC,CAAC,OAAO,KAAK,IAAI,OAAO,KAAK;CAChG,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAdS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAU,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAV,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAU,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,MAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,UAAA;EAAA,UAlBX;;;;;;;;;;;;;;;;;EAgBT,UAAA;CAAA,CAAA;;AAEU,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAU,YAAA,CAAA;EApBtB,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,UAAU;;;;;;;;;;;;;;;;;EAiBX,CAAA"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { t as __exportAll } from "./tinya-code-gas-admin-ui-rolldown-runtime-DpJrqANO.mjs";
|
|
2
|
+
import { i as getSchema } from "./tinya-code-gas-admin-ui-schema-catalog-CDrz9pVN.mjs";
|
|
3
|
+
import { n as dataSourceKey, t as DataSourceService } from "./tinya-code-gas-admin-ui-data-source.service-LD8AM3Rn.mjs";
|
|
4
|
+
import { t as optionsFromRows } from "./tinya-code-gas-admin-ui-source-options-B9R4mw8-.mjs";
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import { Component, computed, inject, input, model, resource } from "@angular/core";
|
|
7
|
+
import { LucideX } from "@lucide/angular";
|
|
8
|
+
var multiselect_exports = /* @__PURE__ */ __exportAll({ FieldMultiselect: () => FieldMultiselect });
|
|
9
|
+
var FieldMultiselect = class FieldMultiselect {
|
|
10
|
+
field = input.required(...ngDevMode ? [{ debugName: "field" }] : /* istanbul ignore next */ []);
|
|
11
|
+
tree = input(...ngDevMode ? [void 0, { debugName: "tree" }] : /* istanbul ignore next */ []);
|
|
12
|
+
value = model.required(...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
|
|
13
|
+
disabled = input(false, ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
|
|
14
|
+
ds = inject(DataSourceService);
|
|
15
|
+
registro = computed(() => {
|
|
16
|
+
const source = this.field().source;
|
|
17
|
+
const tree = this.tree();
|
|
18
|
+
if (source === void 0 || source.params === void 0 || tree === void 0) return void 0;
|
|
19
|
+
return tree().value();
|
|
20
|
+
}, ...ngDevMode ? [{ debugName: "registro" }] : /* istanbul ignore next */ []);
|
|
21
|
+
claveFuente = computed(() => {
|
|
22
|
+
const source = this.field().source;
|
|
23
|
+
return source === void 0 ? void 0 : dataSourceKey(source, this.registro());
|
|
24
|
+
}, ...ngDevMode ? [{ debugName: "claveFuente" }] : /* istanbul ignore next */ []);
|
|
25
|
+
fuenteResource = resource({
|
|
26
|
+
...ngDevMode ? { debugName: "fuenteResource" } : /* istanbul ignore next */ {},
|
|
27
|
+
params: () => this.claveFuente(),
|
|
28
|
+
loader: async () => {
|
|
29
|
+
const source = this.field().source;
|
|
30
|
+
if (source === void 0) return [];
|
|
31
|
+
return this.ds.rows(source, this.registro());
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
opciones = computed(() => {
|
|
35
|
+
const field = this.field();
|
|
36
|
+
if (field.source === void 0) return field.options ?? [];
|
|
37
|
+
if (this.fuenteResource.status() === "error") return [];
|
|
38
|
+
return optionsFromRows(this.fuenteResource.value() ?? [], {
|
|
39
|
+
source: field.source,
|
|
40
|
+
target: getSchema(field.source.resource)
|
|
41
|
+
});
|
|
42
|
+
}, ...ngDevMode ? [{ debugName: "opciones" }] : /* istanbul ignore next */ []);
|
|
43
|
+
cargando = computed(() => this.claveFuente() !== void 0 && this.fuenteResource.status() === "loading", ...ngDevMode ? [{ debugName: "cargando" }] : /* istanbul ignore next */ []);
|
|
44
|
+
fallo = computed(() => this.claveFuente() !== void 0 && this.fuenteResource.status() === "error", ...ngDevMode ? [{ debugName: "fallo" }] : /* istanbul ignore next */ []);
|
|
45
|
+
toggle(option) {
|
|
46
|
+
if (this.disabled()) return;
|
|
47
|
+
this.value.update((current) => current.includes(option.value) ? current.filter((item) => item !== option.value) : [...current, option.value]);
|
|
48
|
+
}
|
|
49
|
+
remove(item) {
|
|
50
|
+
if (this.disabled()) return;
|
|
51
|
+
this.value.update((current) => current.filter((value) => value !== item));
|
|
52
|
+
}
|
|
53
|
+
isSelected(item) {
|
|
54
|
+
return this.value().includes(item);
|
|
55
|
+
}
|
|
56
|
+
labelOf(item) {
|
|
57
|
+
return this.opciones().find((option) => option.value === item)?.label ?? item;
|
|
58
|
+
}
|
|
59
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
60
|
+
minVersion: "12.0.0",
|
|
61
|
+
version: "22.2.3",
|
|
62
|
+
ngImport: i0,
|
|
63
|
+
type: FieldMultiselect,
|
|
64
|
+
deps: [],
|
|
65
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
66
|
+
});
|
|
67
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
68
|
+
minVersion: "17.0.0",
|
|
69
|
+
version: "22.2.3",
|
|
70
|
+
type: FieldMultiselect,
|
|
71
|
+
isStandalone: true,
|
|
72
|
+
selector: "app-field-multiselect",
|
|
73
|
+
inputs: {
|
|
74
|
+
field: {
|
|
75
|
+
classPropertyName: "field",
|
|
76
|
+
publicName: "field",
|
|
77
|
+
isSignal: true,
|
|
78
|
+
isRequired: true,
|
|
79
|
+
transformFunction: null
|
|
80
|
+
},
|
|
81
|
+
tree: {
|
|
82
|
+
classPropertyName: "tree",
|
|
83
|
+
publicName: "tree",
|
|
84
|
+
isSignal: true,
|
|
85
|
+
isRequired: false,
|
|
86
|
+
transformFunction: null
|
|
87
|
+
},
|
|
88
|
+
value: {
|
|
89
|
+
classPropertyName: "value",
|
|
90
|
+
publicName: "value",
|
|
91
|
+
isSignal: true,
|
|
92
|
+
isRequired: true,
|
|
93
|
+
transformFunction: null
|
|
94
|
+
},
|
|
95
|
+
disabled: {
|
|
96
|
+
classPropertyName: "disabled",
|
|
97
|
+
publicName: "disabled",
|
|
98
|
+
isSignal: true,
|
|
99
|
+
isRequired: false,
|
|
100
|
+
transformFunction: null
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
outputs: { value: "valueChange" },
|
|
104
|
+
ngImport: i0,
|
|
105
|
+
template: `
|
|
106
|
+
<div class="space-y-2">
|
|
107
|
+
@if (fallo()) {
|
|
108
|
+
<p class="text-xs text-danger" role="alert">No se pudieron cargar las opciones.</p>
|
|
109
|
+
} @else if (cargando()) {
|
|
110
|
+
<p class="text-xs text-neutral" role="status">Cargando opciones…</p>
|
|
111
|
+
}
|
|
112
|
+
@if (value().length > 0) {
|
|
113
|
+
<div class="flex flex-wrap gap-1.5" data-testid="multiselect-chips">
|
|
114
|
+
@for (item of value(); track item) {
|
|
115
|
+
<span
|
|
116
|
+
class="inline-flex items-center rounded-full bg-primary/10 px-2.5 py-1 text-xs text-primary"
|
|
117
|
+
>
|
|
118
|
+
{{ labelOf(item) }}
|
|
119
|
+
<button
|
|
120
|
+
type="button"
|
|
121
|
+
class="rounded-full px-0.5 hover:text-danger"
|
|
122
|
+
[attr.aria-label]="'Quitar ' + labelOf(item)"
|
|
123
|
+
[disabled]="disabled()"
|
|
124
|
+
(click)="remove(item)"
|
|
125
|
+
>
|
|
126
|
+
<svg lucideX size="14" />
|
|
127
|
+
</button>
|
|
128
|
+
</span>
|
|
129
|
+
}
|
|
130
|
+
</div>
|
|
131
|
+
}
|
|
132
|
+
<div class="flex flex-wrap gap-1.5">
|
|
133
|
+
@for (option of opciones(); track option.value) {
|
|
134
|
+
@if (!isSelected(option.value)) {
|
|
135
|
+
<button
|
|
136
|
+
type="button"
|
|
137
|
+
class="rounded-full border border-neutral/30 px-2.5 py-1 text-xs hover:border-primary disabled:cursor-not-allowed disabled:opacity-50"
|
|
138
|
+
[disabled]="disabled() || (option.disabled ?? false)"
|
|
139
|
+
(click)="toggle(option)"
|
|
140
|
+
>
|
|
141
|
+
{{ option.label }}
|
|
142
|
+
</button>
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
`,
|
|
148
|
+
isInline: true,
|
|
149
|
+
dependencies: [{
|
|
150
|
+
kind: "component",
|
|
151
|
+
type: LucideX,
|
|
152
|
+
selector: "svg[lucideX]"
|
|
153
|
+
}]
|
|
154
|
+
});
|
|
155
|
+
};
|
|
156
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
157
|
+
minVersion: "12.0.0",
|
|
158
|
+
version: "22.2.3",
|
|
159
|
+
ngImport: i0,
|
|
160
|
+
type: FieldMultiselect,
|
|
161
|
+
decorators: [{
|
|
162
|
+
type: Component,
|
|
163
|
+
args: [{
|
|
164
|
+
selector: "app-field-multiselect",
|
|
165
|
+
imports: [LucideX],
|
|
166
|
+
template: `
|
|
167
|
+
<div class="space-y-2">
|
|
168
|
+
@if (fallo()) {
|
|
169
|
+
<p class="text-xs text-danger" role="alert">No se pudieron cargar las opciones.</p>
|
|
170
|
+
} @else if (cargando()) {
|
|
171
|
+
<p class="text-xs text-neutral" role="status">Cargando opciones…</p>
|
|
172
|
+
}
|
|
173
|
+
@if (value().length > 0) {
|
|
174
|
+
<div class="flex flex-wrap gap-1.5" data-testid="multiselect-chips">
|
|
175
|
+
@for (item of value(); track item) {
|
|
176
|
+
<span
|
|
177
|
+
class="inline-flex items-center rounded-full bg-primary/10 px-2.5 py-1 text-xs text-primary"
|
|
178
|
+
>
|
|
179
|
+
{{ labelOf(item) }}
|
|
180
|
+
<button
|
|
181
|
+
type="button"
|
|
182
|
+
class="rounded-full px-0.5 hover:text-danger"
|
|
183
|
+
[attr.aria-label]="'Quitar ' + labelOf(item)"
|
|
184
|
+
[disabled]="disabled()"
|
|
185
|
+
(click)="remove(item)"
|
|
186
|
+
>
|
|
187
|
+
<svg lucideX size="14" />
|
|
188
|
+
</button>
|
|
189
|
+
</span>
|
|
190
|
+
}
|
|
191
|
+
</div>
|
|
192
|
+
}
|
|
193
|
+
<div class="flex flex-wrap gap-1.5">
|
|
194
|
+
@for (option of opciones(); track option.value) {
|
|
195
|
+
@if (!isSelected(option.value)) {
|
|
196
|
+
<button
|
|
197
|
+
type="button"
|
|
198
|
+
class="rounded-full border border-neutral/30 px-2.5 py-1 text-xs hover:border-primary disabled:cursor-not-allowed disabled:opacity-50"
|
|
199
|
+
[disabled]="disabled() || (option.disabled ?? false)"
|
|
200
|
+
(click)="toggle(option)"
|
|
201
|
+
>
|
|
202
|
+
{{ option.label }}
|
|
203
|
+
</button>
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
`
|
|
209
|
+
}]
|
|
210
|
+
}],
|
|
211
|
+
propDecorators: {
|
|
212
|
+
field: [{
|
|
213
|
+
type: i0.Input,
|
|
214
|
+
args: [{
|
|
215
|
+
isSignal: true,
|
|
216
|
+
alias: "field",
|
|
217
|
+
required: true
|
|
218
|
+
}]
|
|
219
|
+
}],
|
|
220
|
+
tree: [{
|
|
221
|
+
type: i0.Input,
|
|
222
|
+
args: [{
|
|
223
|
+
isSignal: true,
|
|
224
|
+
alias: "tree",
|
|
225
|
+
required: false
|
|
226
|
+
}]
|
|
227
|
+
}],
|
|
228
|
+
value: [{
|
|
229
|
+
type: i0.Input,
|
|
230
|
+
args: [{
|
|
231
|
+
isSignal: true,
|
|
232
|
+
alias: "value",
|
|
233
|
+
required: true
|
|
234
|
+
}]
|
|
235
|
+
}, {
|
|
236
|
+
type: i0.Output,
|
|
237
|
+
args: ["valueChange"]
|
|
238
|
+
}],
|
|
239
|
+
disabled: [{
|
|
240
|
+
type: i0.Input,
|
|
241
|
+
args: [{
|
|
242
|
+
isSignal: true,
|
|
243
|
+
alias: "disabled",
|
|
244
|
+
required: false
|
|
245
|
+
}]
|
|
246
|
+
}]
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
export { multiselect_exports as n, FieldMultiselect as t };
|
|
250
|
+
|
|
251
|
+
//# sourceMappingURL=tinya-code-gas-admin-ui-multiselect-CuWwAfdY.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tinya-code-gas-admin-ui-multiselect-CuWwAfdY.mjs","names":[],"sources":["../../../projects/gas-admin-ui/src/lib/fields/multiselect/multiselect.ts"],"sourcesContent":["import { Component, computed, inject, input, model, resource } from '@angular/core';\nimport { LucideX } from '@lucide/angular';\nimport type { FormValueControl } from '@angular/forms/signals';\n\nimport type { MultiselectField, SelectOption } from '../../core/models/schema.model';\nimport { DataSourceService, dataSourceKey } from '../../core/services/data-source.service';\nimport { optionsFromRows } from '../../core/utils/source-options';\nimport { getSchema } from '../../core/registry/schema-catalog';\nimport type { RootTree } from '../field-node';\n\n/**\n * Selección múltiple con chips (base.md §5.1). `<select multiple>` no está\n * soportado por `[formField]`, así que es un control propio que cumple el\n * contrato `FormValueControl<string[]>`: el nodo llega desde el host con\n * `[formField]` y el valor se sincroniza por `model()`.\n *\n * Opciones: estáticas (`options`) o una fuente declarada (`source`), con la\n * misma regla XOR que el `select` y el mismo fetcher (F8 · R6.5). `tree`\n * existe para resolver `{campo}` en `source.params` con el registro del\n * formulario — sin él un multiselect con parámetros quedaría con el mismo\n * nombre de opción y otra regla que el select.\n */\n@Component({\n selector: 'app-field-multiselect',\n imports: [LucideX],\n template: `\n <div class=\"space-y-2\">\n @if (fallo()) {\n <p class=\"text-xs text-danger\" role=\"alert\">No se pudieron cargar las opciones.</p>\n } @else if (cargando()) {\n <p class=\"text-xs text-neutral\" role=\"status\">Cargando opciones…</p>\n }\n @if (value().length > 0) {\n <div class=\"flex flex-wrap gap-1.5\" data-testid=\"multiselect-chips\">\n @for (item of value(); track item) {\n <span\n class=\"inline-flex items-center rounded-full bg-primary/10 px-2.5 py-1 text-xs text-primary\"\n >\n {{ labelOf(item) }}\n <button\n type=\"button\"\n class=\"rounded-full px-0.5 hover:text-danger\"\n [attr.aria-label]=\"'Quitar ' + labelOf(item)\"\n [disabled]=\"disabled()\"\n (click)=\"remove(item)\"\n >\n <svg lucideX size=\"14\" />\n </button>\n </span>\n }\n </div>\n }\n <div class=\"flex flex-wrap gap-1.5\">\n @for (option of opciones(); track option.value) {\n @if (!isSelected(option.value)) {\n <button\n type=\"button\"\n class=\"rounded-full border border-neutral/30 px-2.5 py-1 text-xs hover:border-primary disabled:cursor-not-allowed disabled:opacity-50\"\n [disabled]=\"disabled() || (option.disabled ?? false)\"\n (click)=\"toggle(option)\"\n >\n {{ option.label }}\n </button>\n }\n }\n </div>\n </div>\n `,\n})\nexport class FieldMultiselect implements FormValueControl<string[]> {\n readonly field = input.required<MultiselectField>();\n\n /** Registro del formulario, sólo para resolver `{campo}` en `source.params`. */\n readonly tree = input<RootTree>();\n\n /** Sincronizado por el directive `FormField` del host. */\n readonly value = model.required<string[]>();\n readonly disabled = input(false);\n\n private readonly ds = inject(DataSourceService);\n\n private readonly registro = computed<Record<string, unknown> | undefined>(() => {\n const source = this.field().source;\n const tree = this.tree();\n if (source === undefined || source.params === undefined || tree === undefined) return undefined;\n return tree().value();\n });\n\n /** `undefined` sin fuente ⇒ `resource` queda idle y jamás llama al loader. */\n private readonly claveFuente = computed(() => {\n const source = this.field().source;\n return source === undefined ? undefined : dataSourceKey(source, this.registro());\n });\n\n private readonly fuenteResource = resource({\n params: () => this.claveFuente(),\n loader: async () => {\n const source = this.field().source;\n if (source === undefined) return [];\n return this.ds.rows(source, this.registro());\n },\n });\n\n /** Estáticas del schema o filas de la fuente declarada (F8 · R6.5). */\n protected readonly opciones = computed<SelectOption[]>(() => {\n const field = this.field();\n if (field.source === undefined) return field.options ?? [];\n // `value()` del resource TIRA en estado error (contract de Angular):\n // se mira el estado antes de leerlo, o el render rompe en vez de\n // pintar el aviso de fallo.\n if (this.fuenteResource.status() === 'error') return [];\n return optionsFromRows(this.fuenteResource.value() ?? [], {\n source: field.source,\n target: getSchema(field.source.resource),\n });\n });\n\n /** Sólo aplica con `source`: una lista estática no tiene vuelta que esperar. */\n protected readonly cargando = computed(\n () => this.claveFuente() !== undefined && this.fuenteResource.status() === 'loading',\n );\n\n protected readonly fallo = computed(\n () => this.claveFuente() !== undefined && this.fuenteResource.status() === 'error',\n );\n\n protected toggle(option: SelectOption): void {\n if (this.disabled()) {\n return;\n }\n this.value.update((current) =>\n current.includes(option.value)\n ? current.filter((item) => item !== option.value)\n : [...current, option.value],\n );\n }\n\n protected remove(item: string): void {\n if (this.disabled()) {\n return;\n }\n this.value.update((current) => current.filter((value) => value !== item));\n }\n\n protected isSelected(item: string): boolean {\n return this.value().includes(item);\n }\n\n protected labelOf(item: string): string {\n return this.opciones().find((option) => option.value === item)?.label ?? item;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { Service, signal } from "@angular/core";
|
|
3
|
+
var NotificationService = class NotificationService {
|
|
4
|
+
toasts = signal([], ...ngDevMode ? [{ debugName: "toasts" }] : /* istanbul ignore next */ []);
|
|
5
|
+
confirmation = signal(null, ...ngDevMode ? [{ debugName: "confirmation" }] : /* istanbul ignore next */ []);
|
|
6
|
+
nextId = 1;
|
|
7
|
+
pendingResolve = null;
|
|
8
|
+
success(message) {
|
|
9
|
+
this.push("success", message);
|
|
10
|
+
}
|
|
11
|
+
error(message) {
|
|
12
|
+
this.push("error", message);
|
|
13
|
+
}
|
|
14
|
+
info(message) {
|
|
15
|
+
this.push("info", message);
|
|
16
|
+
}
|
|
17
|
+
dismiss(id) {
|
|
18
|
+
this.toasts.update((toasts) => toasts.filter((toast) => toast.id !== id));
|
|
19
|
+
}
|
|
20
|
+
confirm(options) {
|
|
21
|
+
this.pendingResolve?.(false);
|
|
22
|
+
this.confirmation.set(options);
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
this.pendingResolve = resolve;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
resolveConfirmation(accepted) {
|
|
28
|
+
this.confirmation.set(null);
|
|
29
|
+
const resolve = this.pendingResolve;
|
|
30
|
+
this.pendingResolve = null;
|
|
31
|
+
resolve?.(accepted);
|
|
32
|
+
}
|
|
33
|
+
push(kind, message) {
|
|
34
|
+
const id = this.nextId++;
|
|
35
|
+
this.toasts.update((toasts) => [...toasts, {
|
|
36
|
+
id,
|
|
37
|
+
kind,
|
|
38
|
+
message
|
|
39
|
+
}]);
|
|
40
|
+
if (kind !== "error") setTimeout(() => this.dismiss(id), 4e3);
|
|
41
|
+
}
|
|
42
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
43
|
+
minVersion: "12.0.0",
|
|
44
|
+
version: "22.2.3",
|
|
45
|
+
ngImport: i0,
|
|
46
|
+
type: NotificationService,
|
|
47
|
+
deps: [],
|
|
48
|
+
target: i0.ɵɵFactoryTarget.Service
|
|
49
|
+
});
|
|
50
|
+
static ɵprov = i0.ɵɵngDeclareService({
|
|
51
|
+
minVersion: "22.0.0",
|
|
52
|
+
version: "22.2.3",
|
|
53
|
+
ngImport: i0,
|
|
54
|
+
type: NotificationService
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
58
|
+
minVersion: "12.0.0",
|
|
59
|
+
version: "22.2.3",
|
|
60
|
+
ngImport: i0,
|
|
61
|
+
type: NotificationService,
|
|
62
|
+
decorators: [{ type: Service }]
|
|
63
|
+
});
|
|
64
|
+
export { NotificationService as t };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs","names":[],"sources":["../../../projects/gas-admin-ui/src/lib/core/services/notification.service.ts"],"sourcesContent":["import { Service, signal } from '@angular/core';\n\nexport type ToastKind = 'success' | 'error' | 'info';\n\nexport interface Toast {\n id: number;\n kind: ToastKind;\n message: string;\n}\n\nexport interface ConfirmOptions {\n title: string;\n message: string;\n confirmLabel?: string;\n cancelLabel?: string;\n}\n\n/**\n * Notificaciones de la app: toasts (señales, se renderizan en `app-toast`,\n * Fase 5) y un diálogo de confirmación con respuesta como `Promise`\n * (base.md §10: borrado con confirmación, aviso de cambios sin guardar).\n */\n@Service()\nexport class NotificationService {\n readonly toasts = signal<Toast[]>([]);\n /** Confirmación en curso; `null` = sin diálogo. */\n readonly confirmation = signal<ConfirmOptions | null>(null);\n\n private nextId = 1;\n private pendingResolve: ((accepted: boolean) => void) | null = null;\n\n success(message: string): void {\n this.push('success', message);\n }\n\n error(message: string): void {\n this.push('error', message);\n }\n\n info(message: string): void {\n this.push('info', message);\n }\n\n dismiss(id: number): void {\n this.toasts.update((toasts) => toasts.filter((toast) => toast.id !== id));\n }\n\n /** Abre el diálogo de confirmación y espera la respuesta del usuario. */\n confirm(options: ConfirmOptions): Promise<boolean> {\n // Solo una confirmación a la vez: la anterior se responde como rechazo.\n this.pendingResolve?.(false);\n this.confirmation.set(options);\n return new Promise<boolean>((resolve) => {\n this.pendingResolve = resolve;\n });\n }\n\n /** Resuelve la confirmación pendiente (lo llama el componente de diálogo, Fase 5). */\n resolveConfirmation(accepted: boolean): void {\n this.confirmation.set(null);\n const resolve = this.pendingResolve;\n this.pendingResolve = null;\n resolve?.(accepted);\n }\n\n private push(kind: ToastKind, message: string): void {\n const id = this.nextId++;\n this.toasts.update((toasts) => [...toasts, { id, kind, message }]);\n if (kind !== 'error') {\n setTimeout(() => this.dismiss(id), 4000);\n }\n }\n}\n"],"mappings":";;AAuBA,IAAa,sBAAb,MAAa,oBAAmB;CACrB,SAAS,OAAgB,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAE5B,eAAe,OAA8B,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAEnD,SAAS;CACT,iBAAuD;CAE/D,QAAQ,SAAe;EACrB,KAAK,KAAK,WAAW,OAAO;CAC9B;CAEA,MAAM,SAAe;EACnB,KAAK,KAAK,SAAS,OAAO;CAC5B;CAEA,KAAK,SAAe;EAClB,KAAK,KAAK,QAAQ,OAAO;CAC3B;CAEA,QAAQ,IAAU;EAChB,KAAK,OAAO,QAAQ,WAAW,OAAO,QAAQ,UAAU,MAAM,OAAO,EAAE,CAAC;CAC1E;CAGA,QAAQ,SAAuB;EAE7B,KAAK,iBAAiB,KAAK;EAC3B,KAAK,aAAa,IAAI,OAAO;EAC7B,OAAO,IAAI,SAAkB,YAAW;GACtC,KAAK,iBAAiB;EACxB,CAAC;CACH;CAGA,oBAAoB,UAAiB;EACnC,KAAK,aAAa,IAAI,IAAI;EAC1B,MAAM,UAAU,KAAK;EACrB,KAAK,iBAAiB;EACtB,UAAU,QAAQ;CACpB;CAEQ,KAAK,MAAiB,SAAe;EAC3C,MAAM,KAAK,KAAK;EAChB,KAAK,OAAO,QAAQ,WAAW,CAAC,GAAG,QAAQ;GAAE;GAAI;GAAM;EAAO,CAAE,CAAC;EACjE,IAAI,SAAS,SACX,iBAAiB,KAAK,QAAQ,EAAE,GAAG,GAAI;CAE3C;CAhDW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAmB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAnB,OAAA,QAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;CAAmB,CAAA;;AAAnB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAmB,YAAA,CAAA,EAD/B,MAAA,QAAA,CAAA"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { n as FieldAria } from "./tinya-code-gas-admin-ui-field-aria-BD1Wiggc.mjs";
|
|
2
|
+
import { t as childTree } from "./tinya-code-gas-admin-ui-field-node-CIK6KNN_.mjs";
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import { Component, computed, input } from "@angular/core";
|
|
5
|
+
import { FormField } from "@angular/forms/signals";
|
|
6
|
+
var FieldNumber = class FieldNumber {
|
|
7
|
+
field = input.required(...ngDevMode ? [{ debugName: "field" }] : /* istanbul ignore next */ []);
|
|
8
|
+
tree = input.required(...ngDevMode ? [{ debugName: "tree" }] : /* istanbul ignore next */ []);
|
|
9
|
+
node = computed(() => childTree(this.tree(), this.field().key), ...ngDevMode ? [{ debugName: "node" }] : /* istanbul ignore next */ []);
|
|
10
|
+
state = computed(() => this.node()(), ...ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []);
|
|
11
|
+
stepAttr = computed(() => {
|
|
12
|
+
const field = this.field();
|
|
13
|
+
if (field.step !== void 0) return field.step;
|
|
14
|
+
return field.decimals !== void 0 ? Math.pow(10, -field.decimals) : null;
|
|
15
|
+
}, ...ngDevMode ? [{ debugName: "stepAttr" }] : /* istanbul ignore next */ []);
|
|
16
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
17
|
+
minVersion: "12.0.0",
|
|
18
|
+
version: "22.2.3",
|
|
19
|
+
ngImport: i0,
|
|
20
|
+
type: FieldNumber,
|
|
21
|
+
deps: [],
|
|
22
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
23
|
+
});
|
|
24
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
25
|
+
minVersion: "17.1.0",
|
|
26
|
+
version: "22.2.3",
|
|
27
|
+
type: FieldNumber,
|
|
28
|
+
isStandalone: true,
|
|
29
|
+
selector: "app-field-number",
|
|
30
|
+
inputs: {
|
|
31
|
+
field: {
|
|
32
|
+
classPropertyName: "field",
|
|
33
|
+
publicName: "field",
|
|
34
|
+
isSignal: true,
|
|
35
|
+
isRequired: true,
|
|
36
|
+
transformFunction: null
|
|
37
|
+
},
|
|
38
|
+
tree: {
|
|
39
|
+
classPropertyName: "tree",
|
|
40
|
+
publicName: "tree",
|
|
41
|
+
isSignal: true,
|
|
42
|
+
isRequired: true,
|
|
43
|
+
transformFunction: null
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
ngImport: i0,
|
|
47
|
+
template: `
|
|
48
|
+
<input
|
|
49
|
+
type="number"
|
|
50
|
+
class="field-input"
|
|
51
|
+
[id]="state().name()"
|
|
52
|
+
[formField]="node()"
|
|
53
|
+
[step]="stepAttr()"
|
|
54
|
+
[placeholder]="field().placeholder ?? ''"
|
|
55
|
+
/>
|
|
56
|
+
`,
|
|
57
|
+
isInline: true,
|
|
58
|
+
dependencies: [{
|
|
59
|
+
kind: "directive",
|
|
60
|
+
type: FieldAria,
|
|
61
|
+
selector: "input[id], select[id], textarea[id], output[id]"
|
|
62
|
+
}, {
|
|
63
|
+
kind: "directive",
|
|
64
|
+
type: FormField,
|
|
65
|
+
selector: "[formField]",
|
|
66
|
+
inputs: ["formField"],
|
|
67
|
+
exportAs: ["formField"]
|
|
68
|
+
}]
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
72
|
+
minVersion: "12.0.0",
|
|
73
|
+
version: "22.2.3",
|
|
74
|
+
ngImport: i0,
|
|
75
|
+
type: FieldNumber,
|
|
76
|
+
decorators: [{
|
|
77
|
+
type: Component,
|
|
78
|
+
args: [{
|
|
79
|
+
selector: "app-field-number",
|
|
80
|
+
imports: [FieldAria, FormField],
|
|
81
|
+
template: `
|
|
82
|
+
<input
|
|
83
|
+
type="number"
|
|
84
|
+
class="field-input"
|
|
85
|
+
[id]="state().name()"
|
|
86
|
+
[formField]="node()"
|
|
87
|
+
[step]="stepAttr()"
|
|
88
|
+
[placeholder]="field().placeholder ?? ''"
|
|
89
|
+
/>
|
|
90
|
+
`
|
|
91
|
+
}]
|
|
92
|
+
}],
|
|
93
|
+
propDecorators: {
|
|
94
|
+
field: [{
|
|
95
|
+
type: i0.Input,
|
|
96
|
+
args: [{
|
|
97
|
+
isSignal: true,
|
|
98
|
+
alias: "field",
|
|
99
|
+
required: true
|
|
100
|
+
}]
|
|
101
|
+
}],
|
|
102
|
+
tree: [{
|
|
103
|
+
type: i0.Input,
|
|
104
|
+
args: [{
|
|
105
|
+
isSignal: true,
|
|
106
|
+
alias: "tree",
|
|
107
|
+
required: true
|
|
108
|
+
}]
|
|
109
|
+
}]
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
export { FieldNumber };
|
|
113
|
+
|
|
114
|
+
//# sourceMappingURL=tinya-code-gas-admin-ui-number-JNr7glc8.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tinya-code-gas-admin-ui-number-JNr7glc8.mjs","names":[],"sources":["../../../projects/gas-admin-ui/src/lib/fields/number/number.ts"],"sourcesContent":["import { Component, computed, input } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\n\nimport type { NumberField } from '../../core/models/schema.model';\nimport { FieldAria } from '../field-aria';\nimport { childTree, type RootTree } from '../field-node';\n\n/**\n * Input numérico (base.md §5.1). `step` sale del tipo o de `decimals`;\n * `min`/`max` los gestiona `FormField` desde las reglas (Fase 10).\n */\n@Component({\n selector: 'app-field-number',\n imports: [FieldAria, FormField],\n template: `\n <input\n type=\"number\"\n class=\"field-input\"\n [id]=\"state().name()\"\n [formField]=\"node()\"\n [step]=\"stepAttr()\"\n [placeholder]=\"field().placeholder ?? ''\"\n />\n `,\n})\nexport class FieldNumber {\n readonly field = input.required<NumberField>();\n readonly tree = input.required<RootTree>();\n\n protected readonly node = computed(() => childTree<number>(this.tree(), this.field().key));\n protected readonly state = computed(() => this.node()());\n\n protected readonly stepAttr = computed<number | null>(() => {\n const field = this.field();\n if (field.step !== undefined) {\n return field.step;\n }\n return field.decimals !== undefined ? Math.pow(10, -field.decimals) : null;\n });\n}\n"],"mappings":";;;;;AAyBA,IAAa,cAAb,MAAa,YAAW;CACb,QAAQ,MAAM,SAAuB,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CACrC,OAAO,MAAM,SAAoB,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAEvB,OAAO,eAAe,UAAkB,KAAK,KAAI,GAAI,KAAK,MAAK,CAAE,CAAC,GAAG,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CACvE,QAAQ,eAAe,KAAK,KAAI,CAAE,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAErC,WAAW,eAA6B;EACzD,MAAM,QAAQ,KAAK,MAAK;EACxB,IAAI,MAAM,SAAS,QACjB,OAAO,MAAM;EAEf,OAAO,MAAM,aAAa,SAAY,KAAK,IAAI,IAAI,CAAC,MAAM,QAAQ,IAAI;CACxE,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAbS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAW,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAX,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAW,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,MAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,UAAA;EAAA,UAXZ;;;;;;;;;;EAST,UAAA;EAAA,cAAA,CAAA;GAAA,MAAA;GAAA,MAVS;GAAS,UAAA;EAAA,GAAA;GAAA,MAAA;GAAA,MAAE;GAAS,UAAA;GAAA,QAAA,CAAA,WAAA;GAAA,UAAA,CAAA,WAAA;EAAA,CAAA;CAAA,CAAA;;AAYnB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAW,YAAA,CAAA;EAdvB,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,SAAS,CAAC,WAAW,SAAS;GAC9B,UAAU;;;;;;;;;;EAUX,CAAA"}
|