codexly-ui 0.14.4 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/codexly-ui.mjs +575 -53
- package/fesm2022/codexly-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/codexly-ui.d.ts +171 -19
package/fesm2022/codexly-ui.mjs
CHANGED
|
@@ -10,6 +10,8 @@ import * as i1 from '@angular/cdk/overlay';
|
|
|
10
10
|
import { ScrollStrategyOptions, OverlayModule } from '@angular/cdk/overlay';
|
|
11
11
|
import { ScrollingModule, CdkScrollable } from '@angular/cdk/scrolling';
|
|
12
12
|
import { Router, NavigationEnd, RouterLink, RouterLinkActive } from '@angular/router';
|
|
13
|
+
import * as i1$2 from '@angular/cdk/drag-drop';
|
|
14
|
+
import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
|
|
13
15
|
|
|
14
16
|
// ── Parse 'red' | 'red-500' → { color, shade } ───────────────────────────────
|
|
15
17
|
function parseColorInput(input) {
|
|
@@ -2147,6 +2149,9 @@ class ClxProgressBarComponent {
|
|
|
2147
2149
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
2148
2150
|
showValue = input(false, ...(ngDevMode ? [{ debugName: "showValue" }] : /* istanbul ignore next */ []));
|
|
2149
2151
|
valueFormat = input('percent', ...(ngDevMode ? [{ debugName: "valueFormat" }] : /* istanbul ignore next */ []));
|
|
2152
|
+
/** Only read when variant()==='segmented' — ignores value()/max() entirely, each segment's
|
|
2153
|
+
* width is its own value as a fraction of the segments' combined total. */
|
|
2154
|
+
segments = input([], ...(ngDevMode ? [{ debugName: "segments" }] : /* istanbul ignore next */ []));
|
|
2150
2155
|
_pct = computed(() => {
|
|
2151
2156
|
const m = this.max();
|
|
2152
2157
|
if (!m)
|
|
@@ -2177,8 +2182,17 @@ class ClxProgressBarComponent {
|
|
|
2177
2182
|
cls += ' clx-pb-striped';
|
|
2178
2183
|
return cls;
|
|
2179
2184
|
}, ...(ngDevMode ? [{ debugName: "_fillCls" }] : /* istanbul ignore next */ []));
|
|
2185
|
+
_segmentPcts = computed(() => {
|
|
2186
|
+
const segs = this.segments();
|
|
2187
|
+
const total = segs.reduce((sum, s) => sum + s.value, 0) || 1;
|
|
2188
|
+
return segs.map(s => ({
|
|
2189
|
+
pct: (s.value / total) * 100,
|
|
2190
|
+
cls: resolveColor(s.color).bg,
|
|
2191
|
+
label: s.label,
|
|
2192
|
+
}));
|
|
2193
|
+
}, ...(ngDevMode ? [{ debugName: "_segmentPcts" }] : /* istanbul ignore next */ []));
|
|
2180
2194
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2181
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxProgressBarComponent, isStandalone: true, selector: "clx-progress-bar", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, showValue: { classPropertyName: "showValue", publicName: "showValue", isSignal: true, isRequired: false, transformFunction: null }, valueFormat: { classPropertyName: "valueFormat", publicName: "valueFormat", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "flex flex-col gap-1.5 w-full" }, ngImport: i0, template: `
|
|
2195
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxProgressBarComponent, isStandalone: true, selector: "clx-progress-bar", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, showValue: { classPropertyName: "showValue", publicName: "showValue", isSignal: true, isRequired: false, transformFunction: null }, valueFormat: { classPropertyName: "valueFormat", publicName: "valueFormat", isSignal: true, isRequired: false, transformFunction: null }, segments: { classPropertyName: "segments", publicName: "segments", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "flex flex-col gap-1.5 w-full" }, ngImport: i0, template: `
|
|
2182
2196
|
@if (label() || showValue()) {
|
|
2183
2197
|
<div class="flex items-center justify-between gap-2">
|
|
2184
2198
|
@if (label()) {
|
|
@@ -2192,23 +2206,42 @@ class ClxProgressBarComponent {
|
|
|
2192
2206
|
</div>
|
|
2193
2207
|
}
|
|
2194
2208
|
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
[class]="_trackH()"
|
|
2199
|
-
role="progressbar"
|
|
2200
|
-
[attr.aria-valuenow]="variant() === 'indeterminate' ? null : value()"
|
|
2201
|
-
[attr.aria-valuemin]="0"
|
|
2202
|
-
[attr.aria-valuemax]="max()"
|
|
2203
|
-
[attr.aria-label]="label() || null">
|
|
2204
|
-
|
|
2205
|
-
<!-- Fill -->
|
|
2209
|
+
@if (variant() === 'segmented') {
|
|
2210
|
+
<!-- Track: one flex child per segment, own color each, widths normalized to the segments'
|
|
2211
|
+
own value sum — independent of value()/max(), which this variant ignores. -->
|
|
2206
2212
|
<div
|
|
2207
|
-
class="
|
|
2208
|
-
[class]="
|
|
2209
|
-
|
|
2213
|
+
class="w-full flex overflow-hidden rounded-full bg-clx-surface-2 gap-0.5"
|
|
2214
|
+
[class]="_trackH()"
|
|
2215
|
+
role="img"
|
|
2216
|
+
[attr.aria-label]="label() || null">
|
|
2217
|
+
@for (seg of _segmentPcts(); track $index) {
|
|
2218
|
+
<div
|
|
2219
|
+
class="h-full first:rounded-l-full last:rounded-r-full"
|
|
2220
|
+
[class]="seg.cls"
|
|
2221
|
+
[style.width.%]="seg.pct"
|
|
2222
|
+
[attr.title]="seg.label">
|
|
2223
|
+
</div>
|
|
2224
|
+
}
|
|
2210
2225
|
</div>
|
|
2211
|
-
|
|
2226
|
+
} @else {
|
|
2227
|
+
<!-- Track -->
|
|
2228
|
+
<div
|
|
2229
|
+
class="w-full overflow-hidden rounded-full bg-clx-surface-2"
|
|
2230
|
+
[class]="_trackH()"
|
|
2231
|
+
role="progressbar"
|
|
2232
|
+
[attr.aria-valuenow]="variant() === 'indeterminate' ? null : value()"
|
|
2233
|
+
[attr.aria-valuemin]="0"
|
|
2234
|
+
[attr.aria-valuemax]="max()"
|
|
2235
|
+
[attr.aria-label]="label() || null">
|
|
2236
|
+
|
|
2237
|
+
<!-- Fill -->
|
|
2238
|
+
<div
|
|
2239
|
+
class="h-full rounded-full transition-[width,background-color] duration-500 ease-out"
|
|
2240
|
+
[class]="_fillCls()"
|
|
2241
|
+
[style.width]="variant() === 'indeterminate' ? '40%' : _pct() + '%'">
|
|
2242
|
+
</div>
|
|
2243
|
+
</div>
|
|
2244
|
+
}
|
|
2212
2245
|
`, isInline: true, styles: ["@keyframes clx-pb-indeterminate{0%{transform:translate(-100%) scaleX(.4)}40%{transform:translate(0) scaleX(.4)}to{transform:translate(100%) scaleX(.4)}}.clx-pb-indeterminate{animation:clx-pb-indeterminate 1.4s ease-in-out infinite}@keyframes clx-pb-stripe{0%{background-position:1rem 0}to{background-position:0 0}}.clx-pb-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.18) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.18) 50%,rgba(255,255,255,.18) 75%,transparent 75%,transparent);background-size:1rem 1rem;animation:clx-pb-stripe 1s linear infinite}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2213
2246
|
}
|
|
2214
2247
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxProgressBarComponent, decorators: [{
|
|
@@ -2227,25 +2260,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
2227
2260
|
</div>
|
|
2228
2261
|
}
|
|
2229
2262
|
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
[class]="_trackH()"
|
|
2234
|
-
role="progressbar"
|
|
2235
|
-
[attr.aria-valuenow]="variant() === 'indeterminate' ? null : value()"
|
|
2236
|
-
[attr.aria-valuemin]="0"
|
|
2237
|
-
[attr.aria-valuemax]="max()"
|
|
2238
|
-
[attr.aria-label]="label() || null">
|
|
2239
|
-
|
|
2240
|
-
<!-- Fill -->
|
|
2263
|
+
@if (variant() === 'segmented') {
|
|
2264
|
+
<!-- Track: one flex child per segment, own color each, widths normalized to the segments'
|
|
2265
|
+
own value sum — independent of value()/max(), which this variant ignores. -->
|
|
2241
2266
|
<div
|
|
2242
|
-
class="
|
|
2243
|
-
[class]="
|
|
2244
|
-
|
|
2267
|
+
class="w-full flex overflow-hidden rounded-full bg-clx-surface-2 gap-0.5"
|
|
2268
|
+
[class]="_trackH()"
|
|
2269
|
+
role="img"
|
|
2270
|
+
[attr.aria-label]="label() || null">
|
|
2271
|
+
@for (seg of _segmentPcts(); track $index) {
|
|
2272
|
+
<div
|
|
2273
|
+
class="h-full first:rounded-l-full last:rounded-r-full"
|
|
2274
|
+
[class]="seg.cls"
|
|
2275
|
+
[style.width.%]="seg.pct"
|
|
2276
|
+
[attr.title]="seg.label">
|
|
2277
|
+
</div>
|
|
2278
|
+
}
|
|
2245
2279
|
</div>
|
|
2246
|
-
|
|
2280
|
+
} @else {
|
|
2281
|
+
<!-- Track -->
|
|
2282
|
+
<div
|
|
2283
|
+
class="w-full overflow-hidden rounded-full bg-clx-surface-2"
|
|
2284
|
+
[class]="_trackH()"
|
|
2285
|
+
role="progressbar"
|
|
2286
|
+
[attr.aria-valuenow]="variant() === 'indeterminate' ? null : value()"
|
|
2287
|
+
[attr.aria-valuemin]="0"
|
|
2288
|
+
[attr.aria-valuemax]="max()"
|
|
2289
|
+
[attr.aria-label]="label() || null">
|
|
2290
|
+
|
|
2291
|
+
<!-- Fill -->
|
|
2292
|
+
<div
|
|
2293
|
+
class="h-full rounded-full transition-[width,background-color] duration-500 ease-out"
|
|
2294
|
+
[class]="_fillCls()"
|
|
2295
|
+
[style.width]="variant() === 'indeterminate' ? '40%' : _pct() + '%'">
|
|
2296
|
+
</div>
|
|
2297
|
+
</div>
|
|
2298
|
+
}
|
|
2247
2299
|
`, styles: ["@keyframes clx-pb-indeterminate{0%{transform:translate(-100%) scaleX(.4)}40%{transform:translate(0) scaleX(.4)}to{transform:translate(100%) scaleX(.4)}}.clx-pb-indeterminate{animation:clx-pb-indeterminate 1.4s ease-in-out infinite}@keyframes clx-pb-stripe{0%{background-position:1rem 0}to{background-position:0 0}}.clx-pb-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.18) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.18) 50%,rgba(255,255,255,.18) 75%,transparent 75%,transparent);background-size:1rem 1rem;animation:clx-pb-stripe 1s linear infinite}\n"] }]
|
|
2248
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], showValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValue", required: false }] }], valueFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueFormat", required: false }] }] } });
|
|
2300
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], showValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValue", required: false }] }], valueFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueFormat", required: false }] }], segments: [{ type: i0.Input, args: [{ isSignal: true, alias: "segments", required: false }] }] } });
|
|
2249
2301
|
|
|
2250
2302
|
class ClxRatingComponent {
|
|
2251
2303
|
_themeSvc = inject(ClxThemeService);
|
|
@@ -10549,6 +10601,9 @@ class ClxWizardComponent {
|
|
|
10549
10601
|
prevLabel = input('Anterior', ...(ngDevMode ? [{ debugName: "prevLabel" }] : /* istanbul ignore next */ []));
|
|
10550
10602
|
nextLabel = input('Siguiente', ...(ngDevMode ? [{ debugName: "nextLabel" }] : /* istanbul ignore next */ []));
|
|
10551
10603
|
finishLabel = input('Finalizar', ...(ngDevMode ? [{ debugName: "finishLabel" }] : /* istanbul ignore next */ []));
|
|
10604
|
+
/** Shows a spinner on the finish button and disables it — for an async (finish) handler that
|
|
10605
|
+
* takes a moment (an HTTP call), so the consumer doesn't need its own separate loading label. */
|
|
10606
|
+
finishLoading = input(false, ...(ngDevMode ? [{ debugName: "finishLoading" }] : /* istanbul ignore next */ []));
|
|
10552
10607
|
// ── Outputs ────────────────────────────────────────────────────────────────
|
|
10553
10608
|
stepChange = output();
|
|
10554
10609
|
finish = output();
|
|
@@ -10657,7 +10712,7 @@ class ClxWizardComponent {
|
|
|
10657
10712
|
return `${base} border-2 border-clx-border text-clx-text-subtle bg-clx-surface ${ptr}`;
|
|
10658
10713
|
}
|
|
10659
10714
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxWizardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10660
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxWizardComponent, isStandalone: true, selector: "clx-wizard", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, activeTextColor: { classPropertyName: "activeTextColor", publicName: "activeTextColor", isSignal: true, isRequired: false, transformFunction: null }, underlineColor: { classPropertyName: "underlineColor", publicName: "underlineColor", isSignal: true, isRequired: false, transformFunction: null }, stepColor: { classPropertyName: "stepColor", publicName: "stepColor", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, prevLabel: { classPropertyName: "prevLabel", publicName: "prevLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, finishLabel: { classPropertyName: "finishLabel", publicName: "finishLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { stepChange: "stepChange", finish: "finish" }, queries: [{ propertyName: "_stepQuery", predicate: ClxStepComponent }], ngImport: i0, template: `
|
|
10715
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxWizardComponent, isStandalone: true, selector: "clx-wizard", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, activeTextColor: { classPropertyName: "activeTextColor", publicName: "activeTextColor", isSignal: true, isRequired: false, transformFunction: null }, underlineColor: { classPropertyName: "underlineColor", publicName: "underlineColor", isSignal: true, isRequired: false, transformFunction: null }, stepColor: { classPropertyName: "stepColor", publicName: "stepColor", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, prevLabel: { classPropertyName: "prevLabel", publicName: "prevLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, finishLabel: { classPropertyName: "finishLabel", publicName: "finishLabel", isSignal: true, isRequired: false, transformFunction: null }, finishLoading: { classPropertyName: "finishLoading", publicName: "finishLoading", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { stepChange: "stepChange", finish: "finish" }, queries: [{ propertyName: "_stepQuery", predicate: ClxStepComponent }], ngImport: i0, template: `
|
|
10661
10716
|
<div [class]="_rootClass()">
|
|
10662
10717
|
|
|
10663
10718
|
<!-- ══ HORIZONTAL: clx-tabs indicator ═══════════════════════════════ -->
|
|
@@ -10755,7 +10810,8 @@ class ClxWizardComponent {
|
|
|
10755
10810
|
size="sm"
|
|
10756
10811
|
icon="check_circle"
|
|
10757
10812
|
iconPosition="right"
|
|
10758
|
-
[disabled]="!_currentStepValid()"
|
|
10813
|
+
[disabled]="!_currentStepValid() || finishLoading()"
|
|
10814
|
+
[loading]="finishLoading()"
|
|
10759
10815
|
(click)="_onFinish()"
|
|
10760
10816
|
>{{ finishLabel() }}</button>
|
|
10761
10817
|
}
|
|
@@ -10864,7 +10920,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
10864
10920
|
size="sm"
|
|
10865
10921
|
icon="check_circle"
|
|
10866
10922
|
iconPosition="right"
|
|
10867
|
-
[disabled]="!_currentStepValid()"
|
|
10923
|
+
[disabled]="!_currentStepValid() || finishLoading()"
|
|
10924
|
+
[loading]="finishLoading()"
|
|
10868
10925
|
(click)="_onFinish()"
|
|
10869
10926
|
>{{ finishLabel() }}</button>
|
|
10870
10927
|
}
|
|
@@ -10872,7 +10929,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
10872
10929
|
</div>
|
|
10873
10930
|
</div>
|
|
10874
10931
|
`, styles: ["@keyframes clx-wizard-fade-slide{0%{opacity:0;transform:translate(10px)}to{opacity:1;transform:translate(0)}}.clx-wizard-step-enter{animation:clx-wizard-fade-slide .22s cubic-bezier(.4,0,.2,1) both}@keyframes clx-wizard-fill{0%{width:0%}to{width:100%}}.clx-wizard-connector-fill{animation:clx-wizard-fill .3s ease both}clx-step[data-active=false]{display:none}\n"] }]
|
|
10875
|
-
}], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], activeTextColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTextColor", required: false }] }], underlineColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "underlineColor", required: false }] }], stepColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepColor", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], linear: [{ type: i0.Input, args: [{ isSignal: true, alias: "linear", required: false }] }], prevLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "prevLabel", required: false }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: false }] }], finishLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "finishLabel", required: false }] }], stepChange: [{ type: i0.Output, args: ["stepChange"] }], finish: [{ type: i0.Output, args: ["finish"] }], _stepQuery: [{
|
|
10932
|
+
}], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], activeTextColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTextColor", required: false }] }], underlineColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "underlineColor", required: false }] }], stepColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepColor", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], linear: [{ type: i0.Input, args: [{ isSignal: true, alias: "linear", required: false }] }], prevLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "prevLabel", required: false }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: false }] }], finishLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "finishLabel", required: false }] }], finishLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "finishLoading", required: false }] }], stepChange: [{ type: i0.Output, args: ["stepChange"] }], finish: [{ type: i0.Output, args: ["finish"] }], _stepQuery: [{
|
|
10876
10933
|
type: ContentChildren,
|
|
10877
10934
|
args: [ClxStepComponent]
|
|
10878
10935
|
}] } });
|
|
@@ -15892,13 +15949,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
15892
15949
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], retryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "retryLabel", required: false }] }], backLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "backLabel", required: false }] }], errorId: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorId", required: false }] }], retry: [{ type: i0.Output, args: ["retry"] }], back: [{ type: i0.Output, args: ["back"] }] } });
|
|
15893
15950
|
|
|
15894
15951
|
class ClxStatCardComponent {
|
|
15952
|
+
_themeSvc = inject(ClxThemeService);
|
|
15895
15953
|
metric = input.required(...(ngDevMode ? [{ debugName: "metric" }] : /* istanbul ignore next */ []));
|
|
15896
15954
|
chartData = input([30, 45, 28, 60, 40, 70, 55, 80, 50, 90], ...(ngDevMode ? [{ debugName: "chartData" }] : /* istanbul ignore next */ []));
|
|
15897
15955
|
color = input('indigo', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
15898
15956
|
layout = input('horizontal', ...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
15899
15957
|
_hostClass = computed(() => {
|
|
15900
15958
|
const border = resolveColor(this.color()).borderLight;
|
|
15901
|
-
const
|
|
15959
|
+
const radius = resolveContainerRadius(this._themeSvc.config().borderRadius);
|
|
15960
|
+
const base = `bg-clx-surface ${radius} shadow-md border ${border} p-5 w-full overflow-hidden min-w-[260px]`;
|
|
15902
15961
|
return `flex items-center gap-4 ${base}`;
|
|
15903
15962
|
}, ...(ngDevMode ? [{ debugName: "_hostClass" }] : /* istanbul ignore next */ []));
|
|
15904
15963
|
_barHeights = computed(() => {
|
|
@@ -15926,7 +15985,7 @@ class ClxStatCardComponent {
|
|
|
15926
15985
|
}, ...(ngDevMode ? [{ debugName: "_trendArrowIcon" }] : /* istanbul ignore next */ []));
|
|
15927
15986
|
_trendTextClass = computed(() => {
|
|
15928
15987
|
const d = this.metric().trendDirection;
|
|
15929
|
-
return d === 'up' ? 'text-green-500' : d === 'down' ? 'text-red-500' : 'text-
|
|
15988
|
+
return d === 'up' ? 'text-green-500' : d === 'down' ? 'text-red-500' : 'text-clx-text-subtle';
|
|
15930
15989
|
}, ...(ngDevMode ? [{ debugName: "_trendTextClass" }] : /* istanbul ignore next */ []));
|
|
15931
15990
|
_trendIcon = computed(() => {
|
|
15932
15991
|
const d = this.metric().trendDirection;
|
|
@@ -15989,8 +16048,8 @@ class ClxStatCardComponent {
|
|
|
15989
16048
|
|
|
15990
16049
|
<!-- Text block -->
|
|
15991
16050
|
<div class="flex flex-col gap-1 min-w-0 flex-1">
|
|
15992
|
-
<span class="text-sm text-
|
|
15993
|
-
<span class="text-2xl font-semibold text-
|
|
16051
|
+
<span class="text-sm text-clx-text-muted truncate">{{ metric().title }}</span>
|
|
16052
|
+
<span class="text-2xl font-semibold text-clx-text leading-tight">
|
|
15994
16053
|
{{ _formattedValue() }}
|
|
15995
16054
|
</span>
|
|
15996
16055
|
<span clx-badge
|
|
@@ -16026,8 +16085,8 @@ class ClxStatCardComponent {
|
|
|
16026
16085
|
<div class="w-11 h-11 rounded-full flex items-center justify-center mb-2" [class]="_iconBgSubtle()">
|
|
16027
16086
|
<span clx-icon [name]="metric().icon" size="md" [class]="_iconTextBase()"></span>
|
|
16028
16087
|
</div>
|
|
16029
|
-
<span class="text-sm text-
|
|
16030
|
-
<span class="text-2xl font-semibold text-
|
|
16088
|
+
<span class="text-sm text-clx-text-muted truncate">{{ metric().title }}</span>
|
|
16089
|
+
<span class="text-2xl font-semibold text-clx-text leading-tight">{{ _formattedValue() }}</span>
|
|
16031
16090
|
</div>
|
|
16032
16091
|
|
|
16033
16092
|
<!-- Col derecha: barras + tendencia -->
|
|
@@ -16042,7 +16101,7 @@ class ClxStatCardComponent {
|
|
|
16042
16101
|
}
|
|
16043
16102
|
</div>
|
|
16044
16103
|
<!-- Tendencia -->
|
|
16045
|
-
<div class="flex items-center gap-1 text-xs text-
|
|
16104
|
+
<div class="flex items-center gap-1 text-xs text-clx-text-subtle whitespace-nowrap">
|
|
16046
16105
|
{{ metric().trendDirection === 'up' ? 'Increased By' : 'Decreased By' }}
|
|
16047
16106
|
<span class="font-semibold" [class]="_trendTextClass()">{{ metric().trend }}</span>
|
|
16048
16107
|
<span clx-icon [name]="_trendArrowIcon()" size="sm" [class]="_trendTextClass()"></span>
|
|
@@ -16061,8 +16120,8 @@ class ClxStatCardComponent {
|
|
|
16061
16120
|
<span clx-icon [name]="_trendIcon()" size="xxs"></span>
|
|
16062
16121
|
{{ metric().trend }}
|
|
16063
16122
|
</span>
|
|
16064
|
-
<span class="text-2xl font-semibold text-
|
|
16065
|
-
<span class="text-xs font-semibold tracking-widest text-
|
|
16123
|
+
<span class="text-2xl font-semibold text-clx-text leading-tight">{{ _formattedValue() }}</span>
|
|
16124
|
+
<span class="text-xs font-semibold tracking-widest text-clx-text-subtle uppercase">{{ metric().title }}</span>
|
|
16066
16125
|
</div>
|
|
16067
16126
|
|
|
16068
16127
|
<!-- Col derecha: solo icono -->
|
|
@@ -16092,8 +16151,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
16092
16151
|
|
|
16093
16152
|
<!-- Text block -->
|
|
16094
16153
|
<div class="flex flex-col gap-1 min-w-0 flex-1">
|
|
16095
|
-
<span class="text-sm text-
|
|
16096
|
-
<span class="text-2xl font-semibold text-
|
|
16154
|
+
<span class="text-sm text-clx-text-muted truncate">{{ metric().title }}</span>
|
|
16155
|
+
<span class="text-2xl font-semibold text-clx-text leading-tight">
|
|
16097
16156
|
{{ _formattedValue() }}
|
|
16098
16157
|
</span>
|
|
16099
16158
|
<span clx-badge
|
|
@@ -16129,8 +16188,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
16129
16188
|
<div class="w-11 h-11 rounded-full flex items-center justify-center mb-2" [class]="_iconBgSubtle()">
|
|
16130
16189
|
<span clx-icon [name]="metric().icon" size="md" [class]="_iconTextBase()"></span>
|
|
16131
16190
|
</div>
|
|
16132
|
-
<span class="text-sm text-
|
|
16133
|
-
<span class="text-2xl font-semibold text-
|
|
16191
|
+
<span class="text-sm text-clx-text-muted truncate">{{ metric().title }}</span>
|
|
16192
|
+
<span class="text-2xl font-semibold text-clx-text leading-tight">{{ _formattedValue() }}</span>
|
|
16134
16193
|
</div>
|
|
16135
16194
|
|
|
16136
16195
|
<!-- Col derecha: barras + tendencia -->
|
|
@@ -16145,7 +16204,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
16145
16204
|
}
|
|
16146
16205
|
</div>
|
|
16147
16206
|
<!-- Tendencia -->
|
|
16148
|
-
<div class="flex items-center gap-1 text-xs text-
|
|
16207
|
+
<div class="flex items-center gap-1 text-xs text-clx-text-subtle whitespace-nowrap">
|
|
16149
16208
|
{{ metric().trendDirection === 'up' ? 'Increased By' : 'Decreased By' }}
|
|
16150
16209
|
<span class="font-semibold" [class]="_trendTextClass()">{{ metric().trend }}</span>
|
|
16151
16210
|
<span clx-icon [name]="_trendArrowIcon()" size="sm" [class]="_trendTextClass()"></span>
|
|
@@ -16164,8 +16223,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
16164
16223
|
<span clx-icon [name]="_trendIcon()" size="xxs"></span>
|
|
16165
16224
|
{{ metric().trend }}
|
|
16166
16225
|
</span>
|
|
16167
|
-
<span class="text-2xl font-semibold text-
|
|
16168
|
-
<span class="text-xs font-semibold tracking-widest text-
|
|
16226
|
+
<span class="text-2xl font-semibold text-clx-text leading-tight">{{ _formattedValue() }}</span>
|
|
16227
|
+
<span class="text-xs font-semibold tracking-widest text-clx-text-subtle uppercase">{{ metric().title }}</span>
|
|
16169
16228
|
</div>
|
|
16170
16229
|
|
|
16171
16230
|
<!-- Col derecha: solo icono -->
|
|
@@ -16177,6 +16236,469 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
16177
16236
|
}]
|
|
16178
16237
|
}], ctorParameters: () => [], propDecorators: { metric: [{ type: i0.Input, args: [{ isSignal: true, alias: "metric", required: true }] }], chartData: [{ type: i0.Input, args: [{ isSignal: true, alias: "chartData", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }] } });
|
|
16179
16238
|
|
|
16239
|
+
/** Standard chrome for any dashboard widget (stat card, chart, table, list...) — header with
|
|
16240
|
+
* title + an optional drag handle + an overlay menu for per-widget actions (configure, resize,
|
|
16241
|
+
* remove), plus shared loading/empty/error states so individual widgets never re-implement them.
|
|
16242
|
+
* Widget content itself is projected via the default <ng-content>; callers keep full control of
|
|
16243
|
+
* what renders inside once state() is 'ready'. */
|
|
16244
|
+
class ClxWidgetCardComponent {
|
|
16245
|
+
_themeSvc = inject(ClxThemeService);
|
|
16246
|
+
title = input.required(...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
16247
|
+
state = input('ready', ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
|
|
16248
|
+
draggable = input(false, ...(ngDevMode ? [{ debugName: "draggable" }] : /* istanbul ignore next */ []));
|
|
16249
|
+
menuActions = input([], ...(ngDevMode ? [{ debugName: "menuActions" }] : /* istanbul ignore next */ []));
|
|
16250
|
+
menuLabel = input('Opciones del widget', ...(ngDevMode ? [{ debugName: "menuLabel" }] : /* istanbul ignore next */ []));
|
|
16251
|
+
emptyMessage = input('Sin datos en el rango seleccionado', ...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []));
|
|
16252
|
+
errorMessage = input('No se pudo cargar este widget', ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
|
|
16253
|
+
retryLabel = input('Reintentar', ...(ngDevMode ? [{ debugName: "retryLabel" }] : /* istanbul ignore next */ []));
|
|
16254
|
+
menuAction = output();
|
|
16255
|
+
retry = output();
|
|
16256
|
+
_sso = inject(ScrollStrategyOptions);
|
|
16257
|
+
_scrollStrategy = this._sso.reposition();
|
|
16258
|
+
_positions = [
|
|
16259
|
+
{ originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },
|
|
16260
|
+
{ originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },
|
|
16261
|
+
];
|
|
16262
|
+
_menuOpen = signal(false, ...(ngDevMode ? [{ debugName: "_menuOpen" }] : /* istanbul ignore next */ []));
|
|
16263
|
+
_menuPanelClass = computed(() => {
|
|
16264
|
+
const t = resolveColor(this._themeSvc.cardBorderColor());
|
|
16265
|
+
return `w-48 p-1.5 bg-clx-surface rounded-xl shadow-xl border ${t.borderLight} overflow-hidden mt-1`;
|
|
16266
|
+
}, ...(ngDevMode ? [{ debugName: "_menuPanelClass" }] : /* istanbul ignore next */ []));
|
|
16267
|
+
_hostClass = computed(() => {
|
|
16268
|
+
const t = resolveColor(this._themeSvc.cardBorderColor());
|
|
16269
|
+
const radius = resolveContainerRadius(this._themeSvc.config().borderRadius);
|
|
16270
|
+
return `flex flex-col bg-clx-surface ${radius} border ${t.borderLight} shadow-sm overflow-hidden h-full`;
|
|
16271
|
+
}, ...(ngDevMode ? [{ debugName: "_hostClass" }] : /* istanbul ignore next */ []));
|
|
16272
|
+
_toggleMenu() { this._menuOpen.update(v => !v); }
|
|
16273
|
+
_closeMenu() { this._menuOpen.set(false); }
|
|
16274
|
+
_onMenuKeydown(event) {
|
|
16275
|
+
if (event.key === 'Escape')
|
|
16276
|
+
this._closeMenu();
|
|
16277
|
+
}
|
|
16278
|
+
_onMenuAction(action) {
|
|
16279
|
+
this.menuAction.emit(action);
|
|
16280
|
+
this._closeMenu();
|
|
16281
|
+
}
|
|
16282
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxWidgetCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
16283
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxWidgetCardComponent, isStandalone: true, selector: "clx-widget-card", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, menuActions: { classPropertyName: "menuActions", publicName: "menuActions", isSignal: true, isRequired: false, transformFunction: null }, menuLabel: { classPropertyName: "menuLabel", publicName: "menuLabel", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, retryLabel: { classPropertyName: "retryLabel", publicName: "retryLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { menuAction: "menuAction", retry: "retry" }, host: { properties: { "class": "_hostClass()" } }, ngImport: i0, template: `
|
|
16284
|
+
<div class="flex items-center justify-between gap-2 px-4 py-3 border-b border-clx-border-soft shrink-0">
|
|
16285
|
+
<div class="flex items-center gap-2 min-w-0">
|
|
16286
|
+
@if (draggable()) {
|
|
16287
|
+
<span clx-icon name="drag_indicator" size="sm" class="text-clx-text-subtle cursor-grab shrink-0"></span>
|
|
16288
|
+
}
|
|
16289
|
+
<p class="text-sm font-semibold text-clx-text-label truncate">{{ title() }}</p>
|
|
16290
|
+
</div>
|
|
16291
|
+
|
|
16292
|
+
@if (menuActions().length) {
|
|
16293
|
+
<button
|
|
16294
|
+
#origin="cdkOverlayOrigin"
|
|
16295
|
+
cdkOverlayOrigin
|
|
16296
|
+
type="button"
|
|
16297
|
+
class="shrink-0 w-7 h-7 rounded-lg flex items-center justify-center text-clx-text-subtle hover:bg-clx-surface-2 cursor-pointer"
|
|
16298
|
+
[attr.aria-label]="menuLabel()"
|
|
16299
|
+
(click)="_toggleMenu()">
|
|
16300
|
+
<span clx-icon name="more_vert" size="sm"></span>
|
|
16301
|
+
</button>
|
|
16302
|
+
|
|
16303
|
+
<ng-template
|
|
16304
|
+
cdkConnectedOverlay
|
|
16305
|
+
[cdkConnectedOverlayOrigin]="origin"
|
|
16306
|
+
[cdkConnectedOverlayOpen]="_menuOpen()"
|
|
16307
|
+
[cdkConnectedOverlayPositions]="_positions"
|
|
16308
|
+
[cdkConnectedOverlayScrollStrategy]="_scrollStrategy"
|
|
16309
|
+
[cdkConnectedOverlayPush]="true"
|
|
16310
|
+
(overlayOutsideClick)="_closeMenu()"
|
|
16311
|
+
(overlayKeydown)="_onMenuKeydown($event)">
|
|
16312
|
+
<div [class]="_menuPanelClass()">
|
|
16313
|
+
@for (item of menuActions(); track item.action) {
|
|
16314
|
+
<button
|
|
16315
|
+
type="button"
|
|
16316
|
+
class="w-full text-left px-3 py-2 rounded-lg text-sm flex items-center gap-2 hover:bg-clx-surface-2 cursor-pointer"
|
|
16317
|
+
[class]="item.danger ? 'text-red-600' : 'text-clx-text-label'"
|
|
16318
|
+
(click)="_onMenuAction(item.action)">
|
|
16319
|
+
<span clx-icon [name]="item.icon" size="sm" [class]="item.danger ? 'text-red-600' : 'text-clx-text-subtle'"></span>
|
|
16320
|
+
{{ item.label }}
|
|
16321
|
+
</button>
|
|
16322
|
+
}
|
|
16323
|
+
</div>
|
|
16324
|
+
</ng-template>
|
|
16325
|
+
}
|
|
16326
|
+
</div>
|
|
16327
|
+
|
|
16328
|
+
<div class="flex-1 min-h-0 overflow-auto">
|
|
16329
|
+
@switch (state()) {
|
|
16330
|
+
@case ('loading') {
|
|
16331
|
+
<div class="h-full flex flex-col gap-3 justify-center p-4">
|
|
16332
|
+
<clx-skeleton variant="text" width="100%" height="12px" />
|
|
16333
|
+
<clx-skeleton variant="text" width="85%" height="12px" />
|
|
16334
|
+
<clx-skeleton variant="text" width="92%" height="12px" />
|
|
16335
|
+
</div>
|
|
16336
|
+
}
|
|
16337
|
+
@case ('empty') {
|
|
16338
|
+
<div class="h-full flex flex-col items-center justify-center gap-2 p-6 text-center">
|
|
16339
|
+
<div class="w-11 h-11 rounded-xl bg-clx-surface-2 flex items-center justify-center">
|
|
16340
|
+
<span clx-icon name="inbox" size="md" class="text-clx-text-subtle"></span>
|
|
16341
|
+
</div>
|
|
16342
|
+
<p class="text-xs text-clx-text-subtle">{{ emptyMessage() }}</p>
|
|
16343
|
+
</div>
|
|
16344
|
+
}
|
|
16345
|
+
@case ('error') {
|
|
16346
|
+
<div class="h-full flex flex-col items-center justify-center gap-3 p-6 text-center">
|
|
16347
|
+
<div class="w-11 h-11 rounded-xl bg-red-50 flex items-center justify-center">
|
|
16348
|
+
<span clx-icon name="error" size="md" class="text-red-600"></span>
|
|
16349
|
+
</div>
|
|
16350
|
+
<p class="text-xs text-clx-text-subtle">{{ errorMessage() }}</p>
|
|
16351
|
+
<button
|
|
16352
|
+
type="button"
|
|
16353
|
+
class="text-xs font-semibold px-3 py-1.5 rounded-lg border border-clx-border text-clx-text-label hover:bg-clx-surface-2 cursor-pointer"
|
|
16354
|
+
(click)="retry.emit()">
|
|
16355
|
+
{{ retryLabel() }}
|
|
16356
|
+
</button>
|
|
16357
|
+
</div>
|
|
16358
|
+
}
|
|
16359
|
+
@default {
|
|
16360
|
+
<ng-content />
|
|
16361
|
+
}
|
|
16362
|
+
}
|
|
16363
|
+
</div>
|
|
16364
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: ClxIconComponent, selector: "span[clx-icon]", inputs: ["name", "size", "color", "fill"] }, { kind: "component", type: ClxSkeletonComponent, selector: "clx-skeleton", inputs: ["variant", "size", "width", "height"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
16365
|
+
}
|
|
16366
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxWidgetCardComponent, decorators: [{
|
|
16367
|
+
type: Component,
|
|
16368
|
+
args: [{
|
|
16369
|
+
selector: 'clx-widget-card',
|
|
16370
|
+
standalone: true,
|
|
16371
|
+
imports: [OverlayModule, ClxIconComponent, ClxSkeletonComponent],
|
|
16372
|
+
encapsulation: ViewEncapsulation.None,
|
|
16373
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
16374
|
+
host: { '[class]': '_hostClass()' },
|
|
16375
|
+
template: `
|
|
16376
|
+
<div class="flex items-center justify-between gap-2 px-4 py-3 border-b border-clx-border-soft shrink-0">
|
|
16377
|
+
<div class="flex items-center gap-2 min-w-0">
|
|
16378
|
+
@if (draggable()) {
|
|
16379
|
+
<span clx-icon name="drag_indicator" size="sm" class="text-clx-text-subtle cursor-grab shrink-0"></span>
|
|
16380
|
+
}
|
|
16381
|
+
<p class="text-sm font-semibold text-clx-text-label truncate">{{ title() }}</p>
|
|
16382
|
+
</div>
|
|
16383
|
+
|
|
16384
|
+
@if (menuActions().length) {
|
|
16385
|
+
<button
|
|
16386
|
+
#origin="cdkOverlayOrigin"
|
|
16387
|
+
cdkOverlayOrigin
|
|
16388
|
+
type="button"
|
|
16389
|
+
class="shrink-0 w-7 h-7 rounded-lg flex items-center justify-center text-clx-text-subtle hover:bg-clx-surface-2 cursor-pointer"
|
|
16390
|
+
[attr.aria-label]="menuLabel()"
|
|
16391
|
+
(click)="_toggleMenu()">
|
|
16392
|
+
<span clx-icon name="more_vert" size="sm"></span>
|
|
16393
|
+
</button>
|
|
16394
|
+
|
|
16395
|
+
<ng-template
|
|
16396
|
+
cdkConnectedOverlay
|
|
16397
|
+
[cdkConnectedOverlayOrigin]="origin"
|
|
16398
|
+
[cdkConnectedOverlayOpen]="_menuOpen()"
|
|
16399
|
+
[cdkConnectedOverlayPositions]="_positions"
|
|
16400
|
+
[cdkConnectedOverlayScrollStrategy]="_scrollStrategy"
|
|
16401
|
+
[cdkConnectedOverlayPush]="true"
|
|
16402
|
+
(overlayOutsideClick)="_closeMenu()"
|
|
16403
|
+
(overlayKeydown)="_onMenuKeydown($event)">
|
|
16404
|
+
<div [class]="_menuPanelClass()">
|
|
16405
|
+
@for (item of menuActions(); track item.action) {
|
|
16406
|
+
<button
|
|
16407
|
+
type="button"
|
|
16408
|
+
class="w-full text-left px-3 py-2 rounded-lg text-sm flex items-center gap-2 hover:bg-clx-surface-2 cursor-pointer"
|
|
16409
|
+
[class]="item.danger ? 'text-red-600' : 'text-clx-text-label'"
|
|
16410
|
+
(click)="_onMenuAction(item.action)">
|
|
16411
|
+
<span clx-icon [name]="item.icon" size="sm" [class]="item.danger ? 'text-red-600' : 'text-clx-text-subtle'"></span>
|
|
16412
|
+
{{ item.label }}
|
|
16413
|
+
</button>
|
|
16414
|
+
}
|
|
16415
|
+
</div>
|
|
16416
|
+
</ng-template>
|
|
16417
|
+
}
|
|
16418
|
+
</div>
|
|
16419
|
+
|
|
16420
|
+
<div class="flex-1 min-h-0 overflow-auto">
|
|
16421
|
+
@switch (state()) {
|
|
16422
|
+
@case ('loading') {
|
|
16423
|
+
<div class="h-full flex flex-col gap-3 justify-center p-4">
|
|
16424
|
+
<clx-skeleton variant="text" width="100%" height="12px" />
|
|
16425
|
+
<clx-skeleton variant="text" width="85%" height="12px" />
|
|
16426
|
+
<clx-skeleton variant="text" width="92%" height="12px" />
|
|
16427
|
+
</div>
|
|
16428
|
+
}
|
|
16429
|
+
@case ('empty') {
|
|
16430
|
+
<div class="h-full flex flex-col items-center justify-center gap-2 p-6 text-center">
|
|
16431
|
+
<div class="w-11 h-11 rounded-xl bg-clx-surface-2 flex items-center justify-center">
|
|
16432
|
+
<span clx-icon name="inbox" size="md" class="text-clx-text-subtle"></span>
|
|
16433
|
+
</div>
|
|
16434
|
+
<p class="text-xs text-clx-text-subtle">{{ emptyMessage() }}</p>
|
|
16435
|
+
</div>
|
|
16436
|
+
}
|
|
16437
|
+
@case ('error') {
|
|
16438
|
+
<div class="h-full flex flex-col items-center justify-center gap-3 p-6 text-center">
|
|
16439
|
+
<div class="w-11 h-11 rounded-xl bg-red-50 flex items-center justify-center">
|
|
16440
|
+
<span clx-icon name="error" size="md" class="text-red-600"></span>
|
|
16441
|
+
</div>
|
|
16442
|
+
<p class="text-xs text-clx-text-subtle">{{ errorMessage() }}</p>
|
|
16443
|
+
<button
|
|
16444
|
+
type="button"
|
|
16445
|
+
class="text-xs font-semibold px-3 py-1.5 rounded-lg border border-clx-border text-clx-text-label hover:bg-clx-surface-2 cursor-pointer"
|
|
16446
|
+
(click)="retry.emit()">
|
|
16447
|
+
{{ retryLabel() }}
|
|
16448
|
+
</button>
|
|
16449
|
+
</div>
|
|
16450
|
+
}
|
|
16451
|
+
@default {
|
|
16452
|
+
<ng-content />
|
|
16453
|
+
}
|
|
16454
|
+
}
|
|
16455
|
+
</div>
|
|
16456
|
+
`,
|
|
16457
|
+
}]
|
|
16458
|
+
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], draggable: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggable", required: false }] }], menuActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuActions", required: false }] }], menuLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuLabel", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], retryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "retryLabel", required: false }] }], menuAction: [{ type: i0.Output, args: ["menuAction"] }], retry: [{ type: i0.Output, args: ["retry"] }] } });
|
|
16459
|
+
|
|
16460
|
+
/** Drop-in cell for a `clxCell` table column: label + inline progress bar + trailing value —
|
|
16461
|
+
* e.g. "Canadá [████████░░] 6,192" rows in a "sales by country/branch" dashboard widget. Mount it
|
|
16462
|
+
* inside `<ng-template clxCell let-row>` instead of hand-building the flex row each time. */
|
|
16463
|
+
class ClxTableProgressCellComponent {
|
|
16464
|
+
label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
16465
|
+
value = input.required(...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
16466
|
+
max = input(100, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
16467
|
+
color = input(undefined, ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
16468
|
+
/** Optional leading glyph (e.g. a flag emoji) shown before the label. */
|
|
16469
|
+
leadingIcon = input(undefined, ...(ngDevMode ? [{ debugName: "leadingIcon" }] : /* istanbul ignore next */ []));
|
|
16470
|
+
/** Overrides the trailing number's text (e.g. a formatted "6,192") — falls back to the raw value(). */
|
|
16471
|
+
displayValue = input(undefined, ...(ngDevMode ? [{ debugName: "displayValue" }] : /* istanbul ignore next */ []));
|
|
16472
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxTableProgressCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
16473
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxTableProgressCellComponent, isStandalone: true, selector: "clx-table-progress-cell", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, leadingIcon: { classPropertyName: "leadingIcon", publicName: "leadingIcon", isSignal: true, isRequired: false, transformFunction: null }, displayValue: { classPropertyName: "displayValue", publicName: "displayValue", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "flex items-center gap-2.5 w-full" }, ngImport: i0, template: `
|
|
16474
|
+
@if (leadingIcon()) {
|
|
16475
|
+
<span class="text-base shrink-0">{{ leadingIcon() }}</span>
|
|
16476
|
+
}
|
|
16477
|
+
<span class="text-sm text-clx-text-label shrink-0 w-24 truncate">{{ label() }}</span>
|
|
16478
|
+
<div class="flex-1 min-w-0">
|
|
16479
|
+
<clx-progress-bar [value]="value()" [max]="max()" [color]="color()" size="xs" />
|
|
16480
|
+
</div>
|
|
16481
|
+
<span class="text-sm font-semibold text-clx-text tabular-nums shrink-0">{{ displayValue() ?? value() }}</span>
|
|
16482
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ClxProgressBarComponent, selector: "clx-progress-bar", inputs: ["value", "max", "color", "size", "variant", "label", "showValue", "valueFormat", "segments"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
16483
|
+
}
|
|
16484
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxTableProgressCellComponent, decorators: [{
|
|
16485
|
+
type: Component,
|
|
16486
|
+
args: [{
|
|
16487
|
+
selector: 'clx-table-progress-cell',
|
|
16488
|
+
standalone: true,
|
|
16489
|
+
imports: [ClxProgressBarComponent],
|
|
16490
|
+
encapsulation: ViewEncapsulation.None,
|
|
16491
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
16492
|
+
host: { class: 'flex items-center gap-2.5 w-full' },
|
|
16493
|
+
template: `
|
|
16494
|
+
@if (leadingIcon()) {
|
|
16495
|
+
<span class="text-base shrink-0">{{ leadingIcon() }}</span>
|
|
16496
|
+
}
|
|
16497
|
+
<span class="text-sm text-clx-text-label shrink-0 w-24 truncate">{{ label() }}</span>
|
|
16498
|
+
<div class="flex-1 min-w-0">
|
|
16499
|
+
<clx-progress-bar [value]="value()" [max]="max()" [color]="color()" size="xs" />
|
|
16500
|
+
</div>
|
|
16501
|
+
<span class="text-sm font-semibold text-clx-text tabular-nums shrink-0">{{ displayValue() ?? value() }}</span>
|
|
16502
|
+
`,
|
|
16503
|
+
}]
|
|
16504
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], leadingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingIcon", required: false }] }], displayValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayValue", required: false }] }] } });
|
|
16505
|
+
|
|
16506
|
+
/** Drop-in cell for a `clxCell` table column: avatar (or initials) + label on the left, a status
|
|
16507
|
+
* pill on the right — e.g. a "recent orders" dashboard widget row like "Orden #4582 ⋯ Entregado".
|
|
16508
|
+
* Mount it inside `<ng-template clxCell let-row>` instead of hand-building the flex row each time. */
|
|
16509
|
+
class ClxTableStatusCellComponent {
|
|
16510
|
+
label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
16511
|
+
avatarSrc = input(null, ...(ngDevMode ? [{ debugName: "avatarSrc" }] : /* istanbul ignore next */ []));
|
|
16512
|
+
avatarInitials = input(null, ...(ngDevMode ? [{ debugName: "avatarInitials" }] : /* istanbul ignore next */ []));
|
|
16513
|
+
avatarColor = input(undefined, ...(ngDevMode ? [{ debugName: "avatarColor" }] : /* istanbul ignore next */ []));
|
|
16514
|
+
statusLabel = input.required(...(ngDevMode ? [{ debugName: "statusLabel" }] : /* istanbul ignore next */ []));
|
|
16515
|
+
statusColor = input('slate', ...(ngDevMode ? [{ debugName: "statusColor" }] : /* istanbul ignore next */ []));
|
|
16516
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxTableStatusCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
16517
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.15", type: ClxTableStatusCellComponent, isStandalone: true, selector: "clx-table-status-cell", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, avatarSrc: { classPropertyName: "avatarSrc", publicName: "avatarSrc", isSignal: true, isRequired: false, transformFunction: null }, avatarInitials: { classPropertyName: "avatarInitials", publicName: "avatarInitials", isSignal: true, isRequired: false, transformFunction: null }, avatarColor: { classPropertyName: "avatarColor", publicName: "avatarColor", isSignal: true, isRequired: false, transformFunction: null }, statusLabel: { classPropertyName: "statusLabel", publicName: "statusLabel", isSignal: true, isRequired: true, transformFunction: null }, statusColor: { classPropertyName: "statusColor", publicName: "statusColor", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "flex items-center justify-between gap-3 w-full" }, ngImport: i0, template: `
|
|
16518
|
+
<div class="flex items-center gap-2.5 min-w-0">
|
|
16519
|
+
<clx-avatar [src]="avatarSrc()" [initials]="avatarInitials()" [color]="avatarColor()" size="xs" />
|
|
16520
|
+
<span class="text-sm text-clx-text-label truncate">{{ label() }}</span>
|
|
16521
|
+
</div>
|
|
16522
|
+
<span clx-badge [color]="statusColor()" variant="light" shape="pill" size="xs" class="shrink-0">
|
|
16523
|
+
{{ statusLabel() }}
|
|
16524
|
+
</span>
|
|
16525
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ClxAvatarComponent, selector: "clx-avatar", inputs: ["src", "initials", "iconName", "color", "size", "shape", "alt"] }, { kind: "component", type: ClxBadgeComponent, selector: "span[clx-badge]", inputs: ["variant", "color", "size", "shape", "positioned"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
16526
|
+
}
|
|
16527
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxTableStatusCellComponent, decorators: [{
|
|
16528
|
+
type: Component,
|
|
16529
|
+
args: [{
|
|
16530
|
+
selector: 'clx-table-status-cell',
|
|
16531
|
+
standalone: true,
|
|
16532
|
+
imports: [ClxAvatarComponent, ClxBadgeComponent],
|
|
16533
|
+
encapsulation: ViewEncapsulation.None,
|
|
16534
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
16535
|
+
host: { class: 'flex items-center justify-between gap-3 w-full' },
|
|
16536
|
+
template: `
|
|
16537
|
+
<div class="flex items-center gap-2.5 min-w-0">
|
|
16538
|
+
<clx-avatar [src]="avatarSrc()" [initials]="avatarInitials()" [color]="avatarColor()" size="xs" />
|
|
16539
|
+
<span class="text-sm text-clx-text-label truncate">{{ label() }}</span>
|
|
16540
|
+
</div>
|
|
16541
|
+
<span clx-badge [color]="statusColor()" variant="light" shape="pill" size="xs" class="shrink-0">
|
|
16542
|
+
{{ statusLabel() }}
|
|
16543
|
+
</span>
|
|
16544
|
+
`,
|
|
16545
|
+
}]
|
|
16546
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], avatarSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarSrc", required: false }] }], avatarInitials: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarInitials", required: false }] }], avatarColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarColor", required: false }] }], statusLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "statusLabel", required: true }] }], statusColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "statusColor", required: false }] }] } });
|
|
16547
|
+
|
|
16548
|
+
/** Content template for one grid cell — `<ng-template clxGridItem let-item>...</ng-template>`,
|
|
16549
|
+
* mirroring the `clxCell`/`clxColumn` convention ClxTableComponent already uses for projected
|
|
16550
|
+
* per-row templates. Typically a <clx-widget-card> wrapping whatever the widget actually renders. */
|
|
16551
|
+
class ClxGridItemDirective {
|
|
16552
|
+
templateRef;
|
|
16553
|
+
constructor(templateRef) {
|
|
16554
|
+
this.templateRef = templateRef;
|
|
16555
|
+
}
|
|
16556
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxGridItemDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
16557
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.15", type: ClxGridItemDirective, isStandalone: true, selector: "ng-template[clxGridItem]", ngImport: i0 });
|
|
16558
|
+
}
|
|
16559
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxGridItemDirective, decorators: [{
|
|
16560
|
+
type: Directive,
|
|
16561
|
+
args: [{ selector: 'ng-template[clxGridItem]', standalone: true }]
|
|
16562
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef }] });
|
|
16563
|
+
/** Content-agnostic configurable dashboard grid: positions/sizes projected widgets on a CSS grid
|
|
16564
|
+
* using column/row units, supports drag-to-reorder (via Angular CDK's CdkDropList/CdkDrag — no
|
|
16565
|
+
* new dependency, @angular/cdk is already pulled in by ClxProfileComponent/ClxWidgetCardComponent's
|
|
16566
|
+
* overlay usage) and resize-by-dragging a corner handle. Persistence is the caller's job: listen
|
|
16567
|
+
* to (layoutChange) and save the resulting ClxGridItem[] (e.g. to rp_dashboard_layouts.layout). */
|
|
16568
|
+
class ClxDashboardGridComponent {
|
|
16569
|
+
items = input.required(...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
16570
|
+
columns = input(4, ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
16571
|
+
rowHeight = input(92, ...(ngDevMode ? [{ debugName: "rowHeight" }] : /* istanbul ignore next */ []));
|
|
16572
|
+
gap = input(16, ...(ngDevMode ? [{ debugName: "gap" }] : /* istanbul ignore next */ []));
|
|
16573
|
+
editable = input(false, ...(ngDevMode ? [{ debugName: "editable" }] : /* istanbul ignore next */ []));
|
|
16574
|
+
layoutChange = output();
|
|
16575
|
+
itemResize = output();
|
|
16576
|
+
_itemTemplate = contentChild(ClxGridItemDirective, ...(ngDevMode ? [{ debugName: "_itemTemplate" }] : /* istanbul ignore next */ []));
|
|
16577
|
+
_gridCols = computed(() => `repeat(${this.columns()}, minmax(0, 1fr))`, ...(ngDevMode ? [{ debugName: "_gridCols" }] : /* istanbul ignore next */ []));
|
|
16578
|
+
_resizing = null;
|
|
16579
|
+
_onDrop(event) {
|
|
16580
|
+
const next = [...this.items()];
|
|
16581
|
+
moveItemInArray(next, event.previousIndex, event.currentIndex);
|
|
16582
|
+
this.layoutChange.emit(next);
|
|
16583
|
+
}
|
|
16584
|
+
_onDragMoved(_event) {
|
|
16585
|
+
// Reordering is handled by cdkDropListDropped above; this hook exists for future free-form
|
|
16586
|
+
// (x/y pixel) positioning if a consumer needs it — not required for a reorderable column grid.
|
|
16587
|
+
}
|
|
16588
|
+
_startResize(event, item) {
|
|
16589
|
+
event.preventDefault();
|
|
16590
|
+
event.stopPropagation();
|
|
16591
|
+
this._resizing = { item, startX: event.clientX, startY: event.clientY, startW: item.w, startH: item.h };
|
|
16592
|
+
const cellW = event.target.closest('[style*="grid-column"]')?.clientWidth
|
|
16593
|
+
?? (this.rowHeight() * 2);
|
|
16594
|
+
const onMove = (e) => {
|
|
16595
|
+
if (!this._resizing)
|
|
16596
|
+
return;
|
|
16597
|
+
const dx = e.clientX - this._resizing.startX;
|
|
16598
|
+
const dy = e.clientY - this._resizing.startY;
|
|
16599
|
+
const deltaCols = Math.round(dx / (cellW / this._resizing.startW || 1));
|
|
16600
|
+
const deltaRows = Math.round(dy / this.rowHeight());
|
|
16601
|
+
const nextW = Math.max(item.minW ?? 1, this._resizing.startW + deltaCols);
|
|
16602
|
+
const nextH = Math.max(item.minH ?? 1, this._resizing.startH + deltaRows);
|
|
16603
|
+
if (nextW !== item.w || nextH !== item.h) {
|
|
16604
|
+
item.w = nextW;
|
|
16605
|
+
item.h = nextH;
|
|
16606
|
+
this.itemResize.emit({ id: item.id, w: nextW, h: nextH });
|
|
16607
|
+
}
|
|
16608
|
+
};
|
|
16609
|
+
const onUp = () => {
|
|
16610
|
+
this._resizing = null;
|
|
16611
|
+
this.layoutChange.emit([...this.items()]);
|
|
16612
|
+
window.removeEventListener('pointermove', onMove);
|
|
16613
|
+
window.removeEventListener('pointerup', onUp);
|
|
16614
|
+
};
|
|
16615
|
+
window.addEventListener('pointermove', onMove);
|
|
16616
|
+
window.addEventListener('pointerup', onUp);
|
|
16617
|
+
}
|
|
16618
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxDashboardGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
16619
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxDashboardGridComponent, isStandalone: true, selector: "clx-dashboard-grid", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { layoutChange: "layoutChange", itemResize: "itemResize" }, host: { classAttribute: "block w-full" }, queries: [{ propertyName: "_itemTemplate", first: true, predicate: ClxGridItemDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
16620
|
+
<div
|
|
16621
|
+
cdkDropList
|
|
16622
|
+
[cdkDropListDisabled]="!editable()"
|
|
16623
|
+
(cdkDropListDropped)="_onDrop($event)"
|
|
16624
|
+
class="grid w-full"
|
|
16625
|
+
[style.grid-template-columns]="_gridCols()"
|
|
16626
|
+
[style.grid-auto-rows.px]="rowHeight()"
|
|
16627
|
+
[style.gap.px]="gap()">
|
|
16628
|
+
@for (item of items(); track item.id) {
|
|
16629
|
+
<div
|
|
16630
|
+
cdkDrag
|
|
16631
|
+
[cdkDragDisabled]="!editable()"
|
|
16632
|
+
[cdkDragData]="item"
|
|
16633
|
+
(cdkDragMoved)="_onDragMoved($event)"
|
|
16634
|
+
class="relative min-w-0"
|
|
16635
|
+
[class.cursor-grab]="editable()"
|
|
16636
|
+
[style.grid-column]="'span ' + item.w"
|
|
16637
|
+
[style.grid-row]="'span ' + item.h">
|
|
16638
|
+
|
|
16639
|
+
<ng-container
|
|
16640
|
+
[ngTemplateOutlet]="_itemTemplate()?.templateRef ?? null"
|
|
16641
|
+
[ngTemplateOutletContext]="{ $implicit: item }">
|
|
16642
|
+
</ng-container>
|
|
16643
|
+
|
|
16644
|
+
@if (editable()) {
|
|
16645
|
+
<div
|
|
16646
|
+
class="absolute -right-1 -bottom-1 w-3.5 h-3.5 rounded bg-clx-primary border-2 border-clx-surface shadow cursor-nwse-resize"
|
|
16647
|
+
(pointerdown)="_startResize($event, item)">
|
|
16648
|
+
</div>
|
|
16649
|
+
}
|
|
16650
|
+
</div>
|
|
16651
|
+
}
|
|
16652
|
+
</div>
|
|
16653
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
16654
|
+
}
|
|
16655
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxDashboardGridComponent, decorators: [{
|
|
16656
|
+
type: Component,
|
|
16657
|
+
args: [{
|
|
16658
|
+
selector: 'clx-dashboard-grid',
|
|
16659
|
+
standalone: true,
|
|
16660
|
+
imports: [NgTemplateOutlet, DragDropModule],
|
|
16661
|
+
encapsulation: ViewEncapsulation.None,
|
|
16662
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
16663
|
+
host: { class: 'block w-full' },
|
|
16664
|
+
template: `
|
|
16665
|
+
<div
|
|
16666
|
+
cdkDropList
|
|
16667
|
+
[cdkDropListDisabled]="!editable()"
|
|
16668
|
+
(cdkDropListDropped)="_onDrop($event)"
|
|
16669
|
+
class="grid w-full"
|
|
16670
|
+
[style.grid-template-columns]="_gridCols()"
|
|
16671
|
+
[style.grid-auto-rows.px]="rowHeight()"
|
|
16672
|
+
[style.gap.px]="gap()">
|
|
16673
|
+
@for (item of items(); track item.id) {
|
|
16674
|
+
<div
|
|
16675
|
+
cdkDrag
|
|
16676
|
+
[cdkDragDisabled]="!editable()"
|
|
16677
|
+
[cdkDragData]="item"
|
|
16678
|
+
(cdkDragMoved)="_onDragMoved($event)"
|
|
16679
|
+
class="relative min-w-0"
|
|
16680
|
+
[class.cursor-grab]="editable()"
|
|
16681
|
+
[style.grid-column]="'span ' + item.w"
|
|
16682
|
+
[style.grid-row]="'span ' + item.h">
|
|
16683
|
+
|
|
16684
|
+
<ng-container
|
|
16685
|
+
[ngTemplateOutlet]="_itemTemplate()?.templateRef ?? null"
|
|
16686
|
+
[ngTemplateOutletContext]="{ $implicit: item }">
|
|
16687
|
+
</ng-container>
|
|
16688
|
+
|
|
16689
|
+
@if (editable()) {
|
|
16690
|
+
<div
|
|
16691
|
+
class="absolute -right-1 -bottom-1 w-3.5 h-3.5 rounded bg-clx-primary border-2 border-clx-surface shadow cursor-nwse-resize"
|
|
16692
|
+
(pointerdown)="_startResize($event, item)">
|
|
16693
|
+
</div>
|
|
16694
|
+
}
|
|
16695
|
+
</div>
|
|
16696
|
+
}
|
|
16697
|
+
</div>
|
|
16698
|
+
`,
|
|
16699
|
+
}]
|
|
16700
|
+
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], layoutChange: [{ type: i0.Output, args: ["layoutChange"] }], itemResize: [{ type: i0.Output, args: ["itemResize"] }], _itemTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ClxGridItemDirective), { isSignal: true }] }] } });
|
|
16701
|
+
|
|
16180
16702
|
const PRODUCT_TAG_LABEL = {
|
|
16181
16703
|
'new': 'Nuevo',
|
|
16182
16704
|
'sale': 'Oferta',
|
|
@@ -18780,5 +19302,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
18780
19302
|
* Generated bundle index. Do not edit.
|
|
18781
19303
|
*/
|
|
18782
19304
|
|
|
18783
|
-
export { CLX_ADDON_BORDER, CLX_ADDON_TEXT, CLX_ALERT_OPTIONS, CLX_ALERT_RESOLVE, CLX_BG_ADDON, CLX_BG_DISABLED, CLX_BG_ICON_WRAP, CLX_BG_SECTION, CLX_BG_SURFACE, CLX_BORDER_DEFAULT, CLX_BORDER_DISABLED, CLX_BORDER_MEDIUM, CLX_COLOR_HEX, CLX_COLOR_HEX_100, CLX_COLOR_MAP, CLX_FONT_CATALOG, CLX_MODAL_ANIM_CONFIG, CLX_MODAL_DATA, CLX_MODAL_REF, CLX_OPTION_DISABLED, CLX_PLACEHOLDER, CLX_RADIO_GROUP, CLX_RADIUS_MAP, CLX_TEXT_BODY, CLX_TEXT_DISABLED, CLX_TEXT_HEADING, CLX_TEXT_HINT, CLX_TEXT_IDLE, CLX_TEXT_INPUT, CLX_TEXT_LABEL, CLX_TEXT_OPTION, CLX_TEXT_SUBTITLE, CLX_TEXT_TITLE, CLX_THEME_CONFIG, CLX_THEME_DEFAULTS, CLX_TOAST_DEFAULTS, ClxAlertComponent, ClxAlertService, ClxAnimateDirective, ClxAnimateGroupDirective, ClxAnimateService, ClxAppLayoutComponent, ClxAvatarComponent, ClxBadgeComponent, ClxBrandComponent, ClxButtonComponent, ClxButtonGroupComponent, ClxCardBodyDirective, ClxCardComponent, ClxCardExpiryInputComponent, ClxCardFooterDirective, ClxCardHeaderActionsDirective, ClxCardHeaderDirective, ClxCardNumberInputComponent, ClxCardValidators, ClxCarouselComponent, ClxCarouselDirective, ClxCartComponent, ClxCartSummaryDrawer, ClxCellDirective, ClxCheckboxComponent, ClxCollapseComponent, ClxColorPickerComponent, ClxColumnDefDirective, ClxDateRangePickerComponent, ClxDatepickerComponent, ClxDrawerComponent, ClxDrawerService, ClxEditorComponent, ClxEditorImageModalComponent, ClxEditorLinkModalComponent, ClxFabComponent, ClxFilterPanelComponent, ClxHeaderCellDirective, ClxIconComponent, ClxInputComponent, ClxListComponent, ClxListItemComponent, ClxMenuComponent, ClxMenuItemComponent, ClxMenuItemTrailingDirective, ClxModalComponent, ClxModalService, ClxNativeOverlayService, ClxNavGroupComponent, ClxNotificationComponent, ClxNumberComponent, ClxOtpComponent, ClxPageEmptyComponent, ClxPageHeaderComponent, ClxPageHeaderTitleDirective, ClxPageNotFoundComponent, ClxPageServerErrorComponent, ClxPageUnauthorizedComponent, ClxPaginationComponent, ClxProductComponent, ClxProductDetailComponent, ClxProductQuickViewComponent, ClxProfileComponent, ClxProgressBarComponent, ClxRadioComponent, ClxRadioGroupComponent, ClxRatingComponent, ClxSearchComponent, ClxSelectComponent, ClxSkeletonComponent, ClxSliderComponent, ClxSocialIconComponent, ClxSpinnerComponent, ClxStatCardComponent, ClxStepComponent, ClxStepperComponent, ClxSwitchComponent, ClxTabDirective, ClxTableActionsComponent, ClxTableComponent, ClxTabsComponent, ClxTagComponent, ClxTextareaComponent, ClxThemeService, ClxTimelineComponent, ClxTimelineItemComponent, ClxTimepickerComponent, ClxToastComponent, ClxToastContainerComponent, ClxToastService, ClxTooltipComponent, ClxTooltipDirective, ClxTreeComponent, ClxUploadComponent, ClxWishlistComponent, ClxWizardComponent, TIMEPICKER_SIZE_MAP, detectClxCardBrand, isClxCardExpired, parseColorInput, provideCodexlyTheme, resolveColor, resolveContainerRadius, resolveRadius };
|
|
19305
|
+
export { CLX_ADDON_BORDER, CLX_ADDON_TEXT, CLX_ALERT_OPTIONS, CLX_ALERT_RESOLVE, CLX_BG_ADDON, CLX_BG_DISABLED, CLX_BG_ICON_WRAP, CLX_BG_SECTION, CLX_BG_SURFACE, CLX_BORDER_DEFAULT, CLX_BORDER_DISABLED, CLX_BORDER_MEDIUM, CLX_COLOR_HEX, CLX_COLOR_HEX_100, CLX_COLOR_MAP, CLX_FONT_CATALOG, CLX_MODAL_ANIM_CONFIG, CLX_MODAL_DATA, CLX_MODAL_REF, CLX_OPTION_DISABLED, CLX_PLACEHOLDER, CLX_RADIO_GROUP, CLX_RADIUS_MAP, CLX_TEXT_BODY, CLX_TEXT_DISABLED, CLX_TEXT_HEADING, CLX_TEXT_HINT, CLX_TEXT_IDLE, CLX_TEXT_INPUT, CLX_TEXT_LABEL, CLX_TEXT_OPTION, CLX_TEXT_SUBTITLE, CLX_TEXT_TITLE, CLX_THEME_CONFIG, CLX_THEME_DEFAULTS, CLX_TOAST_DEFAULTS, ClxAlertComponent, ClxAlertService, ClxAnimateDirective, ClxAnimateGroupDirective, ClxAnimateService, ClxAppLayoutComponent, ClxAvatarComponent, ClxBadgeComponent, ClxBrandComponent, ClxButtonComponent, ClxButtonGroupComponent, ClxCardBodyDirective, ClxCardComponent, ClxCardExpiryInputComponent, ClxCardFooterDirective, ClxCardHeaderActionsDirective, ClxCardHeaderDirective, ClxCardNumberInputComponent, ClxCardValidators, ClxCarouselComponent, ClxCarouselDirective, ClxCartComponent, ClxCartSummaryDrawer, ClxCellDirective, ClxCheckboxComponent, ClxCollapseComponent, ClxColorPickerComponent, ClxColumnDefDirective, ClxDashboardGridComponent, ClxDateRangePickerComponent, ClxDatepickerComponent, ClxDrawerComponent, ClxDrawerService, ClxEditorComponent, ClxEditorImageModalComponent, ClxEditorLinkModalComponent, ClxFabComponent, ClxFilterPanelComponent, ClxGridItemDirective, ClxHeaderCellDirective, ClxIconComponent, ClxInputComponent, ClxListComponent, ClxListItemComponent, ClxMenuComponent, ClxMenuItemComponent, ClxMenuItemTrailingDirective, ClxModalComponent, ClxModalService, ClxNativeOverlayService, ClxNavGroupComponent, ClxNotificationComponent, ClxNumberComponent, ClxOtpComponent, ClxPageEmptyComponent, ClxPageHeaderComponent, ClxPageHeaderTitleDirective, ClxPageNotFoundComponent, ClxPageServerErrorComponent, ClxPageUnauthorizedComponent, ClxPaginationComponent, ClxProductComponent, ClxProductDetailComponent, ClxProductQuickViewComponent, ClxProfileComponent, ClxProgressBarComponent, ClxRadioComponent, ClxRadioGroupComponent, ClxRatingComponent, ClxSearchComponent, ClxSelectComponent, ClxSkeletonComponent, ClxSliderComponent, ClxSocialIconComponent, ClxSpinnerComponent, ClxStatCardComponent, ClxStepComponent, ClxStepperComponent, ClxSwitchComponent, ClxTabDirective, ClxTableActionsComponent, ClxTableComponent, ClxTableProgressCellComponent, ClxTableStatusCellComponent, ClxTabsComponent, ClxTagComponent, ClxTextareaComponent, ClxThemeService, ClxTimelineComponent, ClxTimelineItemComponent, ClxTimepickerComponent, ClxToastComponent, ClxToastContainerComponent, ClxToastService, ClxTooltipComponent, ClxTooltipDirective, ClxTreeComponent, ClxUploadComponent, ClxWidgetCardComponent, ClxWishlistComponent, ClxWizardComponent, TIMEPICKER_SIZE_MAP, detectClxCardBrand, isClxCardExpired, parseColorInput, provideCodexlyTheme, resolveColor, resolveContainerRadius, resolveRadius };
|
|
18784
19306
|
//# sourceMappingURL=codexly-ui.mjs.map
|