@nucleus-suite-pe/core 2.1.0 → 2.3.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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, makeEnvironmentProviders, inject, Injector, signal, computed, Injectable, effect, DestroyRef, ElementRef, input, Directive, model, untracked, ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, TemplateRef, viewChild, output, afterNextRender, contentChildren } from '@angular/core';
|
|
2
|
+
import { InjectionToken, makeEnvironmentProviders, inject, Injector, signal, computed, Injectable, effect, Pipe, DestroyRef, ElementRef, input, Directive, model, untracked, ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, TemplateRef, viewChild, output, afterNextRender, contentChildren } from '@angular/core';
|
|
3
3
|
import { HttpContextToken, HttpClient, HttpContext, HttpErrorResponse } from '@angular/common/http';
|
|
4
4
|
import { firstValueFrom, from, switchMap, catchError, throwError } from 'rxjs';
|
|
5
5
|
import { Router, RouterLink, NavigationEnd } from '@angular/router';
|
|
@@ -24,23 +24,26 @@ import * as i5 from 'primeng/textarea';
|
|
|
24
24
|
import { TextareaModule } from 'primeng/textarea';
|
|
25
25
|
import * as i6 from 'primeng/toggleswitch';
|
|
26
26
|
import { ToggleSwitchModule } from 'primeng/toggleswitch';
|
|
27
|
+
import { CdkDrag, CdkDragHandle, CdkDropList } from '@angular/cdk/drag-drop';
|
|
27
28
|
import * as i1$2 from 'primeng/button';
|
|
28
29
|
import { ButtonModule } from 'primeng/button';
|
|
29
|
-
import * as
|
|
30
|
+
import * as i2$3 from 'primeng/paginator';
|
|
31
|
+
import { PaginatorModule } from 'primeng/paginator';
|
|
32
|
+
import * as i4 from 'primeng/table';
|
|
30
33
|
import { TableModule } from 'primeng/table';
|
|
31
|
-
import * as
|
|
34
|
+
import * as i5$1 from 'primeng/tag';
|
|
32
35
|
import { TagModule } from 'primeng/tag';
|
|
33
|
-
import * as
|
|
36
|
+
import * as i6$1 from 'primeng/tooltip';
|
|
34
37
|
import { TooltipModule } from 'primeng/tooltip';
|
|
35
38
|
import * as i1$3 from 'primeng/avatar';
|
|
36
39
|
import { AvatarModule } from 'primeng/avatar';
|
|
37
|
-
import * as i2$
|
|
40
|
+
import * as i2$4 from 'primeng/breadcrumb';
|
|
38
41
|
import { BreadcrumbModule } from 'primeng/breadcrumb';
|
|
39
42
|
import * as i4$1 from 'primeng/confirmdialog';
|
|
40
43
|
import { ConfirmDialogModule } from 'primeng/confirmdialog';
|
|
41
44
|
import * as i5$2 from 'primeng/toast';
|
|
42
45
|
import { ToastModule } from 'primeng/toast';
|
|
43
|
-
import * as i6$
|
|
46
|
+
import * as i6$2 from 'primeng/drawer';
|
|
44
47
|
import { DrawerModule } from 'primeng/drawer';
|
|
45
48
|
|
|
46
49
|
const NUCLEUS_CONFIG = new InjectionToken('NUCLEUS_CONFIG');
|
|
@@ -361,6 +364,10 @@ const COMMON_COPY = {
|
|
|
361
364
|
noColor: 'Sin color',
|
|
362
365
|
searchIcon: 'Busca un icono',
|
|
363
366
|
noMatches: 'Ningún icono coincide',
|
|
367
|
+
reorderHandle: 'Arrastra para cambiar el orden',
|
|
368
|
+
noResults: 'Ningún registro coincide con la búsqueda',
|
|
369
|
+
viewGrid: 'Vista en mosaico',
|
|
370
|
+
viewRows: 'Vista en filas',
|
|
364
371
|
sessionExpired: 'Tu sesión expiró. Vuelve a iniciar sesión.',
|
|
365
372
|
errorNetwork: 'No se pudo conectar con el servidor. Revisa tu conexión o inténtalo en unos minutos.',
|
|
366
373
|
errorTimeout: 'El servidor tardó demasiado en responder. Inténtalo de nuevo.',
|
|
@@ -379,6 +386,10 @@ const COMMON_COPY = {
|
|
|
379
386
|
noColor: 'No colour',
|
|
380
387
|
searchIcon: 'Search an icon',
|
|
381
388
|
noMatches: 'No icon matches',
|
|
389
|
+
reorderHandle: 'Drag to reorder',
|
|
390
|
+
noResults: 'No records match your search',
|
|
391
|
+
viewGrid: 'Tile view',
|
|
392
|
+
viewRows: 'Row view',
|
|
382
393
|
sessionExpired: 'Your session expired. Sign in again.',
|
|
383
394
|
errorNetwork: 'Could not reach the server. Check your connection or try again in a moment.',
|
|
384
395
|
errorTimeout: 'The server took too long to answer. Try again.',
|
|
@@ -488,8 +499,12 @@ class SessionService {
|
|
|
488
499
|
if (!me)
|
|
489
500
|
return [];
|
|
490
501
|
return [
|
|
491
|
-
...me.ownedCompanies
|
|
492
|
-
|
|
502
|
+
...me.ownedCompanies
|
|
503
|
+
.filter((company) => company.isActive)
|
|
504
|
+
.map((company) => toOption(company, 'owner')),
|
|
505
|
+
...me.sharedCompanies
|
|
506
|
+
.filter((company) => company.isActive)
|
|
507
|
+
.map((company) => toOption(company, 'collaborator')),
|
|
493
508
|
];
|
|
494
509
|
}, ...(ngDevMode ? [{ debugName: "companyOptions" }] : /* istanbul ignore next */ []));
|
|
495
510
|
companyId = computed(() => {
|
|
@@ -829,7 +844,7 @@ function isoDay(value) {
|
|
|
829
844
|
const date = String(parsed.getDate()).padStart(2, '0');
|
|
830
845
|
return `${year}-${month}-${date}`;
|
|
831
846
|
}
|
|
832
|
-
function toNumber(value) {
|
|
847
|
+
function toNumber$1(value) {
|
|
833
848
|
const parsed = typeof value === 'number' ? value : Number(value);
|
|
834
849
|
return Number.isFinite(parsed) ? parsed : 0;
|
|
835
850
|
}
|
|
@@ -856,6 +871,82 @@ function endOfDayUtc(value) {
|
|
|
856
871
|
return `${isoDay(nucleusParseDate(value))}T23:59:59.999Z`;
|
|
857
872
|
}
|
|
858
873
|
|
|
874
|
+
const COMPACT_LOCALES = { es: 'es-PE', en: 'en-US' };
|
|
875
|
+
const BYTE_UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
|
876
|
+
function trim(value) {
|
|
877
|
+
return value.endsWith('.0') ? value.slice(0, -2) : value;
|
|
878
|
+
}
|
|
879
|
+
function compactNumber(value) {
|
|
880
|
+
if (!Number.isFinite(value))
|
|
881
|
+
return '—';
|
|
882
|
+
const abs = Math.abs(value);
|
|
883
|
+
const locale = COMPACT_LOCALES[nucleusLang()] ?? 'en-US';
|
|
884
|
+
let digits = 0;
|
|
885
|
+
if (abs >= 1000) {
|
|
886
|
+
const unit = 1000 ** Math.floor(Math.log10(abs) / 3);
|
|
887
|
+
digits = Math.abs(value / unit) < 10 ? 1 : 0;
|
|
888
|
+
}
|
|
889
|
+
const text = new Intl.NumberFormat(locale, {
|
|
890
|
+
notation: 'compact',
|
|
891
|
+
compactDisplay: 'short',
|
|
892
|
+
maximumFractionDigits: digits,
|
|
893
|
+
}).format(value);
|
|
894
|
+
return text.replace(/(\d)\s?k$/, '$1 K');
|
|
895
|
+
}
|
|
896
|
+
function compactBytes(value) {
|
|
897
|
+
if (!Number.isFinite(value) || value <= 0)
|
|
898
|
+
return '0 B';
|
|
899
|
+
const index = Math.min(Math.floor(Math.log(value) / Math.log(1024)), BYTE_UNITS.length - 1);
|
|
900
|
+
const scaled = value / 1024 ** index;
|
|
901
|
+
const digits = index === 0 ? 0 : scaled < 10 ? 1 : 0;
|
|
902
|
+
return `${trim(scaled.toFixed(digits))} ${BYTE_UNITS[index]}`;
|
|
903
|
+
}
|
|
904
|
+
function compactMegabytes(value) {
|
|
905
|
+
return compactBytes(value * 1024 * 1024);
|
|
906
|
+
}
|
|
907
|
+
function toNumber(value) {
|
|
908
|
+
if (value === null || value === undefined || value === '')
|
|
909
|
+
return null;
|
|
910
|
+
const parsed = typeof value === 'number' ? value : Number(value);
|
|
911
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
912
|
+
}
|
|
913
|
+
class NucleusCompact {
|
|
914
|
+
transform(value, fallback = '—') {
|
|
915
|
+
const parsed = toNumber(value);
|
|
916
|
+
return parsed === null ? fallback : compactNumber(parsed);
|
|
917
|
+
}
|
|
918
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusCompact, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
919
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.22", ngImport: i0, type: NucleusCompact, isStandalone: true, name: "nucleusCompact" });
|
|
920
|
+
}
|
|
921
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusCompact, decorators: [{
|
|
922
|
+
type: Pipe,
|
|
923
|
+
args: [{ name: 'nucleusCompact' }]
|
|
924
|
+
}] });
|
|
925
|
+
class NucleusBytes {
|
|
926
|
+
transform(value, fallback = '—') {
|
|
927
|
+
const parsed = toNumber(value);
|
|
928
|
+
return parsed === null ? fallback : compactBytes(parsed);
|
|
929
|
+
}
|
|
930
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusBytes, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
931
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.22", ngImport: i0, type: NucleusBytes, isStandalone: true, name: "nucleusBytes" });
|
|
932
|
+
}
|
|
933
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusBytes, decorators: [{
|
|
934
|
+
type: Pipe,
|
|
935
|
+
args: [{ name: 'nucleusBytes' }]
|
|
936
|
+
}] });
|
|
937
|
+
class NucleusMegabytes {
|
|
938
|
+
transform(value, fallback = '—') {
|
|
939
|
+
const parsed = toNumber(value);
|
|
940
|
+
return parsed === null ? fallback : compactMegabytes(parsed);
|
|
941
|
+
}
|
|
942
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusMegabytes, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
943
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.22", ngImport: i0, type: NucleusMegabytes, isStandalone: true, name: "nucleusMegabytes" });
|
|
944
|
+
}
|
|
945
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusMegabytes, decorators: [{
|
|
946
|
+
type: Pipe,
|
|
947
|
+
args: [{ name: 'nucleusMegabytes' }]
|
|
948
|
+
}] });
|
|
949
|
+
|
|
859
950
|
const FIELD_TARGETS = [
|
|
860
951
|
'input:not([type="hidden"]):not([disabled])',
|
|
861
952
|
'textarea:not([disabled])',
|
|
@@ -1487,12 +1578,12 @@ const FRAMES = [
|
|
|
1487
1578
|
starfield: true,
|
|
1488
1579
|
accent: 'violet',
|
|
1489
1580
|
tokens: {
|
|
1490
|
-
bg: '#
|
|
1491
|
-
raised: '#
|
|
1581
|
+
bg: '#1f1646',
|
|
1582
|
+
raised: '#2c2160',
|
|
1492
1583
|
ink: '#ece9fb',
|
|
1493
|
-
muted: '#
|
|
1494
|
-
line: '#
|
|
1495
|
-
glow: '#
|
|
1584
|
+
muted: '#9690af',
|
|
1585
|
+
line: '#403863',
|
|
1586
|
+
glow: '#a78bfa',
|
|
1496
1587
|
},
|
|
1497
1588
|
},
|
|
1498
1589
|
{
|
|
@@ -1501,12 +1592,12 @@ const FRAMES = [
|
|
|
1501
1592
|
starfield: false,
|
|
1502
1593
|
accent: 'blue',
|
|
1503
1594
|
tokens: {
|
|
1504
|
-
bg: '#
|
|
1505
|
-
raised: '#
|
|
1506
|
-
ink: '#
|
|
1507
|
-
muted: '#
|
|
1508
|
-
line: '#
|
|
1509
|
-
glow: '#
|
|
1595
|
+
bg: '#12244a',
|
|
1596
|
+
raised: '#1b3263',
|
|
1597
|
+
ink: '#e6edf9',
|
|
1598
|
+
muted: '#95a1b7',
|
|
1599
|
+
line: '#344466',
|
|
1600
|
+
glow: '#60a5fa',
|
|
1510
1601
|
},
|
|
1511
1602
|
},
|
|
1512
1603
|
{
|
|
@@ -1515,12 +1606,12 @@ const FRAMES = [
|
|
|
1515
1606
|
starfield: false,
|
|
1516
1607
|
accent: 'cyan',
|
|
1517
1608
|
tokens: {
|
|
1518
|
-
bg: '#
|
|
1519
|
-
raised: '#
|
|
1520
|
-
ink: '#
|
|
1521
|
-
muted: '#
|
|
1522
|
-
line: '#
|
|
1523
|
-
glow: '#
|
|
1609
|
+
bg: '#0b3a44',
|
|
1610
|
+
raised: '#124d59',
|
|
1611
|
+
ink: '#e3f3f6',
|
|
1612
|
+
muted: '#a2bcc1',
|
|
1613
|
+
line: '#2e5860',
|
|
1614
|
+
glow: '#22d3ee',
|
|
1524
1615
|
},
|
|
1525
1616
|
},
|
|
1526
1617
|
{
|
|
@@ -1529,26 +1620,26 @@ const FRAMES = [
|
|
|
1529
1620
|
starfield: false,
|
|
1530
1621
|
accent: 'green',
|
|
1531
1622
|
tokens: {
|
|
1532
|
-
bg: '#
|
|
1533
|
-
raised: '#
|
|
1534
|
-
ink: '#
|
|
1535
|
-
muted: '#
|
|
1536
|
-
line: '#
|
|
1537
|
-
glow: '#
|
|
1623
|
+
bg: '#0f3d2b',
|
|
1624
|
+
raised: '#18523b',
|
|
1625
|
+
ink: '#e6f2eb',
|
|
1626
|
+
muted: '#aabfb5',
|
|
1627
|
+
line: '#315a4a',
|
|
1628
|
+
glow: '#4ade80',
|
|
1538
1629
|
},
|
|
1539
1630
|
},
|
|
1540
1631
|
{
|
|
1541
1632
|
id: 'plum',
|
|
1542
1633
|
scheme: 'dark',
|
|
1543
1634
|
starfield: false,
|
|
1544
|
-
accent: '
|
|
1635
|
+
accent: 'plum',
|
|
1545
1636
|
tokens: {
|
|
1546
|
-
bg: '#
|
|
1547
|
-
raised: '#
|
|
1548
|
-
ink: '#
|
|
1549
|
-
muted: '#
|
|
1550
|
-
line: '#
|
|
1551
|
-
glow: '#
|
|
1637
|
+
bg: '#3a1a4f',
|
|
1638
|
+
raised: '#4d2666',
|
|
1639
|
+
ink: '#f3e8fa',
|
|
1640
|
+
muted: '#b09ebc',
|
|
1641
|
+
line: '#583b6a',
|
|
1642
|
+
glow: '#c084fc',
|
|
1552
1643
|
},
|
|
1553
1644
|
},
|
|
1554
1645
|
{
|
|
@@ -1557,12 +1648,12 @@ const FRAMES = [
|
|
|
1557
1648
|
starfield: false,
|
|
1558
1649
|
accent: 'red',
|
|
1559
1650
|
tokens: {
|
|
1560
|
-
bg: '#
|
|
1561
|
-
raised: '#
|
|
1562
|
-
ink: '#
|
|
1563
|
-
muted: '#
|
|
1564
|
-
line: '#
|
|
1565
|
-
glow: '#
|
|
1651
|
+
bg: '#4a1519',
|
|
1652
|
+
raised: '#611f24',
|
|
1653
|
+
ink: '#fbe9e9',
|
|
1654
|
+
muted: '#b8989a',
|
|
1655
|
+
line: '#66373a',
|
|
1656
|
+
glow: '#f87171',
|
|
1566
1657
|
},
|
|
1567
1658
|
},
|
|
1568
1659
|
{
|
|
@@ -1571,12 +1662,12 @@ const FRAMES = [
|
|
|
1571
1662
|
starfield: false,
|
|
1572
1663
|
accent: 'amber',
|
|
1573
1664
|
tokens: {
|
|
1574
|
-
bg: '#
|
|
1575
|
-
raised: '#
|
|
1576
|
-
ink: '#
|
|
1577
|
-
muted: '#
|
|
1578
|
-
line: '#
|
|
1579
|
-
glow: '#
|
|
1665
|
+
bg: '#3d2d12',
|
|
1666
|
+
raised: '#52401c',
|
|
1667
|
+
ink: '#f7efdd',
|
|
1668
|
+
muted: '#bbb19c',
|
|
1669
|
+
line: '#5b4c32',
|
|
1670
|
+
glow: '#fbbf24',
|
|
1580
1671
|
},
|
|
1581
1672
|
},
|
|
1582
1673
|
{
|
|
@@ -1585,12 +1676,12 @@ const FRAMES = [
|
|
|
1585
1676
|
starfield: false,
|
|
1586
1677
|
accent: 'blue',
|
|
1587
1678
|
tokens: {
|
|
1588
|
-
bg: '#
|
|
1589
|
-
raised: '#
|
|
1590
|
-
ink: '#
|
|
1591
|
-
muted: '#
|
|
1592
|
-
line: '#
|
|
1593
|
-
glow: '#
|
|
1679
|
+
bg: '#27313f',
|
|
1680
|
+
raised: '#354254',
|
|
1681
|
+
ink: '#e8edf3',
|
|
1682
|
+
muted: '#aab1b9',
|
|
1683
|
+
line: '#464f5c',
|
|
1684
|
+
glow: '#60a5fa',
|
|
1594
1685
|
},
|
|
1595
1686
|
},
|
|
1596
1687
|
{
|
|
@@ -1601,10 +1692,10 @@ const FRAMES = [
|
|
|
1601
1692
|
tokens: {
|
|
1602
1693
|
bg: '#101318',
|
|
1603
1694
|
raised: '#1b2129',
|
|
1604
|
-
ink: '#
|
|
1605
|
-
muted: '#
|
|
1606
|
-
line: '#
|
|
1607
|
-
glow: '#
|
|
1695
|
+
ink: '#e9edf2',
|
|
1696
|
+
muted: '#85898e',
|
|
1697
|
+
line: '#33363b',
|
|
1698
|
+
glow: '#94a3b8',
|
|
1608
1699
|
},
|
|
1609
1700
|
},
|
|
1610
1701
|
{
|
|
@@ -1615,10 +1706,10 @@ const FRAMES = [
|
|
|
1615
1706
|
tokens: {
|
|
1616
1707
|
bg: '#17171a',
|
|
1617
1708
|
raised: '#232327',
|
|
1618
|
-
ink: '#
|
|
1619
|
-
muted: '#
|
|
1620
|
-
line: '#
|
|
1621
|
-
glow: '#
|
|
1709
|
+
ink: '#ededf0',
|
|
1710
|
+
muted: '#8b8b8e',
|
|
1711
|
+
line: '#39393c',
|
|
1712
|
+
glow: '#a1a1aa',
|
|
1622
1713
|
},
|
|
1623
1714
|
},
|
|
1624
1715
|
{
|
|
@@ -1630,9 +1721,9 @@ const FRAMES = [
|
|
|
1630
1721
|
bg: '#ffffff',
|
|
1631
1722
|
raised: '#f1f0f5',
|
|
1632
1723
|
ink: '#16151d',
|
|
1633
|
-
muted: '#
|
|
1634
|
-
line: '#
|
|
1635
|
-
glow: '#
|
|
1724
|
+
muted: '#6a696e',
|
|
1725
|
+
line: '#dadadb',
|
|
1726
|
+
glow: '#7c3aed',
|
|
1636
1727
|
},
|
|
1637
1728
|
},
|
|
1638
1729
|
{
|
|
@@ -1644,9 +1735,65 @@ const FRAMES = [
|
|
|
1644
1735
|
bg: '#eef1f6',
|
|
1645
1736
|
raised: '#e2e7ef',
|
|
1646
1737
|
ink: '#141a24',
|
|
1647
|
-
muted: '#
|
|
1648
|
-
line: '#
|
|
1649
|
-
glow: '#
|
|
1738
|
+
muted: '#5e636b',
|
|
1739
|
+
line: '#cbcfd4',
|
|
1740
|
+
glow: '#2563eb',
|
|
1741
|
+
},
|
|
1742
|
+
},
|
|
1743
|
+
{
|
|
1744
|
+
id: 'studio',
|
|
1745
|
+
scheme: 'light',
|
|
1746
|
+
starfield: false,
|
|
1747
|
+
accent: 'amber',
|
|
1748
|
+
tokens: {
|
|
1749
|
+
bg: '#f1cba0',
|
|
1750
|
+
raised: '#f6dfc4',
|
|
1751
|
+
ink: '#3b2f24',
|
|
1752
|
+
muted: '#675442',
|
|
1753
|
+
line: '#d4b28c',
|
|
1754
|
+
glow: '#7a4a0a',
|
|
1755
|
+
},
|
|
1756
|
+
},
|
|
1757
|
+
{
|
|
1758
|
+
id: 'sage',
|
|
1759
|
+
scheme: 'light',
|
|
1760
|
+
starfield: false,
|
|
1761
|
+
accent: 'green',
|
|
1762
|
+
tokens: {
|
|
1763
|
+
bg: '#d3e4d6',
|
|
1764
|
+
raised: '#e3efe5',
|
|
1765
|
+
ink: '#1c2b20',
|
|
1766
|
+
muted: '#536257',
|
|
1767
|
+
line: '#b6c6b9',
|
|
1768
|
+
glow: '#15803d',
|
|
1769
|
+
},
|
|
1770
|
+
},
|
|
1771
|
+
{
|
|
1772
|
+
id: 'sky',
|
|
1773
|
+
scheme: 'light',
|
|
1774
|
+
starfield: false,
|
|
1775
|
+
accent: 'blue',
|
|
1776
|
+
tokens: {
|
|
1777
|
+
bg: '#cfe0f5',
|
|
1778
|
+
raised: '#e0ebf9',
|
|
1779
|
+
ink: '#14213a',
|
|
1780
|
+
muted: '#505e76',
|
|
1781
|
+
line: '#b1c1d7',
|
|
1782
|
+
glow: '#2563eb',
|
|
1783
|
+
},
|
|
1784
|
+
},
|
|
1785
|
+
{
|
|
1786
|
+
id: 'lavender',
|
|
1787
|
+
scheme: 'light',
|
|
1788
|
+
starfield: false,
|
|
1789
|
+
accent: 'violet',
|
|
1790
|
+
tokens: {
|
|
1791
|
+
bg: '#ddd6f3',
|
|
1792
|
+
raised: '#eae5f8',
|
|
1793
|
+
ink: '#221a3d',
|
|
1794
|
+
muted: '#5e5677',
|
|
1795
|
+
line: '#bfb8d6',
|
|
1796
|
+
glow: '#7c3aed',
|
|
1650
1797
|
},
|
|
1651
1798
|
},
|
|
1652
1799
|
];
|
|
@@ -1674,6 +1821,29 @@ const CANVASES = [
|
|
|
1674
1821
|
warning: '#8a5a00',
|
|
1675
1822
|
},
|
|
1676
1823
|
},
|
|
1824
|
+
{
|
|
1825
|
+
id: 'soft',
|
|
1826
|
+
tokens: {
|
|
1827
|
+
bg: '#d9dce3',
|
|
1828
|
+
surface: '#eef0f4',
|
|
1829
|
+
surfaceAlt: '#dfe3ea',
|
|
1830
|
+
text: '#16151d',
|
|
1831
|
+
textMuted: '#545a66',
|
|
1832
|
+
border: '#c0c6d1',
|
|
1833
|
+
},
|
|
1834
|
+
effects: {
|
|
1835
|
+
shadowOne: '0 1px 2px rgb(16 20 30 / 8%), 0 2px 8px rgb(16 20 30 / 6%)',
|
|
1836
|
+
shadowTwo: '0 4px 12px rgb(16 20 30 / 10%), 0 12px 32px rgb(16 20 30 / 8%)',
|
|
1837
|
+
wash: 0.1,
|
|
1838
|
+
washStrong: 0.18,
|
|
1839
|
+
headerBg: '#c6ccd8',
|
|
1840
|
+
headerInk: '#333a47',
|
|
1841
|
+
headerLine: '#aeb6c4',
|
|
1842
|
+
danger: '#b02121',
|
|
1843
|
+
success: '#136b35',
|
|
1844
|
+
warning: '#8a5a00',
|
|
1845
|
+
},
|
|
1846
|
+
},
|
|
1677
1847
|
{
|
|
1678
1848
|
id: 'dim',
|
|
1679
1849
|
tokens: {
|
|
@@ -1722,15 +1892,20 @@ const CANVASES = [
|
|
|
1722
1892
|
},
|
|
1723
1893
|
];
|
|
1724
1894
|
const ACCENTS = [
|
|
1725
|
-
{ id: 'violet', light: '#
|
|
1726
|
-
{ id: 'blue', light: '#
|
|
1727
|
-
{ id: 'cyan', light: '#
|
|
1728
|
-
{ id: 'green', light: '#
|
|
1729
|
-
{ id: 'lime', light: '#4d7c0f', dark: '#
|
|
1730
|
-
{ id: 'amber', light: '#
|
|
1731
|
-
{ id: 'orange', light: '#
|
|
1732
|
-
{ id: 'rose', light: '#
|
|
1733
|
-
{ id: 'red', light: '#
|
|
1895
|
+
{ id: 'violet', light: '#7c3aed', dark: '#a78bfa' },
|
|
1896
|
+
{ id: 'blue', light: '#2563eb', dark: '#60a5fa' },
|
|
1897
|
+
{ id: 'cyan', light: '#0e7490', dark: '#22d3ee' },
|
|
1898
|
+
{ id: 'green', light: '#15803d', dark: '#4ade80' },
|
|
1899
|
+
{ id: 'lime', light: '#4d7c0f', dark: '#a3e635' },
|
|
1900
|
+
{ id: 'amber', light: '#b45309', dark: '#fbbf24' },
|
|
1901
|
+
{ id: 'orange', light: '#c2410c', dark: '#fb923c' },
|
|
1902
|
+
{ id: 'rose', light: '#e11d48', dark: '#fb7185' },
|
|
1903
|
+
{ id: 'red', light: '#dc2626', dark: '#f87171' },
|
|
1904
|
+
{ id: 'indigo', light: '#4f46e5', dark: '#818cf8' },
|
|
1905
|
+
{ id: 'teal', light: '#0f766e', dark: '#2dd4bf' },
|
|
1906
|
+
{ id: 'plum', light: '#9333ea', dark: '#c084fc' },
|
|
1907
|
+
{ id: 'slate', light: '#64748b', dark: '#94a3b8' },
|
|
1908
|
+
{ id: 'graphite', light: '#71717a', dark: '#a1a1aa' },
|
|
1734
1909
|
];
|
|
1735
1910
|
const DENSITIES = [
|
|
1736
1911
|
{ id: 'comfortable', scale: 1 },
|
|
@@ -1791,10 +1966,10 @@ function resolveAccent(frame, preference) {
|
|
|
1791
1966
|
return accentById(preference === 'auto' ? frame.accent : preference);
|
|
1792
1967
|
}
|
|
1793
1968
|
function accentOn(accent, canvas) {
|
|
1794
|
-
return canvas
|
|
1969
|
+
return isDarkCanvas(canvas) ? accent.dark : accent.light;
|
|
1795
1970
|
}
|
|
1796
1971
|
function isDarkCanvas(canvas) {
|
|
1797
|
-
return canvas
|
|
1972
|
+
return canvas === 'dim' || canvas === 'dark';
|
|
1798
1973
|
}
|
|
1799
1974
|
function auditAppearance() {
|
|
1800
1975
|
const issues = [];
|
|
@@ -1843,6 +2018,10 @@ const FRAMES_ES = {
|
|
|
1843
2018
|
graphite: 'Grafito',
|
|
1844
2019
|
paper: 'Papel',
|
|
1845
2020
|
mist: 'Bruma',
|
|
2021
|
+
studio: 'Estudio',
|
|
2022
|
+
sage: 'Salvia',
|
|
2023
|
+
sky: 'Cielo',
|
|
2024
|
+
lavender: 'Lavanda',
|
|
1846
2025
|
};
|
|
1847
2026
|
const FRAMES_EN = {
|
|
1848
2027
|
nucleus: 'Nucleus',
|
|
@@ -1857,6 +2036,10 @@ const FRAMES_EN = {
|
|
|
1857
2036
|
graphite: 'Graphite',
|
|
1858
2037
|
paper: 'Paper',
|
|
1859
2038
|
mist: 'Mist',
|
|
2039
|
+
studio: 'Studio',
|
|
2040
|
+
sage: 'Sage',
|
|
2041
|
+
sky: 'Sky',
|
|
2042
|
+
lavender: 'Lavender',
|
|
1860
2043
|
};
|
|
1861
2044
|
const ACCENTS_ES = {
|
|
1862
2045
|
auto: 'Del marco',
|
|
@@ -1869,6 +2052,11 @@ const ACCENTS_ES = {
|
|
|
1869
2052
|
orange: 'Naranja',
|
|
1870
2053
|
rose: 'Rosa',
|
|
1871
2054
|
red: 'Rojo',
|
|
2055
|
+
slate: 'Pizarra',
|
|
2056
|
+
graphite: 'Grafito',
|
|
2057
|
+
indigo: 'Índigo',
|
|
2058
|
+
teal: 'Verde azulado',
|
|
2059
|
+
plum: 'Ciruela',
|
|
1872
2060
|
};
|
|
1873
2061
|
const ACCENTS_EN = {
|
|
1874
2062
|
auto: 'From the frame',
|
|
@@ -1881,6 +2069,11 @@ const ACCENTS_EN = {
|
|
|
1881
2069
|
orange: 'Orange',
|
|
1882
2070
|
rose: 'Rose',
|
|
1883
2071
|
red: 'Red',
|
|
2072
|
+
slate: 'Slate',
|
|
2073
|
+
graphite: 'Graphite',
|
|
2074
|
+
indigo: 'Indigo',
|
|
2075
|
+
teal: 'Teal',
|
|
2076
|
+
plum: 'Plum',
|
|
1884
2077
|
};
|
|
1885
2078
|
const THEME_COPY = {
|
|
1886
2079
|
es: {
|
|
@@ -1894,7 +2087,13 @@ const THEME_COPY = {
|
|
|
1894
2087
|
densityTitle: 'Densidad',
|
|
1895
2088
|
densityHint: 'Cuántas filas quieres ver de una sola pasada.',
|
|
1896
2089
|
frames: FRAMES_ES,
|
|
1897
|
-
canvases: {
|
|
2090
|
+
canvases: {
|
|
2091
|
+
light: 'Claro',
|
|
2092
|
+
soft: 'Suave',
|
|
2093
|
+
dim: 'Atenuado',
|
|
2094
|
+
dark: 'Oscuro',
|
|
2095
|
+
system: 'Del sistema',
|
|
2096
|
+
},
|
|
1898
2097
|
accents: ACCENTS_ES,
|
|
1899
2098
|
densities: { comfortable: 'Cómoda', compact: 'Compacta' },
|
|
1900
2099
|
},
|
|
@@ -1909,7 +2108,13 @@ const THEME_COPY = {
|
|
|
1909
2108
|
densityTitle: 'Density',
|
|
1910
2109
|
densityHint: 'How many rows you want to see at a glance.',
|
|
1911
2110
|
frames: FRAMES_EN,
|
|
1912
|
-
canvases: {
|
|
2111
|
+
canvases: {
|
|
2112
|
+
light: 'Light',
|
|
2113
|
+
soft: 'Soft',
|
|
2114
|
+
dim: 'Dim',
|
|
2115
|
+
dark: 'Dark',
|
|
2116
|
+
system: 'System',
|
|
2117
|
+
},
|
|
1913
2118
|
accents: ACCENTS_EN,
|
|
1914
2119
|
densities: { comfortable: 'Comfortable', compact: 'Compact' },
|
|
1915
2120
|
},
|
|
@@ -2021,6 +2226,9 @@ class ThemeService {
|
|
|
2021
2226
|
root.style.setProperty(`--ns-frame-${kebab(name)}`, value);
|
|
2022
2227
|
}
|
|
2023
2228
|
root.style.setProperty('--ns-frame-on-glow', readableOn(frame.tokens.glow));
|
|
2229
|
+
const navActive = readableOn(frame.tokens.bg);
|
|
2230
|
+
root.style.setProperty('--ns-nav-active-bg', navActive);
|
|
2231
|
+
root.style.setProperty('--ns-nav-active-ink', readableOn(navActive));
|
|
2024
2232
|
for (const [name, value] of Object.entries(canvas.tokens)) {
|
|
2025
2233
|
root.style.setProperty(`--ac-${kebab(name)}`, value);
|
|
2026
2234
|
}
|
|
@@ -2297,7 +2505,7 @@ class NucleusCard {
|
|
|
2297
2505
|
<div class="actions">
|
|
2298
2506
|
<ng-content select="[nucleusCardActions]" />
|
|
2299
2507
|
</div>
|
|
2300
|
-
`, isInline: true, styles: [":host{display:block;padding:22px 24px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}:host([data-size=\"sm\"]){max-width:34rem}:host([data-size=\"md\"]){max-width:48rem}:host([data-size=\"lg\"]){max-width:64rem}.head{margin-bottom:18px}h2{margin:0;font-size:16px;font-weight:
|
|
2508
|
+
`, isInline: true, styles: [":host{display:block;padding:22px 24px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}:host([data-size=\"sm\"]){max-width:34rem}:host([data-size=\"md\"]){max-width:48rem}:host([data-size=\"lg\"]){max-width:64rem}.head{margin-bottom:18px}h2{margin:0;font-size:16px;font-weight:var(--ns-weight-heading)}.subtitle{margin:4px 0 0;color:var(--ac-text-muted);font-size:13px}.body{display:contents}.skeleton-rows{display:grid}.skeleton-row{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:13px 0;border-bottom:1px solid color-mix(in srgb,var(--ac-border) 60%,transparent)}.skeleton-row:last-child{border-bottom:0}.actions{display:flex;justify-content:flex-end;gap:8px;margin-top:20px}.actions:empty{display:none}\n"], dependencies: [{ kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2301
2509
|
}
|
|
2302
2510
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusCard, decorators: [{
|
|
2303
2511
|
type: Component,
|
|
@@ -2331,7 +2539,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
2331
2539
|
<div class="actions">
|
|
2332
2540
|
<ng-content select="[nucleusCardActions]" />
|
|
2333
2541
|
</div>
|
|
2334
|
-
`, styles: [":host{display:block;padding:22px 24px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}:host([data-size=\"sm\"]){max-width:34rem}:host([data-size=\"md\"]){max-width:48rem}:host([data-size=\"lg\"]){max-width:64rem}.head{margin-bottom:18px}h2{margin:0;font-size:16px;font-weight:
|
|
2542
|
+
`, styles: [":host{display:block;padding:22px 24px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}:host([data-size=\"sm\"]){max-width:34rem}:host([data-size=\"md\"]){max-width:48rem}:host([data-size=\"lg\"]){max-width:64rem}.head{margin-bottom:18px}h2{margin:0;font-size:16px;font-weight:var(--ns-weight-heading)}.subtitle{margin:4px 0 0;color:var(--ac-text-muted);font-size:13px}.body{display:contents}.skeleton-rows{display:grid}.skeleton-row{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:13px 0;border-bottom:1px solid color-mix(in srgb,var(--ac-border) 60%,transparent)}.skeleton-row:last-child{border-bottom:0}.actions{display:flex;justify-content:flex-end;gap:8px;margin-top:20px}.actions:empty{display:none}\n"] }]
|
|
2335
2543
|
}], propDecorators: { heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], skeletonRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "skeletonRows", required: false }] }] } });
|
|
2336
2544
|
|
|
2337
2545
|
class NucleusMetrics {
|
|
@@ -2351,10 +2559,17 @@ class NucleusMetric {
|
|
|
2351
2559
|
hint = input('', ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
2352
2560
|
link = input('', ...(ngDevMode ? [{ debugName: "link" }] : /* istanbul ignore next */ []));
|
|
2353
2561
|
tone = input('plain', ...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
|
|
2562
|
+
progress = input(null, ...(ngDevMode ? [{ debugName: "progress" }] : /* istanbul ignore next */ []));
|
|
2563
|
+
bar = computed(() => {
|
|
2564
|
+
const value = this.progress();
|
|
2565
|
+
if (value === null || !Number.isFinite(value))
|
|
2566
|
+
return null;
|
|
2567
|
+
return Math.min(Math.max(value, 0), 100);
|
|
2568
|
+
}, ...(ngDevMode ? [{ debugName: "bar" }] : /* istanbul ignore next */ []));
|
|
2354
2569
|
loading = input(null, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
2355
2570
|
busy = computed(() => this.loading() ?? this.group?.loading() ?? false, ...(ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []));
|
|
2356
2571
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusMetric, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2357
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: NucleusMetric, isStandalone: true, selector: "nucleus-metric", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-tone": "tone() === 'accent' ? 'accent' : null" } }, ngImport: i0, template: `
|
|
2572
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: NucleusMetric, isStandalone: true, selector: "nucleus-metric", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, progress: { classPropertyName: "progress", publicName: "progress", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-tone": "tone() === 'accent' ? 'accent' : null" } }, ngImport: i0, template: `
|
|
2358
2573
|
@if (link().length) {
|
|
2359
2574
|
<a class="tile" [routerLink]="link()">
|
|
2360
2575
|
<ng-container [ngTemplateOutlet]="body" />
|
|
@@ -2375,12 +2590,15 @@ class NucleusMetric {
|
|
|
2375
2590
|
}
|
|
2376
2591
|
} @else {
|
|
2377
2592
|
<strong class="value">{{ value() }}</strong>
|
|
2593
|
+
@if (bar() !== null) {
|
|
2594
|
+
<span class="track"><span class="fill" [style.width.%]="bar()"></span></span>
|
|
2595
|
+
}
|
|
2378
2596
|
@if (hint().length) {
|
|
2379
2597
|
<small class="hint">{{ hint() }}</small>
|
|
2380
2598
|
}
|
|
2381
2599
|
}
|
|
2382
2600
|
</ng-template>
|
|
2383
|
-
`, isInline: true, styles: [":host{display:block}.tile{display:grid;align-content:start;gap:5px;height:100%;padding:18px 20px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);color:inherit;text-decoration:none;transition:border-color .14s ease}a.tile:hover{border-color:var(--ac-accent)}:host([data-tone=\"accent\"]) .tile{border-color:var(--ac-accent)}.label{color:var(--ac-text-muted);font-size:11px;font-weight:
|
|
2601
|
+
`, isInline: true, styles: [":host{display:block}.track{overflow:hidden;height:4px;margin-top:3px;border-radius:999px;background:color-mix(in srgb,var(--ac-text) 12%,transparent)}.fill{display:block;height:4px;border-radius:999px;background:var(--ac-accent)}.tile{display:grid;align-content:start;gap:5px;height:100%;padding:18px 20px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);color:inherit;text-decoration:none;transition:border-color .14s ease}a.tile:hover{border-color:var(--ac-accent)}:host([data-tone=\"accent\"]) .tile{border-color:var(--ac-accent)}.label{color:var(--ac-text-muted);font-size:11px;font-weight:var(--ns-weight-heading);letter-spacing:.04em;text-transform:uppercase}.value{font-size:26px;font-variant-numeric:tabular-nums;line-height:1}.hint{color:var(--ac-text-muted);font-size:12px}.value-skeleton{margin:1px 0 2px}.hint-skeleton{margin:3px 0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2384
2602
|
}
|
|
2385
2603
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusMetric, decorators: [{
|
|
2386
2604
|
type: Component,
|
|
@@ -2405,13 +2623,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
2405
2623
|
}
|
|
2406
2624
|
} @else {
|
|
2407
2625
|
<strong class="value">{{ value() }}</strong>
|
|
2626
|
+
@if (bar() !== null) {
|
|
2627
|
+
<span class="track"><span class="fill" [style.width.%]="bar()"></span></span>
|
|
2628
|
+
}
|
|
2408
2629
|
@if (hint().length) {
|
|
2409
2630
|
<small class="hint">{{ hint() }}</small>
|
|
2410
2631
|
}
|
|
2411
2632
|
}
|
|
2412
2633
|
</ng-template>
|
|
2413
|
-
`, styles: [":host{display:block}.tile{display:grid;align-content:start;gap:5px;height:100%;padding:18px 20px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);color:inherit;text-decoration:none;transition:border-color .14s ease}a.tile:hover{border-color:var(--ac-accent)}:host([data-tone=\"accent\"]) .tile{border-color:var(--ac-accent)}.label{color:var(--ac-text-muted);font-size:11px;font-weight:
|
|
2414
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], link: [{ type: i0.Input, args: [{ isSignal: true, alias: "link", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }] } });
|
|
2634
|
+
`, styles: [":host{display:block}.track{overflow:hidden;height:4px;margin-top:3px;border-radius:999px;background:color-mix(in srgb,var(--ac-text) 12%,transparent)}.fill{display:block;height:4px;border-radius:999px;background:var(--ac-accent)}.tile{display:grid;align-content:start;gap:5px;height:100%;padding:18px 20px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);color:inherit;text-decoration:none;transition:border-color .14s ease}a.tile:hover{border-color:var(--ac-accent)}:host([data-tone=\"accent\"]) .tile{border-color:var(--ac-accent)}.label{color:var(--ac-text-muted);font-size:11px;font-weight:var(--ns-weight-heading);letter-spacing:.04em;text-transform:uppercase}.value{font-size:26px;font-variant-numeric:tabular-nums;line-height:1}.hint{color:var(--ac-text-muted);font-size:12px}.value-skeleton{margin:1px 0 2px}.hint-skeleton{margin:3px 0}\n"] }]
|
|
2635
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], link: [{ type: i0.Input, args: [{ isSignal: true, alias: "link", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], progress: [{ type: i0.Input, args: [{ isSignal: true, alias: "progress", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }] } });
|
|
2415
2636
|
|
|
2416
2637
|
class NucleusTabs {
|
|
2417
2638
|
tabs = input.required(...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
|
|
@@ -2438,7 +2659,7 @@ class NucleusTabs {
|
|
|
2438
2659
|
</button>
|
|
2439
2660
|
}
|
|
2440
2661
|
</div>
|
|
2441
|
-
`, isInline: true, styles: [":host{display:block;margin-bottom:12px}.bar{display:flex;overflow-x:auto;justify-content:flex-start;gap:4px;border
|
|
2662
|
+
`, isInline: true, styles: [":host{display:block;margin-bottom:12px}.bar{display:flex;overflow-x:auto;justify-content:flex-start;gap:4px;padding:5px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1);scrollbar-width:none}.bar::-webkit-scrollbar{display:none}.tab{display:inline-flex;flex:none;align-items:center;gap:8px;padding:8px 14px;border:0;border-radius:8px;background:transparent;color:var(--ac-text-muted);font:inherit;font-size:13px;font-weight:var(--ns-weight-emphasis);white-space:nowrap;cursor:pointer;transition:background .12s ease,color .12s ease}.tab:hover{background:var(--ac-surface-alt);color:var(--ac-text)}.tab:focus-visible{outline:2px solid var(--ac-accent);outline-offset:1px}.tab.is-active{background:var(--ac-text);color:var(--ac-surface)}.tab i{font-size:13px}.badge{padding:1px 7px;border-radius:var(--ac-radius-pill);background:color-mix(in srgb,currentColor 14%,transparent);font-size:11px;font-variant-numeric:tabular-nums}.tab.is-active .badge{background:color-mix(in srgb,currentColor 22%,transparent)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2442
2663
|
}
|
|
2443
2664
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusTabs, decorators: [{
|
|
2444
2665
|
type: Component,
|
|
@@ -2463,7 +2684,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
2463
2684
|
</button>
|
|
2464
2685
|
}
|
|
2465
2686
|
</div>
|
|
2466
|
-
`, styles: [":host{display:block;margin-bottom:12px}.bar{display:flex;overflow-x:auto;justify-content:flex-start;gap:4px;border
|
|
2687
|
+
`, styles: [":host{display:block;margin-bottom:12px}.bar{display:flex;overflow-x:auto;justify-content:flex-start;gap:4px;padding:5px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1);scrollbar-width:none}.bar::-webkit-scrollbar{display:none}.tab{display:inline-flex;flex:none;align-items:center;gap:8px;padding:8px 14px;border:0;border-radius:8px;background:transparent;color:var(--ac-text-muted);font:inherit;font-size:13px;font-weight:var(--ns-weight-emphasis);white-space:nowrap;cursor:pointer;transition:background .12s ease,color .12s ease}.tab:hover{background:var(--ac-surface-alt);color:var(--ac-text)}.tab:focus-visible{outline:2px solid var(--ac-accent);outline-offset:1px}.tab.is-active{background:var(--ac-text);color:var(--ac-surface)}.tab i{font-size:13px}.badge{padding:1px 7px;border-radius:var(--ac-radius-pill);background:color-mix(in srgb,currentColor 14%,transparent);font-size:11px;font-variant-numeric:tabular-nums}.tab.is-active .badge{background:color-mix(in srgb,currentColor 22%,transparent)}\n"] }]
|
|
2467
2688
|
}], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: true }] }, { type: i0.Output, args: ["activeChange"] }] } });
|
|
2468
2689
|
|
|
2469
2690
|
class NucleusPage {
|
|
@@ -2947,6 +3168,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
2947
3168
|
], hostDirectives: [NucleusEnterAdvance], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ns-form-grid\" [class]=\"gridClass()\">\n @for (field of fields(); track field.key) {\n <div class=\"ns-field\" [class]=\"fieldClass(field)\">\n @if (kindOf(field) !== 'checkbox' && kindOf(field) !== 'switch') {\n <label [attr.for]=\"kindOf(field) === 'color' ? null : 'nf-' + field.key\">\n {{ field.label }}\n </label>\n }\n\n @switch (kindOf(field)) {\n @case ('textarea') {\n <textarea\n pTextarea\n [id]=\"'nf-' + field.key\"\n [rows]=\"field.rows ?? 3\"\n [ngModel]=\"text(field)\"\n (ngModelChange)=\"write(field, $event)\"\n [disabled]=\"isDisabled(field)\"\n [attr.maxlength]=\"field.maxlength ?? null\"\n [attr.placeholder]=\"field.placeholder ?? null\"\n [ngModelOptions]=\"{ standalone: true }\"\n fluid\n ></textarea>\n }\n @case ('select') {\n <p-select\n [inputId]=\"'nf-' + field.key\"\n [options]=\"optionsOf(field)\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"read(field)\"\n (ngModelChange)=\"write(field, $event)\"\n [disabled]=\"isDisabled(field)\"\n [placeholder]=\"field.placeholder ?? labels().choose\"\n [showClear]=\"field.clearable === true\"\n [filter]=\"isSearchable(field)\"\n filterBy=\"label\"\n [filterPlaceholder]=\"labels().search\"\n [autofocusFilter]=\"true\"\n [resetFilterOnHide]=\"true\"\n [ngModelOptions]=\"{ standalone: true }\"\n fluid\n />\n }\n @case ('icon') {\n <nucleus-icon-picker\n [inputId]=\"'nf-' + field.key\"\n [value]=\"nullableText(field)\"\n (valueChange)=\"write(field, $event)\"\n [disabled]=\"isDisabled(field)\"\n />\n }\n @case ('color') {\n <nucleus-color-picker\n [value]=\"nullableText(field)\"\n (valueChange)=\"write(field, $event)\"\n [disabled]=\"isDisabled(field)\"\n [ariaLabel]=\"field.label\"\n />\n }\n @case ('checkbox') {\n <div class=\"ns-inline\">\n <p-checkbox\n [inputId]=\"'nf-' + field.key\"\n [binary]=\"true\"\n [ngModel]=\"checked(field)\"\n (ngModelChange)=\"write(field, $event)\"\n [disabled]=\"isDisabled(field)\"\n [ngModelOptions]=\"{ standalone: true }\"\n />\n <label [attr.for]=\"'nf-' + field.key\" class=\"ns-inline-label\">{{ field.label }}</label>\n </div>\n }\n @case ('switch') {\n <div class=\"ns-inline\">\n <p-toggleswitch\n [inputId]=\"'nf-' + field.key\"\n [ngModel]=\"checked(field)\"\n (ngModelChange)=\"write(field, $event)\"\n [disabled]=\"isDisabled(field)\"\n [ngModelOptions]=\"{ standalone: true }\"\n />\n <label [attr.for]=\"'nf-' + field.key\" class=\"ns-inline-label\">{{ field.label }}</label>\n </div>\n }\n @default {\n <input\n pInputText\n [id]=\"'nf-' + field.key\"\n [type]=\"kindOf(field) === 'number' ? 'number' : kindOf(field)\"\n [ngModel]=\"text(field)\"\n (ngModelChange)=\"write(field, $event)\"\n [disabled]=\"isDisabled(field)\"\n [attr.maxlength]=\"field.maxlength ?? null\"\n [attr.placeholder]=\"field.placeholder ?? null\"\n [ngModelOptions]=\"{ standalone: true }\"\n autocomplete=\"off\"\n fluid\n />\n }\n }\n\n @if (field.hint) {\n <p class=\"ns-hint\">{{ field.hint }}</p>\n }\n </div>\n }\n</div>\n", styles: [":host{display:block}\n"] }]
|
|
2948
3169
|
}], ctorParameters: () => [], propDecorators: { fields: [{ type: i0.Input, args: [{ isSignal: true, alias: "fields", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], autofocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autofocus", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
2949
3170
|
|
|
3171
|
+
class NucleusLink {
|
|
3172
|
+
route = input(null, ...(ngDevMode ? [{ debugName: "route" }] : /* istanbul ignore next */ []));
|
|
3173
|
+
queryParams = input(null, ...(ngDevMode ? [{ debugName: "queryParams" }] : /* istanbul ignore next */ []));
|
|
3174
|
+
href = input(null, ...(ngDevMode ? [{ debugName: "href" }] : /* istanbul ignore next */ []));
|
|
3175
|
+
hint = input('', ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
3176
|
+
muted = input(false, ...(ngDevMode ? [{ debugName: "muted" }] : /* istanbul ignore next */ []));
|
|
3177
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusLink, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3178
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: NucleusLink, isStandalone: true, selector: "nucleus-link", inputs: { route: { classPropertyName: "route", publicName: "route", isSignal: true, isRequired: false, transformFunction: null }, queryParams: { classPropertyName: "queryParams", publicName: "queryParams", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, muted: { classPropertyName: "muted", publicName: "muted", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-template #body>\n <span class=\"label\"><ng-content /></span>\n <i class=\"pi pi-arrow-up-right\" aria-hidden=\"true\"></i>\n</ng-template>\n\n@if (route(); as target) {\n <a\n class=\"chip\"\n [class.is-muted]=\"muted()\"\n [routerLink]=\"target\"\n [queryParams]=\"queryParams()\"\n [attr.title]=\"hint() || null\"\n >\n <ng-container [ngTemplateOutlet]=\"body\" />\n </a>\n} @else {\n <a\n class=\"chip\"\n [class.is-muted]=\"muted()\"\n [href]=\"href() ?? '#'\"\n [attr.title]=\"hint() || null\"\n >\n <ng-container [ngTemplateOutlet]=\"body\" />\n </a>\n}\n", styles: [":host{display:inline-flex;min-width:0}.chip{display:inline-flex;min-width:0;align-items:center;gap:7px;padding:3px 7px 3px 10px;border:1px solid color-mix(in srgb,var(--ac-accent) 34%,transparent);border-radius:6px;background:color-mix(in srgb,var(--ac-accent) 11%,transparent);color:var(--ac-accent);font-variant-numeric:tabular-nums;text-decoration:none;transition:background .12s ease,border-color .12s ease}.chip.is-muted{border-color:var(--ac-border);background:color-mix(in srgb,var(--ac-text) 6%,transparent);color:var(--ac-text)}.chip .label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chip .pi{flex:none;font-size:.72em;opacity:.7;transition:opacity .12s ease,transform .12s ease}.chip:hover{border-color:color-mix(in srgb,var(--ac-accent) 60%,transparent);background:color-mix(in srgb,var(--ac-accent) 18%,transparent)}.chip:hover .pi{opacity:1;transform:translate(1px,-1px)}.chip:focus-visible{outline:2px solid var(--ac-accent);outline-offset:2px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3179
|
+
}
|
|
3180
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusLink, decorators: [{
|
|
3181
|
+
type: Component,
|
|
3182
|
+
args: [{ selector: 'nucleus-link', imports: [NgTemplateOutlet, RouterLink], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #body>\n <span class=\"label\"><ng-content /></span>\n <i class=\"pi pi-arrow-up-right\" aria-hidden=\"true\"></i>\n</ng-template>\n\n@if (route(); as target) {\n <a\n class=\"chip\"\n [class.is-muted]=\"muted()\"\n [routerLink]=\"target\"\n [queryParams]=\"queryParams()\"\n [attr.title]=\"hint() || null\"\n >\n <ng-container [ngTemplateOutlet]=\"body\" />\n </a>\n} @else {\n <a\n class=\"chip\"\n [class.is-muted]=\"muted()\"\n [href]=\"href() ?? '#'\"\n [attr.title]=\"hint() || null\"\n >\n <ng-container [ngTemplateOutlet]=\"body\" />\n </a>\n}\n", styles: [":host{display:inline-flex;min-width:0}.chip{display:inline-flex;min-width:0;align-items:center;gap:7px;padding:3px 7px 3px 10px;border:1px solid color-mix(in srgb,var(--ac-accent) 34%,transparent);border-radius:6px;background:color-mix(in srgb,var(--ac-accent) 11%,transparent);color:var(--ac-accent);font-variant-numeric:tabular-nums;text-decoration:none;transition:background .12s ease,border-color .12s ease}.chip.is-muted{border-color:var(--ac-border);background:color-mix(in srgb,var(--ac-text) 6%,transparent);color:var(--ac-text)}.chip .label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chip .pi{flex:none;font-size:.72em;opacity:.7;transition:opacity .12s ease,transform .12s ease}.chip:hover{border-color:color-mix(in srgb,var(--ac-accent) 60%,transparent);background:color-mix(in srgb,var(--ac-accent) 18%,transparent)}.chip:hover .pi{opacity:1;transform:translate(1px,-1px)}.chip:focus-visible{outline:2px solid var(--ac-accent);outline-offset:2px}\n"] }]
|
|
3183
|
+
}], propDecorators: { route: [{ type: i0.Input, args: [{ isSignal: true, alias: "route", required: false }] }], queryParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "queryParams", required: false }] }], href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], muted: [{ type: i0.Input, args: [{ isSignal: true, alias: "muted", required: false }] }] } });
|
|
3184
|
+
|
|
2950
3185
|
class NucleusCell {
|
|
2951
3186
|
nucleusCell = input.required(...(ngDevMode ? [{ debugName: "nucleusCell" }] : /* istanbul ignore next */ []));
|
|
2952
3187
|
template = inject(TemplateRef);
|
|
@@ -2960,6 +3195,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
2960
3195
|
}]
|
|
2961
3196
|
}], propDecorators: { nucleusCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "nucleusCell", required: true }] }] } });
|
|
2962
3197
|
|
|
3198
|
+
function menuTile(label, icon, color) {
|
|
3199
|
+
return { label, icon, color, ink: color ? readableOn(color) : null, ghost: false };
|
|
3200
|
+
}
|
|
3201
|
+
function menuGlyph(icon) {
|
|
3202
|
+
return { label: '', icon, color: null, ink: null, ghost: true };
|
|
3203
|
+
}
|
|
3204
|
+
function foldText(value) {
|
|
3205
|
+
return value
|
|
3206
|
+
.normalize('NFD')
|
|
3207
|
+
.replace(/[̀-ͯ]/g, '')
|
|
3208
|
+
.toLowerCase();
|
|
3209
|
+
}
|
|
3210
|
+
function matchesRow(row, term) {
|
|
3211
|
+
return foldText(row.name).includes(term) || foldText(row.meta ?? '').includes(term);
|
|
3212
|
+
}
|
|
3213
|
+
function selectableRows(sections) {
|
|
3214
|
+
return sections.flatMap((section) => section.rows).filter((row) => !row.disabled && !row.current);
|
|
3215
|
+
}
|
|
3216
|
+
|
|
3217
|
+
const NUCLEUS_NARROW_QUERY = '(max-width: 720px)';
|
|
3218
|
+
class NucleusViewport {
|
|
3219
|
+
query = typeof window !== 'undefined' && typeof window.matchMedia === 'function'
|
|
3220
|
+
? window.matchMedia(NUCLEUS_NARROW_QUERY)
|
|
3221
|
+
: null;
|
|
3222
|
+
_narrow = signal(this.query?.matches ?? false, ...(ngDevMode ? [{ debugName: "_narrow" }] : /* istanbul ignore next */ []));
|
|
3223
|
+
narrow = this._narrow.asReadonly();
|
|
3224
|
+
constructor() {
|
|
3225
|
+
const query = this.query;
|
|
3226
|
+
if (!query)
|
|
3227
|
+
return;
|
|
3228
|
+
const onChange = (event) => this._narrow.set(event.matches);
|
|
3229
|
+
query.addEventListener('change', onChange);
|
|
3230
|
+
inject(DestroyRef).onDestroy(() => query.removeEventListener('change', onChange));
|
|
3231
|
+
}
|
|
3232
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusViewport, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3233
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusViewport, providedIn: 'root' });
|
|
3234
|
+
}
|
|
3235
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusViewport, decorators: [{
|
|
3236
|
+
type: Injectable,
|
|
3237
|
+
args: [{ providedIn: 'root' }]
|
|
3238
|
+
}], ctorParameters: () => [] });
|
|
3239
|
+
|
|
2963
3240
|
class NucleusList {
|
|
2964
3241
|
rows = input.required(...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
2965
3242
|
columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
@@ -2971,14 +3248,118 @@ class NucleusList {
|
|
|
2971
3248
|
rowClass = input(() => '', ...(ngDevMode ? [{ debugName: "rowClass" }] : /* istanbul ignore next */ []));
|
|
2972
3249
|
pageSize = input(5, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
|
|
2973
3250
|
pageSizes = input([5, 10, 20, 25], ...(ngDevMode ? [{ debugName: "pageSizes" }] : /* istanbul ignore next */ []));
|
|
3251
|
+
cards = input(true, ...(ngDevMode ? [{ debugName: "cards" }] : /* istanbul ignore next */ []));
|
|
3252
|
+
reorderable = input(false, ...(ngDevMode ? [{ debugName: "reorderable" }] : /* istanbul ignore next */ []));
|
|
3253
|
+
searchable = input(true, ...(ngDevMode ? [{ debugName: "searchable" }] : /* istanbul ignore next */ []));
|
|
3254
|
+
reorderGroup = input(null, ...(ngDevMode ? [{ debugName: "reorderGroup" }] : /* istanbul ignore next */ []));
|
|
2974
3255
|
action = output();
|
|
3256
|
+
reorder = output();
|
|
3257
|
+
dragStart = output();
|
|
2975
3258
|
toggle = output();
|
|
2976
3259
|
cells = contentChildren(NucleusCell, ...(ngDevMode ? [{ debugName: "cells" }] : /* istanbul ignore next */ []));
|
|
3260
|
+
language = inject(NucleusLanguage);
|
|
3261
|
+
viewport = inject(NucleusViewport);
|
|
3262
|
+
copy = computed(() => commonCopyOf(this.language.lang()), ...(ngDevMode ? [{ debugName: "copy" }] : /* istanbul ignore next */ []));
|
|
3263
|
+
term = signal('', ...(ngDevMode ? [{ debugName: "term" }] : /* istanbul ignore next */ []));
|
|
3264
|
+
chosenView = signal('rows', ...(ngDevMode ? [{ debugName: "chosenView" }] : /* istanbul ignore next */ []));
|
|
3265
|
+
canChooseView = computed(() => !this.viewport.narrow(), ...(ngDevMode ? [{ debugName: "canChooseView" }] : /* istanbul ignore next */ []));
|
|
3266
|
+
view = computed(() => this.canChooseView() ? this.chosenView() : 'grid', ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
|
|
3267
|
+
chooseView(value) {
|
|
3268
|
+
this.chosenView.set(value);
|
|
3269
|
+
}
|
|
3270
|
+
filtered = computed(() => {
|
|
3271
|
+
const term = foldText(this.term().trim());
|
|
3272
|
+
const all = this.rows();
|
|
3273
|
+
if (!term)
|
|
3274
|
+
return [...all];
|
|
3275
|
+
const columns = this.columns();
|
|
3276
|
+
return all.filter((row) => columns.some((column) => foldText(this.text(column, row)).includes(term)));
|
|
3277
|
+
}, ...(ngDevMode ? [{ debugName: "filtered" }] : /* istanbul ignore next */ []));
|
|
3278
|
+
dragLocked = computed(() => !this.reorderable() || this.term().trim().length > 0, ...(ngDevMode ? [{ debugName: "dragLocked" }] : /* istanbul ignore next */ []));
|
|
3279
|
+
showNoResults = computed(() => !this.loading() && this.rows().length > 0 && this.filtered().length === 0, ...(ngDevMode ? [{ debugName: "showNoResults" }] : /* istanbul ignore next */ []));
|
|
3280
|
+
onSearch(event) {
|
|
3281
|
+
this.term.set(event.target.value);
|
|
3282
|
+
}
|
|
3283
|
+
firstRow = signal(0, ...(ngDevMode ? [{ debugName: "firstRow" }] : /* istanbul ignore next */ []));
|
|
3284
|
+
rowsOverride = signal(0, ...(ngDevMode ? [{ debugName: "rowsOverride" }] : /* istanbul ignore next */ []));
|
|
3285
|
+
compact = computed(() => this.cards(), ...(ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []));
|
|
3286
|
+
rowsPerPage = computed(() => this.rowsOverride() || this.pageSize(), ...(ngDevMode ? [{ debugName: "rowsPerPage" }] : /* istanbul ignore next */ []));
|
|
3287
|
+
identityColumn = computed(() => {
|
|
3288
|
+
const columns = this.columns();
|
|
3289
|
+
return (columns.find((column) => column.role === 'identity') ??
|
|
3290
|
+
columns.find((column) => !column.role) ??
|
|
3291
|
+
columns[0] ??
|
|
3292
|
+
null);
|
|
3293
|
+
}, ...(ngDevMode ? [{ debugName: "identityColumn" }] : /* istanbul ignore next */ []));
|
|
3294
|
+
statusColumn = computed(() => {
|
|
3295
|
+
const columns = this.columns();
|
|
3296
|
+
const explicit = columns.find((column) => column.role === 'status');
|
|
3297
|
+
if (explicit)
|
|
3298
|
+
return explicit;
|
|
3299
|
+
const identity = this.identityColumn();
|
|
3300
|
+
return columns.find((column) => column !== identity && !column.role && !!column.tag) ?? null;
|
|
3301
|
+
}, ...(ngDevMode ? [{ debugName: "statusColumn" }] : /* istanbul ignore next */ []));
|
|
3302
|
+
attributeColumns = computed(() => {
|
|
3303
|
+
const identity = this.identityColumn();
|
|
3304
|
+
const status = this.statusColumn();
|
|
3305
|
+
return this.columns().filter((column) => column !== identity && column !== status && column.role !== 'hidden');
|
|
3306
|
+
}, ...(ngDevMode ? [{ debugName: "attributeColumns" }] : /* istanbul ignore next */ []));
|
|
3307
|
+
pagedRows = computed(() => {
|
|
3308
|
+
const all = this.filtered();
|
|
3309
|
+
if (!this.paginate())
|
|
3310
|
+
return [...all];
|
|
3311
|
+
const size = this.rowsPerPage();
|
|
3312
|
+
const start = this.firstRow() < all.length ? this.firstRow() : 0;
|
|
3313
|
+
return all.slice(start, start + size);
|
|
3314
|
+
}, ...(ngDevMode ? [{ debugName: "pagedRows" }] : /* istanbul ignore next */ []));
|
|
3315
|
+
resetPage = effect(() => {
|
|
3316
|
+
const total = this.filtered().length;
|
|
3317
|
+
untracked(() => {
|
|
3318
|
+
if (this.firstRow() >= total)
|
|
3319
|
+
this.firstRow.set(0);
|
|
3320
|
+
});
|
|
3321
|
+
}, ...(ngDevMode ? [{ debugName: "resetPage" }] : /* istanbul ignore next */ []));
|
|
3322
|
+
page = this.firstRow.asReadonly();
|
|
3323
|
+
sortAllowed = (index, drag) => {
|
|
3324
|
+
const group = this.reorderGroup();
|
|
3325
|
+
if (!group)
|
|
3326
|
+
return true;
|
|
3327
|
+
const target = this.pagedRows()[index];
|
|
3328
|
+
const dragged = drag.data;
|
|
3329
|
+
if (!target || !dragged)
|
|
3330
|
+
return true;
|
|
3331
|
+
return group(target) === group(dragged);
|
|
3332
|
+
};
|
|
3333
|
+
onRowReorder(event) {
|
|
3334
|
+
this.applyMove(event.dragIndex ?? -1, event.dropIndex ?? -1);
|
|
3335
|
+
}
|
|
3336
|
+
onCardDrop(event) {
|
|
3337
|
+
const offset = this.firstRow();
|
|
3338
|
+
this.applyMove(event.previousIndex + offset, event.currentIndex + offset);
|
|
3339
|
+
}
|
|
3340
|
+
applyMove(from, to) {
|
|
3341
|
+
const all = this.rows();
|
|
3342
|
+
if (from < 0 || to < 0 || from === to)
|
|
3343
|
+
return;
|
|
3344
|
+
if (from >= all.length || to >= all.length)
|
|
3345
|
+
return;
|
|
3346
|
+
const next = [...all];
|
|
3347
|
+
const [moved] = next.splice(from, 1);
|
|
3348
|
+
if (!moved)
|
|
3349
|
+
return;
|
|
3350
|
+
next.splice(to, 0, moved);
|
|
3351
|
+
this.reorder.emit(next);
|
|
3352
|
+
}
|
|
3353
|
+
onPage(event) {
|
|
3354
|
+
this.firstRow.set(event.first ?? 0);
|
|
3355
|
+
if (event.rows)
|
|
3356
|
+
this.rowsOverride.set(event.rows);
|
|
3357
|
+
}
|
|
2977
3358
|
paginate = computed(() => !this.loading(), ...(ngDevMode ? [{ debugName: "paginate" }] : /* istanbul ignore next */ []));
|
|
2978
3359
|
tableStyle = computed(() => ({ 'min-width': this.minWidth() }), ...(ngDevMode ? [{ debugName: "tableStyle" }] : /* istanbul ignore next */ []));
|
|
2979
3360
|
showEmpty = computed(() => !this.loading() && this.rows().length === 0, ...(ngDevMode ? [{ debugName: "showEmpty" }] : /* istanbul ignore next */ []));
|
|
2980
3361
|
placeholders = computed(() => Array.from({ length: Math.max(this.skeletonRows(), 1) }, (_, index) => ({ index })), ...(ngDevMode ? [{ debugName: "placeholders" }] : /* istanbul ignore next */ []));
|
|
2981
|
-
data = computed(() => this.loading() ? this.placeholders() : this.rows(), ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
3362
|
+
data = computed(() => this.loading() ? this.placeholders() : [...this.rows()], ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
2982
3363
|
skeletonWidth(column) {
|
|
2983
3364
|
if (column.kind === 'switch')
|
|
2984
3365
|
return '84px';
|
|
@@ -2997,6 +3378,9 @@ class NucleusList {
|
|
|
2997
3378
|
const raw = row[column.key];
|
|
2998
3379
|
return raw === null || raw === undefined ? '—' : String(raw);
|
|
2999
3380
|
}
|
|
3381
|
+
linkOf(column, row) {
|
|
3382
|
+
return column.link ? column.link(row) : null;
|
|
3383
|
+
}
|
|
3000
3384
|
tagOf(column, row) {
|
|
3001
3385
|
return column.tag ? column.tag(row) : null;
|
|
3002
3386
|
}
|
|
@@ -3024,12 +3408,24 @@ class NucleusList {
|
|
|
3024
3408
|
this.toggle.emit({ key: column.key, row, value: !this.isChecked(column, row) });
|
|
3025
3409
|
}
|
|
3026
3410
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusList, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3027
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: NucleusList, isStandalone: true, selector: "nucleus-list", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, empty: { classPropertyName: "empty", publicName: "empty", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, skeletonRows: { classPropertyName: "skeletonRows", publicName: "skeletonRows", isSignal: true, isRequired: false, transformFunction: null }, rowClass: { classPropertyName: "rowClass", publicName: "rowClass", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizes: { classPropertyName: "pageSizes", publicName: "pageSizes", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action", toggle: "toggle" }, queries: [{ propertyName: "cells", predicate: NucleusCell, isSignal: true }], ngImport: i0, template: "<div class=\"head\">\n <ng-content select=\"[nucleusListTitle]\" />\n <div class=\"head-actions\">\n <ng-content select=\"[nucleusListActions]\" />\n </div>\n</div>\n\n@if (showEmpty()) {\n <div class=\"placeholder\">{{ empty() }}</div>\n} @else {\n <p-table\n [value]=\"data()\"\n styleClass=\"ns-table\"\n [tableStyle]=\"tableStyle()\"\n [paginator]=\"paginate()\"\n [rows]=\"pageSize()\"\n [rowsPerPageOptions]=\"pageSizes()\"\n [alwaysShowPaginator]=\"true\"\n >\n <ng-template #header>\n <tr>\n @for (column of columns(); track column.key) {\n <th [class]=\"'align-' + (column.align ?? 'left')\" [style.width]=\"column.width\">\n {{ column.header }}\n </th>\n }\n @if (actions().length) {\n <th class=\"align-right\"></th>\n }\n </tr>\n </ng-template>\n\n <ng-template #body let-row>\n @if (loading()) {\n <tr class=\"is-skeleton\">\n @for (column of columns(); track column.key) {\n <td [class]=\"'align-' + (column.align ?? 'left')\">\n <p-skeleton height=\"13px\" [width]=\"skeletonWidth(column)\" />\n </td>\n }\n @if (actions().length) {\n <td class=\"align-right actions\">\n <p-skeleton shape=\"circle\" size=\"26px\" />\n </td>\n }\n </tr>\n } @else {\n <tr [class]=\"rowClass()(row)\">\n @for (column of columns(); track column.key) {\n <td [class]=\"'align-' + (column.align ?? 'left')\" [class.strong]=\"column.strong\">\n @if (cellTemplate(column.key); as custom) {\n <ng-container\n [ngTemplateOutlet]=\"custom\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"\n />\n } @else if (column.kind === 'switch') {\n <span class=\"switch-cell\">\n <button\n type=\"button\"\n class=\"ns-switch\"\n role=\"switch\"\n [class.is-on]=\"isChecked(column, row)\"\n [attr.aria-checked]=\"isChecked(column, row)\"\n [attr.aria-label]=\"text(column, row)\"\n [disabled]=\"isLocked(column, row)\"\n [pTooltip]=\"hintOf(column, row)\"\n tooltipPosition=\"top\"\n (click)=\"flip(column, row)\"\n >\n <span class=\"knob\"></span>\n </button>\n <span class=\"switch-label\">{{ text(column, row) }}</span>\n </span>\n } @else {\n {{ text(column, row) }}\n @if (tagOf(column, row); as tag) {\n <p-tag [value]=\"tag.label\" [severity]=\"tag.severity ?? 'secondary'\" />\n }\n }\n </td>\n }\n\n @if (actions().length) {\n <td class=\"align-right actions\">\n @for (entry of visibleActions(row); track entry.id) {\n <p-button\n [icon]=\"entry.icon\"\n [severity]=\"entry.tone === 'danger' ? 'danger' : 'secondary'\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [pTooltip]=\"entry.label\"\n tooltipPosition=\"left\"\n [ariaLabel]=\"entry.label\"\n [disabled]=\"isActionLocked(entry, row)\"\n (onClick)=\"run(entry, row)\"\n />\n }\n </td>\n }\n </tr>\n }\n </ng-template>\n </p-table>\n}\n", styles: [":host{display:block}.head{display:flex;align-items:center;justify-content:space-between;gap:12px}.head:has(>*:not(.head-actions)),.head:has(.head-actions>*){min-height:34px;margin-bottom:12px}.head-actions{display:flex;gap:8px}.placeholder{padding:26px;border:1px dashed var(--ac-border);border-radius:10px;color:var(--ac-text-muted);font-size:14px}.align-left{text-align:left}.align-center{text-align:center}.align-right{text-align:right}.strong{font-weight:600}.actions{white-space:nowrap}.switch-cell{display:inline-flex;align-items:center;gap:10px}.switch-label{color:var(--ac-text-muted);font-size:12px}.ns-switch{position:relative;width:38px;height:22px;flex:none;padding:0;border:1px solid var(--ac-border);border-radius:var(--ac-radius-pill);background:color-mix(in srgb,var(--ac-text) 10%,transparent);cursor:pointer;transition:background .14s ease,border-color .14s ease}.ns-switch .knob{position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--ac-text);transition:transform .14s ease}.ns-switch.is-on{border-color:var(--ac-accent);background:var(--ac-accent)}.ns-switch.is-on .knob{background:var(--ac-on-accent);transform:translate(16px)}.ns-switch:disabled{cursor:not-allowed;opacity:.45}.ns-switch:focus-visible{outline:2px solid var(--ac-accent);outline-offset:2px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i3$1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i4.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3411
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: NucleusList, isStandalone: true, selector: "nucleus-list", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, empty: { classPropertyName: "empty", publicName: "empty", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, skeletonRows: { classPropertyName: "skeletonRows", publicName: "skeletonRows", isSignal: true, isRequired: false, transformFunction: null }, rowClass: { classPropertyName: "rowClass", publicName: "rowClass", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizes: { classPropertyName: "pageSizes", publicName: "pageSizes", isSignal: true, isRequired: false, transformFunction: null }, cards: { classPropertyName: "cards", publicName: "cards", isSignal: true, isRequired: false, transformFunction: null }, reorderable: { classPropertyName: "reorderable", publicName: "reorderable", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, reorderGroup: { classPropertyName: "reorderGroup", publicName: "reorderGroup", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action", reorder: "reorder", dragStart: "dragStart", toggle: "toggle" }, queries: [{ propertyName: "cells", predicate: NucleusCell, isSignal: true }], ngImport: i0, template: "<div class=\"head\">\n <ng-content select=\"[nucleusListTitle]\" />\n <div class=\"head-actions\">\n <ng-content select=\"[nucleusListActions]\" />\n </div>\n</div>\n\n@if (showEmpty()) {\n <div class=\"placeholder\">{{ empty() }}</div>\n} @else {\n <div class=\"bar\">\n @if (searchable()) {\n <label class=\"search\">\n <i class=\"pi pi-search\" aria-hidden=\"true\"></i>\n <input\n type=\"search\"\n [value]=\"term()\"\n [placeholder]=\"copy().search\"\n [attr.aria-label]=\"copy().search\"\n (input)=\"onSearch($event)\"\n />\n </label>\n }\n\n <span class=\"bar-spacer\"></span>\n\n @if (canChooseView()) {\n <span class=\"views\">\n <button\n type=\"button\"\n class=\"view\"\n [class.is-on]=\"view() === 'grid'\"\n [attr.aria-pressed]=\"view() === 'grid'\"\n [attr.aria-label]=\"copy().viewGrid\"\n [pTooltip]=\"copy().viewGrid\"\n tooltipPosition=\"bottom\"\n (click)=\"chooseView('grid')\"\n >\n <i class=\"pi pi-th-large\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n class=\"view\"\n [class.is-on]=\"view() === 'rows'\"\n [attr.aria-pressed]=\"view() === 'rows'\"\n [attr.aria-label]=\"copy().viewRows\"\n [pTooltip]=\"copy().viewRows\"\n tooltipPosition=\"bottom\"\n (click)=\"chooseView('rows')\"\n >\n <i class=\"pi pi-list\" aria-hidden=\"true\"></i>\n </button>\n </span>\n }\n </div>\n\n @if (compact()) {\n @if (showNoResults()) {\n <div class=\"placeholder\">{{ copy().noResults }}</div>\n }\n\n <div\n class=\"cards\"\n [class.is-rows]=\"view() === 'rows'\"\n cdkDropList\n cdkDropListOrientation=\"mixed\"\n [cdkDropListDisabled]=\"dragLocked()\"\n [cdkDropListSortPredicate]=\"sortAllowed\"\n (cdkDropListDropped)=\"onCardDrop($event)\"\n >\n @if (loading()) {\n @for (item of placeholders(); track $index) {\n <div class=\"card\">\n <div class=\"card-top\">\n <p-skeleton height=\"15px\" width=\"52%\" />\n </div>\n <div class=\"card-foot\">\n <p-skeleton height=\"12px\" width=\"30%\" />\n <p-skeleton height=\"12px\" width=\"30%\" />\n </div>\n </div>\n }\n } @else {\n @for (row of pagedRows(); track $index) {\n <article class=\"card\" [class]=\"rowClass()(row)\" cdkDrag\n [cdkDragData]=\"row\"\n [cdkDragDisabled]=\"dragLocked()\"\n (cdkDragStarted)=\"dragStart.emit(row)\">\n <div class=\"card-top\">\n @if (reorderable()) {\n <button\n type=\"button\"\n class=\"grip\"\n cdkDragHandle\n [disabled]=\"dragLocked()\"\n [attr.aria-label]=\"copy().reorderHandle\"\n >\n <i class=\"pi pi-bars\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (identityColumn(); as column) {\n <span class=\"card-name\">\n @if (cellTemplate(column.key); as custom) {\n <ng-container\n [ngTemplateOutlet]=\"custom\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"\n />\n } @else {\n {{ text(column, row) }}\n }\n </span>\n }\n\n @if (statusColumn(); as column) {\n <span class=\"card-status\">\n @if (tagOf(column, row); as tag) {\n <p-tag [value]=\"tag.label\" [severity]=\"tag.severity ?? 'secondary'\" />\n } @else if (cellTemplate(column.key); as custom) {\n <ng-container\n [ngTemplateOutlet]=\"custom\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"\n />\n } @else {\n {{ text(column, row) }}\n }\n </span>\n }\n </div>\n\n @if (attributeColumns().length || visibleActions(row).length) {\n <div class=\"card-foot\">\n <div class=\"card-fields\">\n @for (column of attributeColumns(); track column.key) {\n <div class=\"field\">\n <span class=\"field-label\">{{ column.header }}</span>\n <span class=\"field-value\">\n @if (cellTemplate(column.key); as custom) {\n <ng-container\n [ngTemplateOutlet]=\"custom\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"\n />\n } @else if (linkOf(column, row); as target) {\n <nucleus-link\n [route]=\"target.route\"\n [queryParams]=\"target.queryParams ?? null\"\n [hint]=\"column.header\"\n >\n {{ text(column, row) }}\n </nucleus-link>\n } @else if (column.kind === 'switch') {\n <button\n type=\"button\"\n class=\"ns-switch\"\n role=\"switch\"\n [class.is-on]=\"isChecked(column, row)\"\n [attr.aria-checked]=\"isChecked(column, row)\"\n [attr.aria-label]=\"column.header\"\n [disabled]=\"isLocked(column, row)\"\n (click)=\"flip(column, row)\"\n >\n <span class=\"knob\"></span>\n </button>\n @if (tagOf(column, row); as tag) {\n <p-tag [value]=\"tag.label\" [severity]=\"tag.severity ?? 'secondary'\" />\n } @else {\n <span class=\"switch-label\">{{ text(column, row) }}</span>\n }\n } @else {\n {{ text(column, row) }}\n @if (tagOf(column, row); as tag) {\n <p-tag [value]=\"tag.label\" [severity]=\"tag.severity ?? 'secondary'\" />\n }\n }\n </span>\n </div>\n }\n </div>\n\n @if (visibleActions(row).length) {\n <div class=\"card-actions\">\n @for (entry of visibleActions(row); track entry.id) {\n <p-button\n [icon]=\"entry.icon\"\n [severity]=\"entry.tone === 'danger' ? 'danger' : 'secondary'\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"entry.label\"\n [disabled]=\"isActionLocked(entry, row)\"\n (onClick)=\"run(entry, row)\"\n />\n }\n </div>\n }\n </div>\n }\n </article>\n }\n }\n </div>\n\n @if (paginate()) {\n <div class=\"foot\">\n <p-paginator\n styleClass=\"ns-cards-paginator\"\n [first]=\"page()\"\n [rows]=\"rowsPerPage()\"\n [totalRecords]=\"filtered().length\"\n [rowsPerPageOptions]=\"pageSizes()\"\n (onPageChange)=\"onPage($event)\"\n />\n </div>\n }\n} @else {\n <p-table\n [value]=\"data()\"\n styleClass=\"ns-table\"\n [tableStyle]=\"tableStyle()\"\n [paginator]=\"paginate()\"\n [rows]=\"pageSize()\"\n [rowsPerPageOptions]=\"pageSizes()\"\n [alwaysShowPaginator]=\"true\"\n (onRowReorder)=\"onRowReorder($event)\"\n >\n <ng-template #header>\n <tr>\n @if (reorderable()) {\n <th class=\"grip-head\"></th>\n }\n @for (column of columns(); track column.key) {\n <th [class]=\"'align-' + (column.align ?? 'left')\" [style.width]=\"column.width\">\n {{ column.header }}\n </th>\n }\n @if (actions().length) {\n <th class=\"align-right\"></th>\n }\n </tr>\n </ng-template>\n\n <ng-template #body let-row let-rowIndex=\"rowIndex\">\n @if (loading()) {\n <tr class=\"is-skeleton\">\n @if (reorderable()) {\n <td class=\"grip-cell\"></td>\n }\n @for (column of columns(); track column.key) {\n <td [class]=\"'align-' + (column.align ?? 'left')\">\n <p-skeleton height=\"13px\" [width]=\"skeletonWidth(column)\" />\n </td>\n }\n @if (actions().length) {\n <td class=\"align-right actions\">\n <p-skeleton shape=\"circle\" size=\"26px\" />\n </td>\n }\n </tr>\n } @else {\n <tr\n [class]=\"rowClass()(row)\"\n [pReorderableRow]=\"rowIndex\"\n [pReorderableRowDisabled]=\"dragLocked()\"\n >\n @if (reorderable()) {\n <td class=\"grip-cell\">\n <span class=\"grip\" pReorderableRowHandle [attr.aria-label]=\"copy().reorderHandle\">\n <i class=\"pi pi-bars\" aria-hidden=\"true\"></i>\n </span>\n </td>\n }\n @for (column of columns(); track column.key) {\n <td [class]=\"'align-' + (column.align ?? 'left')\" [class.strong]=\"column.strong\">\n @if (cellTemplate(column.key); as custom) {\n <ng-container\n [ngTemplateOutlet]=\"custom\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"\n />\n } @else if (column.kind === 'switch') {\n <span class=\"switch-cell\">\n <button\n type=\"button\"\n class=\"ns-switch\"\n role=\"switch\"\n [class.is-on]=\"isChecked(column, row)\"\n [attr.aria-checked]=\"isChecked(column, row)\"\n [attr.aria-label]=\"text(column, row)\"\n [disabled]=\"isLocked(column, row)\"\n [pTooltip]=\"hintOf(column, row)\"\n tooltipPosition=\"top\"\n (click)=\"flip(column, row)\"\n >\n <span class=\"knob\"></span>\n </button>\n <span class=\"switch-label\">{{ text(column, row) }}</span>\n </span>\n } @else {\n {{ text(column, row) }}\n @if (tagOf(column, row); as tag) {\n <p-tag [value]=\"tag.label\" [severity]=\"tag.severity ?? 'secondary'\" />\n }\n }\n </td>\n }\n\n @if (actions().length) {\n <td class=\"align-right actions\">\n @for (entry of visibleActions(row); track entry.id) {\n <p-button\n [icon]=\"entry.icon\"\n [severity]=\"entry.tone === 'danger' ? 'danger' : 'secondary'\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [pTooltip]=\"entry.label\"\n tooltipPosition=\"left\"\n [ariaLabel]=\"entry.label\"\n [disabled]=\"isActionLocked(entry, row)\"\n (onClick)=\"run(entry, row)\"\n />\n }\n </td>\n }\n </tr>\n }\n </ng-template>\n </p-table>\n}\n}\n", styles: [":host{display:block}.head{display:flex;align-items:center;justify-content:space-between;gap:12px}.head:has(>*:not(.head-actions)),.head:has(.head-actions>*){min-height:34px;margin-bottom:12px}.head-actions{display:flex;gap:8px}.placeholder{padding:26px;border:1px dashed var(--ac-border);border-radius:10px;color:var(--ac-text-muted);font-size:14px}.align-left{text-align:left}.align-center{text-align:center}.align-right{text-align:right}.strong{font-weight:var(--ns-weight-emphasis)}.actions{white-space:nowrap}.switch-cell{display:inline-flex;align-items:center;gap:10px}.switch-label{color:var(--ac-text-muted);font-size:12px}.ns-switch{position:relative;width:38px;height:22px;flex:none;padding:0;border:1px solid var(--ac-border);border-radius:var(--ac-radius-pill);background:color-mix(in srgb,var(--ac-text) 10%,transparent);cursor:pointer;transition:background .14s ease,border-color .14s ease}.ns-switch .knob{position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--ac-text);transition:transform .14s ease}.ns-switch.is-on{border-color:var(--ac-accent);background:var(--ac-accent)}.ns-switch.is-on .knob{background:var(--ac-on-accent);transform:translate(16px)}.ns-switch:disabled{cursor:not-allowed;opacity:.45}.ns-switch:focus-visible{outline:2px solid var(--ac-accent);outline-offset:2px}.cards{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(320px,1fr))}.card{padding:13px 14px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}.card-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.card-name{display:flex;min-width:0;flex:1;align-items:center;gap:10px;font-size:15px;font-weight:var(--ns-weight-emphasis);line-height:1.3}.card-status{flex:none}.card-foot{display:flex;align-items:flex-end;gap:12px;margin-top:11px;padding-top:11px;border-top:1px solid var(--ac-border)}.card-fields{display:flex;min-width:0;flex:1;flex-wrap:wrap;gap:10px 20px}.card-actions{display:flex;flex:none;align-items:center;gap:2px}.field{display:flex;min-width:0;flex-direction:column;gap:2px}.field-label{color:var(--ac-text-muted);font-size:10px;font-weight:var(--ns-weight-heading);letter-spacing:.07em;text-transform:uppercase}.field-value{display:flex;align-items:center;gap:8px;font-size:15px;font-weight:var(--ns-weight-emphasis);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}::ng-deep .ns-cards-paginator{background:transparent}.grip{display:inline-grid;width:26px;height:26px;flex:none;padding:0;border:0;border-radius:4px;background:transparent;color:var(--ac-text-muted);cursor:grab;place-items:center;touch-action:none}.grip:hover{background:color-mix(in srgb,var(--ac-text) 8%,transparent);color:var(--ac-text)}.grip:active{cursor:grabbing}.grip:focus-visible{outline:2px solid var(--ac-accent);outline-offset:2px}.grip .pi{font-size:13px}.grip-head,.grip-cell{width:38px;padding-right:0!important}.cdk-drag-preview{border:1px solid var(--ac-accent);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-2);opacity:.96}.cdk-drag-placeholder{border:1px dashed var(--ac-border);background:color-mix(in srgb,var(--ac-text) 4%,transparent);opacity:.6}.cdk-drag-placeholder *{visibility:hidden}.cards.cdk-drop-list-dragging .card:not(.cdk-drag-placeholder){transition:transform .18s cubic-bezier(0,0,.2,1)}.cdk-drag-animating{transition:transform .22s cubic-bezier(0,0,.2,1)}.bar{display:flex;align-items:center;gap:10px;margin-bottom:12px;padding:7px 10px;border:1px solid var(--ac-border);border-radius:10px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}.bar-spacer{flex:1}.search{display:flex;min-width:0;max-width:340px;flex:1 1 220px;align-items:center;gap:8px;padding:5px 10px;border:1px solid var(--ac-border);border-radius:6px;background:color-mix(in srgb,var(--ac-text) 4%,transparent);color:var(--ac-text-muted)}.search:focus-within{border-color:var(--ac-accent);color:var(--ac-text)}.search .pi{font-size:13px}.search input{min-width:0;flex:1;padding:0;border:0;background:transparent;color:var(--ac-text);font:inherit;font-size:13px;outline:none}.search input::-webkit-search-cancel-button{filter:grayscale(1) opacity(.6)}.views{display:inline-flex;flex:none;padding:2px;border:1px solid var(--ac-border);border-radius:7px}.view{display:grid;width:30px;height:28px;padding:0;border:0;border-radius:5px;background:transparent;color:var(--ac-text-muted);cursor:pointer;place-items:center}.view:hover{color:var(--ac-text)}.view.is-on{background:color-mix(in srgb,var(--ac-accent) 18%,transparent);color:var(--ac-accent)}.view:focus-visible{outline:2px solid var(--ac-accent);outline-offset:2px}.view .pi{font-size:14px}.foot{margin-top:12px;padding:4px 6px;border:1px solid var(--ac-border);border-radius:10px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}@media(min-width:721px){.cards.is-rows{gap:8px;grid-template-columns:minmax(0,1fr)}.cards.is-rows .card{display:grid;align-items:center;gap:18px;grid-template-columns:minmax(0,2fr) minmax(0,3fr);padding:9px 14px}.cards.is-rows .card-top{min-width:0;align-items:center;gap:12px}.cards.is-rows .card-foot{margin-top:0;padding-top:0;border-top:0;gap:14px}.cards.is-rows .card-fields{display:grid;min-width:0;flex:1;gap:14px;grid-auto-columns:minmax(0,1fr);grid-auto-flow:column}.cards.is-rows .field-label,.cards.is-rows .field-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NucleusLink, selector: "nucleus-link", inputs: ["route", "queryParams", "href", "hint", "muted"] }, { kind: "directive", type: 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"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: 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: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: i2$3.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first", "appendTo"], outputs: ["onPageChange"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i4.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i4.ReorderableRowHandle, selector: "[pReorderableRowHandle]" }, { kind: "directive", type: i4.ReorderableRow, selector: "[pReorderableRow]", inputs: ["pReorderableRow", "pReorderableRowDisabled"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i5$1.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3028
3412
|
}
|
|
3029
3413
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusList, decorators: [{
|
|
3030
3414
|
type: Component,
|
|
3031
|
-
args: [{ selector: 'nucleus-list', imports: [
|
|
3032
|
-
|
|
3415
|
+
args: [{ selector: 'nucleus-list', imports: [
|
|
3416
|
+
NgTemplateOutlet,
|
|
3417
|
+
NucleusLink,
|
|
3418
|
+
CdkDrag,
|
|
3419
|
+
CdkDragHandle,
|
|
3420
|
+
CdkDropList,
|
|
3421
|
+
ButtonModule,
|
|
3422
|
+
PaginatorModule,
|
|
3423
|
+
SkeletonModule,
|
|
3424
|
+
TableModule,
|
|
3425
|
+
TagModule,
|
|
3426
|
+
TooltipModule,
|
|
3427
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"head\">\n <ng-content select=\"[nucleusListTitle]\" />\n <div class=\"head-actions\">\n <ng-content select=\"[nucleusListActions]\" />\n </div>\n</div>\n\n@if (showEmpty()) {\n <div class=\"placeholder\">{{ empty() }}</div>\n} @else {\n <div class=\"bar\">\n @if (searchable()) {\n <label class=\"search\">\n <i class=\"pi pi-search\" aria-hidden=\"true\"></i>\n <input\n type=\"search\"\n [value]=\"term()\"\n [placeholder]=\"copy().search\"\n [attr.aria-label]=\"copy().search\"\n (input)=\"onSearch($event)\"\n />\n </label>\n }\n\n <span class=\"bar-spacer\"></span>\n\n @if (canChooseView()) {\n <span class=\"views\">\n <button\n type=\"button\"\n class=\"view\"\n [class.is-on]=\"view() === 'grid'\"\n [attr.aria-pressed]=\"view() === 'grid'\"\n [attr.aria-label]=\"copy().viewGrid\"\n [pTooltip]=\"copy().viewGrid\"\n tooltipPosition=\"bottom\"\n (click)=\"chooseView('grid')\"\n >\n <i class=\"pi pi-th-large\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n class=\"view\"\n [class.is-on]=\"view() === 'rows'\"\n [attr.aria-pressed]=\"view() === 'rows'\"\n [attr.aria-label]=\"copy().viewRows\"\n [pTooltip]=\"copy().viewRows\"\n tooltipPosition=\"bottom\"\n (click)=\"chooseView('rows')\"\n >\n <i class=\"pi pi-list\" aria-hidden=\"true\"></i>\n </button>\n </span>\n }\n </div>\n\n @if (compact()) {\n @if (showNoResults()) {\n <div class=\"placeholder\">{{ copy().noResults }}</div>\n }\n\n <div\n class=\"cards\"\n [class.is-rows]=\"view() === 'rows'\"\n cdkDropList\n cdkDropListOrientation=\"mixed\"\n [cdkDropListDisabled]=\"dragLocked()\"\n [cdkDropListSortPredicate]=\"sortAllowed\"\n (cdkDropListDropped)=\"onCardDrop($event)\"\n >\n @if (loading()) {\n @for (item of placeholders(); track $index) {\n <div class=\"card\">\n <div class=\"card-top\">\n <p-skeleton height=\"15px\" width=\"52%\" />\n </div>\n <div class=\"card-foot\">\n <p-skeleton height=\"12px\" width=\"30%\" />\n <p-skeleton height=\"12px\" width=\"30%\" />\n </div>\n </div>\n }\n } @else {\n @for (row of pagedRows(); track $index) {\n <article class=\"card\" [class]=\"rowClass()(row)\" cdkDrag\n [cdkDragData]=\"row\"\n [cdkDragDisabled]=\"dragLocked()\"\n (cdkDragStarted)=\"dragStart.emit(row)\">\n <div class=\"card-top\">\n @if (reorderable()) {\n <button\n type=\"button\"\n class=\"grip\"\n cdkDragHandle\n [disabled]=\"dragLocked()\"\n [attr.aria-label]=\"copy().reorderHandle\"\n >\n <i class=\"pi pi-bars\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (identityColumn(); as column) {\n <span class=\"card-name\">\n @if (cellTemplate(column.key); as custom) {\n <ng-container\n [ngTemplateOutlet]=\"custom\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"\n />\n } @else {\n {{ text(column, row) }}\n }\n </span>\n }\n\n @if (statusColumn(); as column) {\n <span class=\"card-status\">\n @if (tagOf(column, row); as tag) {\n <p-tag [value]=\"tag.label\" [severity]=\"tag.severity ?? 'secondary'\" />\n } @else if (cellTemplate(column.key); as custom) {\n <ng-container\n [ngTemplateOutlet]=\"custom\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"\n />\n } @else {\n {{ text(column, row) }}\n }\n </span>\n }\n </div>\n\n @if (attributeColumns().length || visibleActions(row).length) {\n <div class=\"card-foot\">\n <div class=\"card-fields\">\n @for (column of attributeColumns(); track column.key) {\n <div class=\"field\">\n <span class=\"field-label\">{{ column.header }}</span>\n <span class=\"field-value\">\n @if (cellTemplate(column.key); as custom) {\n <ng-container\n [ngTemplateOutlet]=\"custom\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"\n />\n } @else if (linkOf(column, row); as target) {\n <nucleus-link\n [route]=\"target.route\"\n [queryParams]=\"target.queryParams ?? null\"\n [hint]=\"column.header\"\n >\n {{ text(column, row) }}\n </nucleus-link>\n } @else if (column.kind === 'switch') {\n <button\n type=\"button\"\n class=\"ns-switch\"\n role=\"switch\"\n [class.is-on]=\"isChecked(column, row)\"\n [attr.aria-checked]=\"isChecked(column, row)\"\n [attr.aria-label]=\"column.header\"\n [disabled]=\"isLocked(column, row)\"\n (click)=\"flip(column, row)\"\n >\n <span class=\"knob\"></span>\n </button>\n @if (tagOf(column, row); as tag) {\n <p-tag [value]=\"tag.label\" [severity]=\"tag.severity ?? 'secondary'\" />\n } @else {\n <span class=\"switch-label\">{{ text(column, row) }}</span>\n }\n } @else {\n {{ text(column, row) }}\n @if (tagOf(column, row); as tag) {\n <p-tag [value]=\"tag.label\" [severity]=\"tag.severity ?? 'secondary'\" />\n }\n }\n </span>\n </div>\n }\n </div>\n\n @if (visibleActions(row).length) {\n <div class=\"card-actions\">\n @for (entry of visibleActions(row); track entry.id) {\n <p-button\n [icon]=\"entry.icon\"\n [severity]=\"entry.tone === 'danger' ? 'danger' : 'secondary'\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"entry.label\"\n [disabled]=\"isActionLocked(entry, row)\"\n (onClick)=\"run(entry, row)\"\n />\n }\n </div>\n }\n </div>\n }\n </article>\n }\n }\n </div>\n\n @if (paginate()) {\n <div class=\"foot\">\n <p-paginator\n styleClass=\"ns-cards-paginator\"\n [first]=\"page()\"\n [rows]=\"rowsPerPage()\"\n [totalRecords]=\"filtered().length\"\n [rowsPerPageOptions]=\"pageSizes()\"\n (onPageChange)=\"onPage($event)\"\n />\n </div>\n }\n} @else {\n <p-table\n [value]=\"data()\"\n styleClass=\"ns-table\"\n [tableStyle]=\"tableStyle()\"\n [paginator]=\"paginate()\"\n [rows]=\"pageSize()\"\n [rowsPerPageOptions]=\"pageSizes()\"\n [alwaysShowPaginator]=\"true\"\n (onRowReorder)=\"onRowReorder($event)\"\n >\n <ng-template #header>\n <tr>\n @if (reorderable()) {\n <th class=\"grip-head\"></th>\n }\n @for (column of columns(); track column.key) {\n <th [class]=\"'align-' + (column.align ?? 'left')\" [style.width]=\"column.width\">\n {{ column.header }}\n </th>\n }\n @if (actions().length) {\n <th class=\"align-right\"></th>\n }\n </tr>\n </ng-template>\n\n <ng-template #body let-row let-rowIndex=\"rowIndex\">\n @if (loading()) {\n <tr class=\"is-skeleton\">\n @if (reorderable()) {\n <td class=\"grip-cell\"></td>\n }\n @for (column of columns(); track column.key) {\n <td [class]=\"'align-' + (column.align ?? 'left')\">\n <p-skeleton height=\"13px\" [width]=\"skeletonWidth(column)\" />\n </td>\n }\n @if (actions().length) {\n <td class=\"align-right actions\">\n <p-skeleton shape=\"circle\" size=\"26px\" />\n </td>\n }\n </tr>\n } @else {\n <tr\n [class]=\"rowClass()(row)\"\n [pReorderableRow]=\"rowIndex\"\n [pReorderableRowDisabled]=\"dragLocked()\"\n >\n @if (reorderable()) {\n <td class=\"grip-cell\">\n <span class=\"grip\" pReorderableRowHandle [attr.aria-label]=\"copy().reorderHandle\">\n <i class=\"pi pi-bars\" aria-hidden=\"true\"></i>\n </span>\n </td>\n }\n @for (column of columns(); track column.key) {\n <td [class]=\"'align-' + (column.align ?? 'left')\" [class.strong]=\"column.strong\">\n @if (cellTemplate(column.key); as custom) {\n <ng-container\n [ngTemplateOutlet]=\"custom\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"\n />\n } @else if (column.kind === 'switch') {\n <span class=\"switch-cell\">\n <button\n type=\"button\"\n class=\"ns-switch\"\n role=\"switch\"\n [class.is-on]=\"isChecked(column, row)\"\n [attr.aria-checked]=\"isChecked(column, row)\"\n [attr.aria-label]=\"text(column, row)\"\n [disabled]=\"isLocked(column, row)\"\n [pTooltip]=\"hintOf(column, row)\"\n tooltipPosition=\"top\"\n (click)=\"flip(column, row)\"\n >\n <span class=\"knob\"></span>\n </button>\n <span class=\"switch-label\">{{ text(column, row) }}</span>\n </span>\n } @else {\n {{ text(column, row) }}\n @if (tagOf(column, row); as tag) {\n <p-tag [value]=\"tag.label\" [severity]=\"tag.severity ?? 'secondary'\" />\n }\n }\n </td>\n }\n\n @if (actions().length) {\n <td class=\"align-right actions\">\n @for (entry of visibleActions(row); track entry.id) {\n <p-button\n [icon]=\"entry.icon\"\n [severity]=\"entry.tone === 'danger' ? 'danger' : 'secondary'\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [pTooltip]=\"entry.label\"\n tooltipPosition=\"left\"\n [ariaLabel]=\"entry.label\"\n [disabled]=\"isActionLocked(entry, row)\"\n (onClick)=\"run(entry, row)\"\n />\n }\n </td>\n }\n </tr>\n }\n </ng-template>\n </p-table>\n}\n}\n", styles: [":host{display:block}.head{display:flex;align-items:center;justify-content:space-between;gap:12px}.head:has(>*:not(.head-actions)),.head:has(.head-actions>*){min-height:34px;margin-bottom:12px}.head-actions{display:flex;gap:8px}.placeholder{padding:26px;border:1px dashed var(--ac-border);border-radius:10px;color:var(--ac-text-muted);font-size:14px}.align-left{text-align:left}.align-center{text-align:center}.align-right{text-align:right}.strong{font-weight:var(--ns-weight-emphasis)}.actions{white-space:nowrap}.switch-cell{display:inline-flex;align-items:center;gap:10px}.switch-label{color:var(--ac-text-muted);font-size:12px}.ns-switch{position:relative;width:38px;height:22px;flex:none;padding:0;border:1px solid var(--ac-border);border-radius:var(--ac-radius-pill);background:color-mix(in srgb,var(--ac-text) 10%,transparent);cursor:pointer;transition:background .14s ease,border-color .14s ease}.ns-switch .knob{position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--ac-text);transition:transform .14s ease}.ns-switch.is-on{border-color:var(--ac-accent);background:var(--ac-accent)}.ns-switch.is-on .knob{background:var(--ac-on-accent);transform:translate(16px)}.ns-switch:disabled{cursor:not-allowed;opacity:.45}.ns-switch:focus-visible{outline:2px solid var(--ac-accent);outline-offset:2px}.cards{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(320px,1fr))}.card{padding:13px 14px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}.card-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.card-name{display:flex;min-width:0;flex:1;align-items:center;gap:10px;font-size:15px;font-weight:var(--ns-weight-emphasis);line-height:1.3}.card-status{flex:none}.card-foot{display:flex;align-items:flex-end;gap:12px;margin-top:11px;padding-top:11px;border-top:1px solid var(--ac-border)}.card-fields{display:flex;min-width:0;flex:1;flex-wrap:wrap;gap:10px 20px}.card-actions{display:flex;flex:none;align-items:center;gap:2px}.field{display:flex;min-width:0;flex-direction:column;gap:2px}.field-label{color:var(--ac-text-muted);font-size:10px;font-weight:var(--ns-weight-heading);letter-spacing:.07em;text-transform:uppercase}.field-value{display:flex;align-items:center;gap:8px;font-size:15px;font-weight:var(--ns-weight-emphasis);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}::ng-deep .ns-cards-paginator{background:transparent}.grip{display:inline-grid;width:26px;height:26px;flex:none;padding:0;border:0;border-radius:4px;background:transparent;color:var(--ac-text-muted);cursor:grab;place-items:center;touch-action:none}.grip:hover{background:color-mix(in srgb,var(--ac-text) 8%,transparent);color:var(--ac-text)}.grip:active{cursor:grabbing}.grip:focus-visible{outline:2px solid var(--ac-accent);outline-offset:2px}.grip .pi{font-size:13px}.grip-head,.grip-cell{width:38px;padding-right:0!important}.cdk-drag-preview{border:1px solid var(--ac-accent);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-2);opacity:.96}.cdk-drag-placeholder{border:1px dashed var(--ac-border);background:color-mix(in srgb,var(--ac-text) 4%,transparent);opacity:.6}.cdk-drag-placeholder *{visibility:hidden}.cards.cdk-drop-list-dragging .card:not(.cdk-drag-placeholder){transition:transform .18s cubic-bezier(0,0,.2,1)}.cdk-drag-animating{transition:transform .22s cubic-bezier(0,0,.2,1)}.bar{display:flex;align-items:center;gap:10px;margin-bottom:12px;padding:7px 10px;border:1px solid var(--ac-border);border-radius:10px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}.bar-spacer{flex:1}.search{display:flex;min-width:0;max-width:340px;flex:1 1 220px;align-items:center;gap:8px;padding:5px 10px;border:1px solid var(--ac-border);border-radius:6px;background:color-mix(in srgb,var(--ac-text) 4%,transparent);color:var(--ac-text-muted)}.search:focus-within{border-color:var(--ac-accent);color:var(--ac-text)}.search .pi{font-size:13px}.search input{min-width:0;flex:1;padding:0;border:0;background:transparent;color:var(--ac-text);font:inherit;font-size:13px;outline:none}.search input::-webkit-search-cancel-button{filter:grayscale(1) opacity(.6)}.views{display:inline-flex;flex:none;padding:2px;border:1px solid var(--ac-border);border-radius:7px}.view{display:grid;width:30px;height:28px;padding:0;border:0;border-radius:5px;background:transparent;color:var(--ac-text-muted);cursor:pointer;place-items:center}.view:hover{color:var(--ac-text)}.view.is-on{background:color-mix(in srgb,var(--ac-accent) 18%,transparent);color:var(--ac-accent)}.view:focus-visible{outline:2px solid var(--ac-accent);outline-offset:2px}.view .pi{font-size:14px}.foot{margin-top:12px;padding:4px 6px;border:1px solid var(--ac-border);border-radius:10px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}@media(min-width:721px){.cards.is-rows{gap:8px;grid-template-columns:minmax(0,1fr)}.cards.is-rows .card{display:grid;align-items:center;gap:18px;grid-template-columns:minmax(0,2fr) minmax(0,3fr);padding:9px 14px}.cards.is-rows .card-top{min-width:0;align-items:center;gap:12px}.cards.is-rows .card-foot{margin-top:0;padding-top:0;border-top:0;gap:14px}.cards.is-rows .card-fields{display:grid;min-width:0;flex:1;gap:14px;grid-auto-columns:minmax(0,1fr);grid-auto-flow:column}.cards.is-rows .field-label,.cards.is-rows .field-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}\n"] }]
|
|
3428
|
+
}], propDecorators: { rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], empty: [{ type: i0.Input, args: [{ isSignal: true, alias: "empty", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }], skeletonRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "skeletonRows", required: false }] }], rowClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowClass", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageSizes: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizes", required: false }] }], cards: [{ type: i0.Input, args: [{ isSignal: true, alias: "cards", required: false }] }], reorderable: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderable", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], reorderGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderGroup", required: false }] }], action: [{ type: i0.Output, args: ["action"] }], reorder: [{ type: i0.Output, args: ["reorder"] }], dragStart: [{ type: i0.Output, args: ["dragStart"] }], toggle: [{ type: i0.Output, args: ["toggle"] }], cells: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => NucleusCell), { isSignal: true }] }] } });
|
|
3033
3429
|
|
|
3034
3430
|
function toggleCollapsed(collapsed, id) {
|
|
3035
3431
|
const next = new Set(collapsed);
|
|
@@ -3166,32 +3562,13 @@ class NucleusAppearance {
|
|
|
3166
3562
|
this.theme.setDensity(id);
|
|
3167
3563
|
}
|
|
3168
3564
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusAppearance, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3169
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: NucleusAppearance, isStandalone: true, selector: "nucleus-appearance", ngImport: i0, template: "@let t = copy();\n@let current = appearance();\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.frameTitle }}</h3>\n <p class=\"group-hint\">{{ t.frameHint }}</p>\n\n <div class=\"frames\" role=\"radiogroup\" [attr.aria-label]=\"t.frameTitle\">\n @for (frame of frames(); track frame.id) {\n <button\n type=\"button\"\n class=\"frame\"\n role=\"radio\"\n [class.is-active]=\"frame.id === current.frame\"\n [attr.aria-checked]=\"frame.id === current.frame\"\n [attr.aria-label]=\"frame.label\"\n [style.--f-bg]=\"frame.tokens.bg\"\n [style.--f-raised]=\"frame.tokens.raised\"\n [style.--f-ink]=\"frame.tokens.ink\"\n [style.--f-muted]=\"frame.tokens.muted\"\n [style.--f-line]=\"frame.tokens.line\"\n [style.--f-glow]=\"frame.tokens.glow\"\n (click)=\"pickFrame(frame.id)\"\n >\n <span class=\"frame-chip\" aria-hidden=\"true\">\n <span class=\"frame-bar\">\n <span class=\"frame-dot\"></span>\n </span>\n <span class=\"frame-lower\">\n <span class=\"frame-rail\">\n <span class=\"frame-pin\"></span>\n <span class=\"frame-row is-on\"></span>\n <span class=\"frame-row\"></span>\n <span class=\"frame-row\"></span>\n </span>\n <span class=\"frame-canvas\"></span>\n </span>\n </span>\n <span class=\"frame-name\">{{ frame.label }}</span>\n </button>\n }\n </div>\n</section>\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.canvasTitle }}</h3>\n <p class=\"group-hint\">{{ t.canvasHint }}</p>\n\n <div class=\"canvases\" role=\"radiogroup\" [attr.aria-label]=\"t.canvasTitle\">\n @for (canvas of canvases(); track canvas.id) {\n <button\n type=\"button\"\n class=\"canvas\"\n role=\"radio\"\n [class.is-active]=\"canvas.id === current.canvas\"\n [attr.aria-checked]=\"canvas.id === current.canvas\"\n (click)=\"pickCanvas(canvas.id)\"\n >\n <span\n class=\"canvas-chip\"\n aria-hidden=\"true\"\n [style.background]=\"canvas.bg\"\n [style.color]=\"canvas.text\"\n >\n @if (canvas.icon) {\n <i [class]=\"canvas.icon\"></i>\n } @else {\n <span class=\"canvas-sheet\" [style.background]=\"canvas.surface\"></span>\n }\n </span>\n <span class=\"canvas-name\">{{ canvas.label }}</span>\n </button>\n }\n </div>\n</section>\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.accentTitle }}</h3>\n <p class=\"group-hint\">{{ t.accentHint }}</p>\n\n <div class=\"accents\" role=\"radiogroup\" [attr.aria-label]=\"t.accentTitle\">\n @for (accent of accents(); track accent.id) {\n <button\n type=\"button\"\n class=\"accent\"\n role=\"radio\"\n [class.is-auto]=\"accent.id === 'auto'\"\n [class.is-active]=\"accent.id === current.accent\"\n [attr.aria-checked]=\"accent.id === current.accent\"\n [attr.aria-label]=\"accent.label\"\n [title]=\"accent.label\"\n [style.background]=\"accent.color\"\n [style.color]=\"accent.ink\"\n (click)=\"pickAccent(accent.id)\"\n >\n @if (accent.id === current.accent) {\n <i class=\"pi pi-check\" aria-hidden=\"true\"></i>\n } @else if (accent.id === 'auto') {\n <i class=\"pi pi-sparkles\" aria-hidden=\"true\"></i>\n }\n </button>\n }\n </div>\n</section>\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.densityTitle }}</h3>\n <p class=\"group-hint\">{{ t.densityHint }}</p>\n\n <div class=\"densities\" role=\"radiogroup\" [attr.aria-label]=\"t.densityTitle\">\n @for (density of densities(); track density.id) {\n <button\n type=\"button\"\n class=\"density\"\n role=\"radio\"\n [class.is-active]=\"density.id === current.density\"\n [attr.aria-checked]=\"density.id === current.density\"\n (click)=\"pickDensity(density.id)\"\n >\n <span class=\"density-chip\" aria-hidden=\"true\" [style.gap.px]=\"density.gap\">\n <span class=\"density-row\"></span>\n <span class=\"density-row\"></span>\n <span class=\"density-row\"></span>\n </span>\n <span class=\"density-name\">{{ density.label }}</span>\n </button>\n }\n </div>\n</section>\n", styles: [":host{display:flex;flex-direction:column;gap:26px}.group{display:flex;flex-direction:column;gap:2px}.group-title{margin:0;font-size:13px;font-weight:
|
|
3565
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: NucleusAppearance, isStandalone: true, selector: "nucleus-appearance", ngImport: i0, template: "@let t = copy();\n@let current = appearance();\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.frameTitle }}</h3>\n <p class=\"group-hint\">{{ t.frameHint }}</p>\n\n <div class=\"frames\" role=\"radiogroup\" [attr.aria-label]=\"t.frameTitle\">\n @for (frame of frames(); track frame.id) {\n <button\n type=\"button\"\n class=\"frame\"\n role=\"radio\"\n [class.is-active]=\"frame.id === current.frame\"\n [attr.aria-checked]=\"frame.id === current.frame\"\n [attr.aria-label]=\"frame.label\"\n [style.--f-bg]=\"frame.tokens.bg\"\n [style.--f-raised]=\"frame.tokens.raised\"\n [style.--f-ink]=\"frame.tokens.ink\"\n [style.--f-muted]=\"frame.tokens.muted\"\n [style.--f-line]=\"frame.tokens.line\"\n [style.--f-glow]=\"frame.tokens.glow\"\n (click)=\"pickFrame(frame.id)\"\n >\n <span class=\"frame-chip\" aria-hidden=\"true\">\n <span class=\"frame-bar\">\n <span class=\"frame-dot\"></span>\n </span>\n <span class=\"frame-lower\">\n <span class=\"frame-rail\">\n <span class=\"frame-pin\"></span>\n <span class=\"frame-row is-on\"></span>\n <span class=\"frame-row\"></span>\n <span class=\"frame-row\"></span>\n </span>\n <span class=\"frame-canvas\"></span>\n </span>\n </span>\n <span class=\"frame-name\">{{ frame.label }}</span>\n </button>\n }\n </div>\n</section>\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.canvasTitle }}</h3>\n <p class=\"group-hint\">{{ t.canvasHint }}</p>\n\n <div class=\"canvases\" role=\"radiogroup\" [attr.aria-label]=\"t.canvasTitle\">\n @for (canvas of canvases(); track canvas.id) {\n <button\n type=\"button\"\n class=\"canvas\"\n role=\"radio\"\n [class.is-active]=\"canvas.id === current.canvas\"\n [attr.aria-checked]=\"canvas.id === current.canvas\"\n (click)=\"pickCanvas(canvas.id)\"\n >\n <span\n class=\"canvas-chip\"\n aria-hidden=\"true\"\n [style.background]=\"canvas.bg\"\n [style.color]=\"canvas.text\"\n >\n @if (canvas.icon) {\n <i [class]=\"canvas.icon\"></i>\n } @else {\n <span class=\"canvas-sheet\" [style.background]=\"canvas.surface\"></span>\n }\n </span>\n <span class=\"canvas-name\">{{ canvas.label }}</span>\n </button>\n }\n </div>\n</section>\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.accentTitle }}</h3>\n <p class=\"group-hint\">{{ t.accentHint }}</p>\n\n <div class=\"accents\" role=\"radiogroup\" [attr.aria-label]=\"t.accentTitle\">\n @for (accent of accents(); track accent.id) {\n <button\n type=\"button\"\n class=\"accent\"\n role=\"radio\"\n [class.is-auto]=\"accent.id === 'auto'\"\n [class.is-active]=\"accent.id === current.accent\"\n [attr.aria-checked]=\"accent.id === current.accent\"\n [attr.aria-label]=\"accent.label\"\n [title]=\"accent.label\"\n [style.background]=\"accent.color\"\n [style.color]=\"accent.ink\"\n (click)=\"pickAccent(accent.id)\"\n >\n @if (accent.id === current.accent) {\n <i class=\"pi pi-check\" aria-hidden=\"true\"></i>\n } @else if (accent.id === 'auto') {\n <i class=\"pi pi-sparkles\" aria-hidden=\"true\"></i>\n }\n </button>\n }\n </div>\n</section>\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.densityTitle }}</h3>\n <p class=\"group-hint\">{{ t.densityHint }}</p>\n\n <div class=\"densities\" role=\"radiogroup\" [attr.aria-label]=\"t.densityTitle\">\n @for (density of densities(); track density.id) {\n <button\n type=\"button\"\n class=\"density\"\n role=\"radio\"\n [class.is-active]=\"density.id === current.density\"\n [attr.aria-checked]=\"density.id === current.density\"\n (click)=\"pickDensity(density.id)\"\n >\n <span class=\"density-chip\" aria-hidden=\"true\" [style.gap.px]=\"density.gap\">\n <span class=\"density-row\"></span>\n <span class=\"density-row\"></span>\n <span class=\"density-row\"></span>\n </span>\n <span class=\"density-name\">{{ density.label }}</span>\n </button>\n }\n </div>\n</section>\n", styles: [":host{display:flex;flex-direction:column;gap:26px}.group{display:flex;flex-direction:column;gap:2px}.group-title{margin:0;font-size:13px;font-weight:var(--ns-weight-heading);letter-spacing:.02em}.group-hint{margin:0 0 12px;color:var(--ac-text-muted);font-size:12px;font-weight:300;line-height:1.45}.frames{display:grid;grid-template-columns:repeat(auto-fill,minmax(84px,1fr));gap:10px}.frame{display:flex;flex-direction:column;gap:6px;padding:4px;border:2px solid transparent;border-radius:10px;background:transparent;color:var(--ac-text-muted);cursor:pointer}.frame:hover{color:var(--ac-text)}.frame.is-active{border-color:var(--ac-accent);color:var(--ac-text)}.frame-chip{display:flex;overflow:hidden;flex-direction:column;height:52px;border:1px solid var(--f-line);border-radius:6px;background:var(--f-bg)}.frame-bar{display:flex;flex:none;align-items:center;height:12px;padding-left:5px;border-bottom:1px solid var(--f-line)}.frame-dot{width:5px;height:5px;border-radius:50%;background:var(--f-glow)}.frame-lower{display:flex;flex:1;min-height:0}.frame-rail{display:flex;flex:none;flex-direction:column;gap:3px;width:22px;padding:4px 3px;border-right:1px solid var(--f-line)}.frame-pin{height:7px;border-left:2px solid var(--f-glow);border-radius:2px;background:var(--f-raised)}.frame-row{height:3px;border-radius:2px;background:var(--f-muted);opacity:.55}.frame-row.is-on{background:var(--f-glow);opacity:1}.frame-canvas{flex:1;background:var(--ac-bg)}.frame-name{overflow:hidden;font-size:11px;font-weight:var(--ns-weight-emphasis);text-align:center;text-overflow:ellipsis;white-space:nowrap}.canvases{display:grid;grid-template-columns:repeat(auto-fit,minmax(70px,1fr));gap:8px}.canvas{display:flex;flex-direction:column;gap:6px;padding:4px;border:2px solid transparent;border-radius:10px;background:transparent;color:var(--ac-text-muted);cursor:pointer}.canvas:hover{color:var(--ac-text)}.canvas.is-active{border-color:var(--ac-accent);color:var(--ac-text)}.canvas-chip{display:flex;align-items:center;justify-content:center;height:40px;border:1px solid var(--ac-border);border-radius:6px}.canvas-chip i{font-size:15px}.canvas-sheet{width:60%;height:58%;border-radius:3px;box-shadow:0 1px 4px #00000038}.canvas-name{font-size:11px;font-weight:var(--ns-weight-emphasis);text-align:center}.accents{display:flex;flex-wrap:wrap;gap:9px}.accent{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:2px solid transparent;border-radius:50%;cursor:pointer;transition:transform .12s ease}.accent:hover{transform:scale(1.12)}.accent.is-auto{border-style:dashed;border-color:var(--ac-border)}.accent.is-active{border-style:solid;border-color:var(--ac-text);box-shadow:0 0 0 2px var(--ac-surface) inset}.accent i{font-size:11px}.densities{display:flex;gap:10px}.density{display:flex;flex:1;flex-direction:column;gap:6px;padding:4px;border:2px solid transparent;border-radius:10px;background:transparent;color:var(--ac-text-muted);cursor:pointer}.density:hover{color:var(--ac-text)}.density.is-active{border-color:var(--ac-accent);color:var(--ac-text)}.density-chip{display:flex;flex-direction:column;justify-content:center;height:42px;padding:0 10px;border:1px solid var(--ac-border);border-radius:6px;background:var(--ac-surface)}.density-row{height:3px;border-radius:2px;background:var(--ac-text-muted);opacity:.5}.density-name{font-size:11px;font-weight:var(--ns-weight-emphasis);text-align:center}@media(prefers-reduced-motion:reduce){.accent{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3170
3566
|
}
|
|
3171
3567
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusAppearance, decorators: [{
|
|
3172
3568
|
type: Component,
|
|
3173
|
-
args: [{ selector: 'nucleus-appearance', changeDetection: ChangeDetectionStrategy.OnPush, template: "@let t = copy();\n@let current = appearance();\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.frameTitle }}</h3>\n <p class=\"group-hint\">{{ t.frameHint }}</p>\n\n <div class=\"frames\" role=\"radiogroup\" [attr.aria-label]=\"t.frameTitle\">\n @for (frame of frames(); track frame.id) {\n <button\n type=\"button\"\n class=\"frame\"\n role=\"radio\"\n [class.is-active]=\"frame.id === current.frame\"\n [attr.aria-checked]=\"frame.id === current.frame\"\n [attr.aria-label]=\"frame.label\"\n [style.--f-bg]=\"frame.tokens.bg\"\n [style.--f-raised]=\"frame.tokens.raised\"\n [style.--f-ink]=\"frame.tokens.ink\"\n [style.--f-muted]=\"frame.tokens.muted\"\n [style.--f-line]=\"frame.tokens.line\"\n [style.--f-glow]=\"frame.tokens.glow\"\n (click)=\"pickFrame(frame.id)\"\n >\n <span class=\"frame-chip\" aria-hidden=\"true\">\n <span class=\"frame-bar\">\n <span class=\"frame-dot\"></span>\n </span>\n <span class=\"frame-lower\">\n <span class=\"frame-rail\">\n <span class=\"frame-pin\"></span>\n <span class=\"frame-row is-on\"></span>\n <span class=\"frame-row\"></span>\n <span class=\"frame-row\"></span>\n </span>\n <span class=\"frame-canvas\"></span>\n </span>\n </span>\n <span class=\"frame-name\">{{ frame.label }}</span>\n </button>\n }\n </div>\n</section>\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.canvasTitle }}</h3>\n <p class=\"group-hint\">{{ t.canvasHint }}</p>\n\n <div class=\"canvases\" role=\"radiogroup\" [attr.aria-label]=\"t.canvasTitle\">\n @for (canvas of canvases(); track canvas.id) {\n <button\n type=\"button\"\n class=\"canvas\"\n role=\"radio\"\n [class.is-active]=\"canvas.id === current.canvas\"\n [attr.aria-checked]=\"canvas.id === current.canvas\"\n (click)=\"pickCanvas(canvas.id)\"\n >\n <span\n class=\"canvas-chip\"\n aria-hidden=\"true\"\n [style.background]=\"canvas.bg\"\n [style.color]=\"canvas.text\"\n >\n @if (canvas.icon) {\n <i [class]=\"canvas.icon\"></i>\n } @else {\n <span class=\"canvas-sheet\" [style.background]=\"canvas.surface\"></span>\n }\n </span>\n <span class=\"canvas-name\">{{ canvas.label }}</span>\n </button>\n }\n </div>\n</section>\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.accentTitle }}</h3>\n <p class=\"group-hint\">{{ t.accentHint }}</p>\n\n <div class=\"accents\" role=\"radiogroup\" [attr.aria-label]=\"t.accentTitle\">\n @for (accent of accents(); track accent.id) {\n <button\n type=\"button\"\n class=\"accent\"\n role=\"radio\"\n [class.is-auto]=\"accent.id === 'auto'\"\n [class.is-active]=\"accent.id === current.accent\"\n [attr.aria-checked]=\"accent.id === current.accent\"\n [attr.aria-label]=\"accent.label\"\n [title]=\"accent.label\"\n [style.background]=\"accent.color\"\n [style.color]=\"accent.ink\"\n (click)=\"pickAccent(accent.id)\"\n >\n @if (accent.id === current.accent) {\n <i class=\"pi pi-check\" aria-hidden=\"true\"></i>\n } @else if (accent.id === 'auto') {\n <i class=\"pi pi-sparkles\" aria-hidden=\"true\"></i>\n }\n </button>\n }\n </div>\n</section>\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.densityTitle }}</h3>\n <p class=\"group-hint\">{{ t.densityHint }}</p>\n\n <div class=\"densities\" role=\"radiogroup\" [attr.aria-label]=\"t.densityTitle\">\n @for (density of densities(); track density.id) {\n <button\n type=\"button\"\n class=\"density\"\n role=\"radio\"\n [class.is-active]=\"density.id === current.density\"\n [attr.aria-checked]=\"density.id === current.density\"\n (click)=\"pickDensity(density.id)\"\n >\n <span class=\"density-chip\" aria-hidden=\"true\" [style.gap.px]=\"density.gap\">\n <span class=\"density-row\"></span>\n <span class=\"density-row\"></span>\n <span class=\"density-row\"></span>\n </span>\n <span class=\"density-name\">{{ density.label }}</span>\n </button>\n }\n </div>\n</section>\n", styles: [":host{display:flex;flex-direction:column;gap:26px}.group{display:flex;flex-direction:column;gap:2px}.group-title{margin:0;font-size:13px;font-weight:
|
|
3569
|
+
args: [{ selector: 'nucleus-appearance', changeDetection: ChangeDetectionStrategy.OnPush, template: "@let t = copy();\n@let current = appearance();\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.frameTitle }}</h3>\n <p class=\"group-hint\">{{ t.frameHint }}</p>\n\n <div class=\"frames\" role=\"radiogroup\" [attr.aria-label]=\"t.frameTitle\">\n @for (frame of frames(); track frame.id) {\n <button\n type=\"button\"\n class=\"frame\"\n role=\"radio\"\n [class.is-active]=\"frame.id === current.frame\"\n [attr.aria-checked]=\"frame.id === current.frame\"\n [attr.aria-label]=\"frame.label\"\n [style.--f-bg]=\"frame.tokens.bg\"\n [style.--f-raised]=\"frame.tokens.raised\"\n [style.--f-ink]=\"frame.tokens.ink\"\n [style.--f-muted]=\"frame.tokens.muted\"\n [style.--f-line]=\"frame.tokens.line\"\n [style.--f-glow]=\"frame.tokens.glow\"\n (click)=\"pickFrame(frame.id)\"\n >\n <span class=\"frame-chip\" aria-hidden=\"true\">\n <span class=\"frame-bar\">\n <span class=\"frame-dot\"></span>\n </span>\n <span class=\"frame-lower\">\n <span class=\"frame-rail\">\n <span class=\"frame-pin\"></span>\n <span class=\"frame-row is-on\"></span>\n <span class=\"frame-row\"></span>\n <span class=\"frame-row\"></span>\n </span>\n <span class=\"frame-canvas\"></span>\n </span>\n </span>\n <span class=\"frame-name\">{{ frame.label }}</span>\n </button>\n }\n </div>\n</section>\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.canvasTitle }}</h3>\n <p class=\"group-hint\">{{ t.canvasHint }}</p>\n\n <div class=\"canvases\" role=\"radiogroup\" [attr.aria-label]=\"t.canvasTitle\">\n @for (canvas of canvases(); track canvas.id) {\n <button\n type=\"button\"\n class=\"canvas\"\n role=\"radio\"\n [class.is-active]=\"canvas.id === current.canvas\"\n [attr.aria-checked]=\"canvas.id === current.canvas\"\n (click)=\"pickCanvas(canvas.id)\"\n >\n <span\n class=\"canvas-chip\"\n aria-hidden=\"true\"\n [style.background]=\"canvas.bg\"\n [style.color]=\"canvas.text\"\n >\n @if (canvas.icon) {\n <i [class]=\"canvas.icon\"></i>\n } @else {\n <span class=\"canvas-sheet\" [style.background]=\"canvas.surface\"></span>\n }\n </span>\n <span class=\"canvas-name\">{{ canvas.label }}</span>\n </button>\n }\n </div>\n</section>\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.accentTitle }}</h3>\n <p class=\"group-hint\">{{ t.accentHint }}</p>\n\n <div class=\"accents\" role=\"radiogroup\" [attr.aria-label]=\"t.accentTitle\">\n @for (accent of accents(); track accent.id) {\n <button\n type=\"button\"\n class=\"accent\"\n role=\"radio\"\n [class.is-auto]=\"accent.id === 'auto'\"\n [class.is-active]=\"accent.id === current.accent\"\n [attr.aria-checked]=\"accent.id === current.accent\"\n [attr.aria-label]=\"accent.label\"\n [title]=\"accent.label\"\n [style.background]=\"accent.color\"\n [style.color]=\"accent.ink\"\n (click)=\"pickAccent(accent.id)\"\n >\n @if (accent.id === current.accent) {\n <i class=\"pi pi-check\" aria-hidden=\"true\"></i>\n } @else if (accent.id === 'auto') {\n <i class=\"pi pi-sparkles\" aria-hidden=\"true\"></i>\n }\n </button>\n }\n </div>\n</section>\n\n<section class=\"group\">\n <h3 class=\"group-title\">{{ t.densityTitle }}</h3>\n <p class=\"group-hint\">{{ t.densityHint }}</p>\n\n <div class=\"densities\" role=\"radiogroup\" [attr.aria-label]=\"t.densityTitle\">\n @for (density of densities(); track density.id) {\n <button\n type=\"button\"\n class=\"density\"\n role=\"radio\"\n [class.is-active]=\"density.id === current.density\"\n [attr.aria-checked]=\"density.id === current.density\"\n (click)=\"pickDensity(density.id)\"\n >\n <span class=\"density-chip\" aria-hidden=\"true\" [style.gap.px]=\"density.gap\">\n <span class=\"density-row\"></span>\n <span class=\"density-row\"></span>\n <span class=\"density-row\"></span>\n </span>\n <span class=\"density-name\">{{ density.label }}</span>\n </button>\n }\n </div>\n</section>\n", styles: [":host{display:flex;flex-direction:column;gap:26px}.group{display:flex;flex-direction:column;gap:2px}.group-title{margin:0;font-size:13px;font-weight:var(--ns-weight-heading);letter-spacing:.02em}.group-hint{margin:0 0 12px;color:var(--ac-text-muted);font-size:12px;font-weight:300;line-height:1.45}.frames{display:grid;grid-template-columns:repeat(auto-fill,minmax(84px,1fr));gap:10px}.frame{display:flex;flex-direction:column;gap:6px;padding:4px;border:2px solid transparent;border-radius:10px;background:transparent;color:var(--ac-text-muted);cursor:pointer}.frame:hover{color:var(--ac-text)}.frame.is-active{border-color:var(--ac-accent);color:var(--ac-text)}.frame-chip{display:flex;overflow:hidden;flex-direction:column;height:52px;border:1px solid var(--f-line);border-radius:6px;background:var(--f-bg)}.frame-bar{display:flex;flex:none;align-items:center;height:12px;padding-left:5px;border-bottom:1px solid var(--f-line)}.frame-dot{width:5px;height:5px;border-radius:50%;background:var(--f-glow)}.frame-lower{display:flex;flex:1;min-height:0}.frame-rail{display:flex;flex:none;flex-direction:column;gap:3px;width:22px;padding:4px 3px;border-right:1px solid var(--f-line)}.frame-pin{height:7px;border-left:2px solid var(--f-glow);border-radius:2px;background:var(--f-raised)}.frame-row{height:3px;border-radius:2px;background:var(--f-muted);opacity:.55}.frame-row.is-on{background:var(--f-glow);opacity:1}.frame-canvas{flex:1;background:var(--ac-bg)}.frame-name{overflow:hidden;font-size:11px;font-weight:var(--ns-weight-emphasis);text-align:center;text-overflow:ellipsis;white-space:nowrap}.canvases{display:grid;grid-template-columns:repeat(auto-fit,minmax(70px,1fr));gap:8px}.canvas{display:flex;flex-direction:column;gap:6px;padding:4px;border:2px solid transparent;border-radius:10px;background:transparent;color:var(--ac-text-muted);cursor:pointer}.canvas:hover{color:var(--ac-text)}.canvas.is-active{border-color:var(--ac-accent);color:var(--ac-text)}.canvas-chip{display:flex;align-items:center;justify-content:center;height:40px;border:1px solid var(--ac-border);border-radius:6px}.canvas-chip i{font-size:15px}.canvas-sheet{width:60%;height:58%;border-radius:3px;box-shadow:0 1px 4px #00000038}.canvas-name{font-size:11px;font-weight:var(--ns-weight-emphasis);text-align:center}.accents{display:flex;flex-wrap:wrap;gap:9px}.accent{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:2px solid transparent;border-radius:50%;cursor:pointer;transition:transform .12s ease}.accent:hover{transform:scale(1.12)}.accent.is-auto{border-style:dashed;border-color:var(--ac-border)}.accent.is-active{border-style:solid;border-color:var(--ac-text);box-shadow:0 0 0 2px var(--ac-surface) inset}.accent i{font-size:11px}.densities{display:flex;gap:10px}.density{display:flex;flex:1;flex-direction:column;gap:6px;padding:4px;border:2px solid transparent;border-radius:10px;background:transparent;color:var(--ac-text-muted);cursor:pointer}.density:hover{color:var(--ac-text)}.density.is-active{border-color:var(--ac-accent);color:var(--ac-text)}.density-chip{display:flex;flex-direction:column;justify-content:center;height:42px;padding:0 10px;border:1px solid var(--ac-border);border-radius:6px;background:var(--ac-surface)}.density-row{height:3px;border-radius:2px;background:var(--ac-text-muted);opacity:.5}.density-name{font-size:11px;font-weight:var(--ns-weight-emphasis);text-align:center}@media(prefers-reduced-motion:reduce){.accent{transition:none}}\n"] }]
|
|
3174
3570
|
}] });
|
|
3175
3571
|
|
|
3176
|
-
function menuTile(label, icon, color) {
|
|
3177
|
-
return { label, icon, color, ink: color ? readableOn(color) : null, ghost: false };
|
|
3178
|
-
}
|
|
3179
|
-
function menuGlyph(icon) {
|
|
3180
|
-
return { label: '', icon, color: null, ink: null, ghost: true };
|
|
3181
|
-
}
|
|
3182
|
-
function foldText(value) {
|
|
3183
|
-
return value
|
|
3184
|
-
.normalize('NFD')
|
|
3185
|
-
.replace(/[̀-ͯ]/g, '')
|
|
3186
|
-
.toLowerCase();
|
|
3187
|
-
}
|
|
3188
|
-
function matchesRow(row, term) {
|
|
3189
|
-
return foldText(row.name).includes(term) || foldText(row.meta ?? '').includes(term);
|
|
3190
|
-
}
|
|
3191
|
-
function selectableRows(sections) {
|
|
3192
|
-
return sections.flatMap((section) => section.rows).filter((row) => !row.disabled && !row.current);
|
|
3193
|
-
}
|
|
3194
|
-
|
|
3195
3572
|
class NucleusMenu {
|
|
3196
3573
|
sections = input([], ...(ngDevMode ? [{ debugName: "sections" }] : /* istanbul ignore next */ []));
|
|
3197
3574
|
heading = input('', ...(ngDevMode ? [{ debugName: "heading" }] : /* istanbul ignore next */ []));
|
|
@@ -3201,9 +3578,14 @@ class NucleusMenu {
|
|
|
3201
3578
|
emptyText = input('', ...(ngDevMode ? [{ debugName: "emptyText" }] : /* istanbul ignore next */ []));
|
|
3202
3579
|
keyboardHint = input('', ...(ngDevMode ? [{ debugName: "keyboardHint" }] : /* istanbul ignore next */ []));
|
|
3203
3580
|
width = input(320, ...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
|
|
3581
|
+
layout = input('list', ...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
3582
|
+
columns = input(3, ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
3204
3583
|
select = output();
|
|
3205
3584
|
dismiss = output();
|
|
3206
3585
|
term = signal('', ...(ngDevMode ? [{ debugName: "term" }] : /* istanbul ignore next */ []));
|
|
3586
|
+
grid = computed(() => this.layout() === 'grid', ...(ngDevMode ? [{ debugName: "grid" }] : /* istanbul ignore next */ []));
|
|
3587
|
+
keyed = signal(false, ...(ngDevMode ? [{ debugName: "keyed" }] : /* istanbul ignore next */ []));
|
|
3588
|
+
pointed = computed(() => this.searchable() || this.keyed(), ...(ngDevMode ? [{ debugName: "pointed" }] : /* istanbul ignore next */ []));
|
|
3207
3589
|
searchBox = viewChild('searchBox', ...(ngDevMode ? [{ debugName: "searchBox" }] : /* istanbul ignore next */ []));
|
|
3208
3590
|
root = viewChild.required('root');
|
|
3209
3591
|
visible = computed(() => {
|
|
@@ -3230,7 +3612,7 @@ class NucleusMenu {
|
|
|
3230
3612
|
queueMicrotask(() => this.focusEntry());
|
|
3231
3613
|
}
|
|
3232
3614
|
isActive(row) {
|
|
3233
|
-
return row.id === this.activeId();
|
|
3615
|
+
return this.pointed() && row.id === this.activeId();
|
|
3234
3616
|
}
|
|
3235
3617
|
onTerm(value) {
|
|
3236
3618
|
this.term.set(value);
|
|
@@ -3246,12 +3628,15 @@ class NucleusMenu {
|
|
|
3246
3628
|
this.dismiss.emit();
|
|
3247
3629
|
return;
|
|
3248
3630
|
}
|
|
3249
|
-
|
|
3631
|
+
const move = this.moveOf(event.key);
|
|
3632
|
+
if (move) {
|
|
3250
3633
|
event.preventDefault();
|
|
3251
|
-
this.
|
|
3634
|
+
if (this.pointed())
|
|
3635
|
+
this.step(move);
|
|
3636
|
+
this.keyed.set(true);
|
|
3252
3637
|
return;
|
|
3253
3638
|
}
|
|
3254
|
-
if (event.key === 'Enter') {
|
|
3639
|
+
if (event.key === 'Enter' && this.pointed()) {
|
|
3255
3640
|
const row = this.reachable().find((item) => item.id === this.activeId());
|
|
3256
3641
|
if (!row)
|
|
3257
3642
|
return;
|
|
@@ -3259,15 +3644,41 @@ class NucleusMenu {
|
|
|
3259
3644
|
this.choose(row);
|
|
3260
3645
|
}
|
|
3261
3646
|
}
|
|
3262
|
-
|
|
3647
|
+
moveOf(key) {
|
|
3648
|
+
const grid = this.grid();
|
|
3649
|
+
const jump = grid ? this.columns() : 1;
|
|
3650
|
+
if (key === 'ArrowDown')
|
|
3651
|
+
return { delta: jump, wrap: !grid };
|
|
3652
|
+
if (key === 'ArrowUp')
|
|
3653
|
+
return { delta: -jump, wrap: !grid };
|
|
3654
|
+
if (!grid || this.term())
|
|
3655
|
+
return null;
|
|
3656
|
+
if (key === 'ArrowRight')
|
|
3657
|
+
return { delta: 1, wrap: true };
|
|
3658
|
+
if (key === 'ArrowLeft')
|
|
3659
|
+
return { delta: -1, wrap: true };
|
|
3660
|
+
return null;
|
|
3661
|
+
}
|
|
3662
|
+
step(move) {
|
|
3263
3663
|
const rows = this.reachable();
|
|
3264
3664
|
if (!rows.length)
|
|
3265
3665
|
return;
|
|
3266
3666
|
const index = rows.findIndex((row) => row.id === this.activeId());
|
|
3267
|
-
const next = (index
|
|
3667
|
+
const next = this.landing(index, move, rows.length);
|
|
3268
3668
|
this.activeId.set(rows[next].id);
|
|
3269
3669
|
this.scrollIntoView(rows[next].id);
|
|
3270
3670
|
}
|
|
3671
|
+
landing(index, move, size) {
|
|
3672
|
+
const target = index + move.delta;
|
|
3673
|
+
if (move.wrap)
|
|
3674
|
+
return (target + size) % size;
|
|
3675
|
+
if (target < 0)
|
|
3676
|
+
return Math.max(index, 0);
|
|
3677
|
+
if (target < size)
|
|
3678
|
+
return target;
|
|
3679
|
+
const lastRowStart = size - 1 - ((size - 1) % move.delta);
|
|
3680
|
+
return index < lastRowStart ? size - 1 : index;
|
|
3681
|
+
}
|
|
3271
3682
|
scrollIntoView(id) {
|
|
3272
3683
|
const target = this.root().nativeElement.querySelector(`[data-row="${id}"]`);
|
|
3273
3684
|
target?.scrollIntoView({ block: 'nearest' });
|
|
@@ -3281,15 +3692,16 @@ class NucleusMenu {
|
|
|
3281
3692
|
this.root().nativeElement.focus();
|
|
3282
3693
|
}
|
|
3283
3694
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3284
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: NucleusMenu, isStandalone: true, selector: "nucleus-menu", inputs: { sections: { classPropertyName: "sections", publicName: "sections", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, keyboardHint: { classPropertyName: "keyboardHint", publicName: "keyboardHint", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select", dismiss: "dismiss" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "style.width.px": "width()" } }, viewQueries: [{ propertyName: "searchBox", first: true, predicate: ["searchBox"], descendants: true, isSignal: true }, { propertyName: "root", first: true, predicate: ["root"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"menu\" #root tabindex=\"-1\">\n @if (heading()) {\n <div class=\"menu-head\">\n <h4>{{ heading() }}</h4>\n @if (badge(); as count) {\n <span class=\"menu-badge\">{{ count }}</span>\n }\n </div>\n }\n\n @if (showSearch()) {\n <div class=\"menu-search\">\n <label class=\"menu-field\">\n <i class=\"pi pi-search\" aria-hidden=\"true\"></i>\n <input\n #searchBox\n type=\"text\"\n autocomplete=\"off\"\n [attr.aria-label]=\"searchPlaceholder()\"\n [placeholder]=\"searchPlaceholder()\"\n [value]=\"term()\"\n (input)=\"onTerm($any($event.target).value)\"\n />\n </label>\n </div>\n }\n\n <div class=\"menu-body\" role=\"listbox\" [attr.aria-label]=\"heading()\">\n @if (isEmpty()) {\n <p class=\"menu-empty\">{{ emptyText() }}</p>\n }\n\n @for (section of visible(); track section.id) {\n @if (section.rows.length) {\n @if (section.label) {\n <p class=\"menu-section\">{{ section.label }}</p>\n }\n\n @for (row of section.rows; track row.id) {\n <button\n type=\"button\"\n class=\"menu-row\"\n role=\"option\"\n [attr.data-row]=\"row.id\"\n [class.is-current]=\"row.current\"\n [class.is-locked]=\"row.disabled\"\n [class.is-active]=\"isActive(row)\"\n [attr.aria-selected]=\"isActive(row)\"\n [disabled]=\"row.disabled || row.current\"\n (click)=\"choose(row)\"\n >\n @if (row.tile; as tile) {\n <span\n class=\"menu-tile\"\n [class.is-ghost]=\"tile.ghost\"\n [style.background]=\"tile.ghost ? null : tile.color\"\n [style.color]=\"tile.ghost ? null : tile.ink\"\n aria-hidden=\"true\"\n >\n @if (tile.icon) {\n <i [class]=\"tile.icon\"></i>\n } @else {\n {{ tile.label }}\n }\n </span>\n }\n\n <span class=\"menu-text\">\n <span class=\"menu-name\">{{ row.name }}</span>\n @if (row.meta) {\n <span class=\"menu-meta\">{{ row.meta }}</span>\n }\n </span>\n\n <span class=\"menu-end\">\n @if (row.tag) {\n <span class=\"menu-tag\" [class.is-current]=\"row.current\">{{ row.tag }}</span>\n } @else if (!row.disabled && !row.current) {\n <i class=\"pi pi-chevron-right menu-chevron\" aria-hidden=\"true\"></i>\n }\n </span>\n </button>\n }\n }\n }\n </div>\n\n @if (showSearch() && keyboardHint()) {\n <p class=\"menu-foot\">{{ keyboardHint() }}</p>\n }\n</div>\n", styles: [":host{display:block}.menu{display:flex;flex-direction:column;min-width:0}.menu:focus-visible{outline:none}.menu-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 15px 10px;border-bottom:1px solid var(--ac-border);background:var(--ns-header-bg)}.menu-head h4{margin:0;overflow:hidden;color:var(--ns-header-ink);font-size:11px;font-weight:600;letter-spacing:.08em;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap}.menu-badge{flex:none;padding:1px 8px;border-radius:var(--ac-radius-pill);background:var(--ac-surface-alt);color:var(--ac-text-muted);font-size:10px;font-variant-numeric:tabular-nums}.menu-search{padding:9px 10px;border-bottom:1px solid var(--ac-border)}.menu-field{position:relative;display:block}.menu-field i{position:absolute;top:50%;left:11px;color:var(--ac-text-muted);font-size:12px;pointer-events:none;transform:translateY(-50%)}.menu-field input{width:100%;box-sizing:border-box;padding:7px 10px 7px 31px;border:1px solid var(--ac-border);border-radius:7px;background:var(--ac-bg);color:var(--ac-text);font:inherit;font-size:13px}.menu-field input::placeholder{color:var(--ac-text-muted)}.menu-field input:focus-visible{border-color:var(--ac-accent);outline:2px solid color-mix(in srgb,var(--ac-accent) 45%,transparent);outline-offset:1px}.menu-body{display:flex;max-height:348px;flex-direction:column;gap:1px;padding:6px;overflow-y:auto}.menu-section{margin:0;padding:11px 9px 5px;color:var(--ac-text-muted);font-size:10px;font-weight:600;letter-spacing:.08em;text-transform:uppercase}.menu-empty{margin:0;padding:26px 14px;color:var(--ac-text-muted);font-size:12px;text-align:center}.menu-row{display:flex;width:100%;align-items:center;gap:11px;padding:9px 10px;border:0;border-radius:8px;background:transparent;color:var(--ac-text);font:inherit;text-align:left;cursor:pointer}.menu-row:hover:not(:disabled),.menu-row.is-active:not(:disabled){background:var(--ns-accent-wash);box-shadow:inset 2px 0 0 var(--ac-accent)}.menu-row:focus-visible{outline:none}.menu-row.is-current{background:var(--ac-surface-alt);box-shadow:none;cursor:default}.menu-row.is-locked{cursor:default;opacity:.55}.menu-tile{display:inline-flex;width:34px;height:34px;flex:none;align-items:center;justify-content:center;border-radius:9px;font-size:11.5px;font-weight:600;letter-spacing:.02em}.menu-tile i{font-size:14px}.menu-tile.is-ghost{background:var(--ac-surface-alt);color:var(--ac-text-muted)}.menu-row:hover:not(:disabled) .menu-tile.is-ghost,.menu-row.is-active:not(:disabled) .menu-tile.is-ghost{color:var(--ac-accent)}.menu-text{display:flex;min-width:0;flex-direction:column;gap:1px}.menu-name{overflow:hidden;font-size:13px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.menu-meta{overflow:hidden;color:var(--ac-text-muted);font-size:11px;text-overflow:ellipsis;white-space:nowrap}.menu-end{display:flex;flex:none;align-items:center;margin-left:auto}.menu-chevron{color:var(--ac-accent);font-size:11px;opacity:0}.menu-row:hover:not(:disabled) .menu-chevron,.menu-row.is-active:not(:disabled) .menu-chevron{opacity:1}.menu-tag{padding:2px 7px;border-radius:4px;background:var(--ac-surface-alt);color:var(--ac-text-muted);font-size:9.5px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;white-space:nowrap}.menu-tag.is-current{background:color-mix(in srgb,var(--ac-accent) 16%,transparent);color:var(--ac-accent)}.menu-foot{margin:0;padding:8px 14px;border-top:1px solid var(--ac-border);color:var(--ac-text-muted);font-size:10.5px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3695
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: NucleusMenu, isStandalone: true, selector: "nucleus-menu", inputs: { sections: { classPropertyName: "sections", publicName: "sections", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, keyboardHint: { classPropertyName: "keyboardHint", publicName: "keyboardHint", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select", dismiss: "dismiss" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "style.width.px": "width()", "style.--menu-columns": "columns()" } }, viewQueries: [{ propertyName: "searchBox", first: true, predicate: ["searchBox"], descendants: true, isSignal: true }, { propertyName: "root", first: true, predicate: ["root"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"menu\" #root tabindex=\"-1\" [class.is-grid]=\"grid()\">\n @if (heading() && !grid()) {\n <div class=\"menu-head\">\n <h4>{{ heading() }}</h4>\n @if (badge(); as count) {\n <span class=\"menu-badge\">{{ count }}</span>\n }\n </div>\n }\n\n @if (showSearch()) {\n <div class=\"menu-search\">\n <label class=\"menu-field\">\n <i class=\"pi pi-search\" aria-hidden=\"true\"></i>\n <input\n #searchBox\n type=\"text\"\n autocomplete=\"off\"\n [attr.aria-label]=\"searchPlaceholder()\"\n [placeholder]=\"searchPlaceholder()\"\n [value]=\"term()\"\n (input)=\"onTerm($any($event.target).value)\"\n />\n </label>\n </div>\n }\n\n <div class=\"menu-body\" role=\"listbox\" [attr.aria-label]=\"heading()\">\n @if (isEmpty()) {\n <p class=\"menu-empty\">{{ emptyText() }}</p>\n }\n\n @for (section of visible(); track section.id) {\n @if (section.rows.length) {\n @if (section.label) {\n <p class=\"menu-section\">\n {{ section.label }}\n @if (grid()) {\n <span class=\"menu-count\">{{ section.rows.length }}</span>\n }\n </p>\n }\n\n <div class=\"menu-group\" role=\"group\" [attr.aria-label]=\"section.label\">\n @for (row of section.rows; track row.id) {\n <button\n type=\"button\"\n class=\"menu-row\"\n role=\"option\"\n [attr.data-row]=\"row.id\"\n [attr.title]=\"grid() && row.disabled ? row.tag : null\"\n [class.is-current]=\"row.current\"\n [class.is-locked]=\"row.disabled\"\n [class.is-active]=\"isActive(row)\"\n [attr.aria-selected]=\"isActive(row)\"\n [disabled]=\"row.disabled || row.current\"\n (click)=\"choose(row)\"\n >\n @if (row.tile; as tile) {\n <span\n class=\"menu-tile\"\n [class.is-ghost]=\"tile.ghost\"\n [class.is-outline]=\"grid() && row.disabled\"\n [style.background]=\"tile.ghost || (grid() && row.disabled) ? null : tile.color\"\n [style.color]=\"tile.ghost || (grid() && row.disabled) ? null : tile.ink\"\n aria-hidden=\"true\"\n >\n @if (tile.icon) {\n <i [class]=\"tile.icon\"></i>\n } @else {\n {{ tile.label }}\n }\n </span>\n }\n\n <span class=\"menu-text\">\n <span class=\"menu-name\">{{ row.name }}</span>\n @if (grid() && row.current && row.tag) {\n <span class=\"menu-meta\">{{ row.tag }}</span>\n } @else if (!grid() && row.meta) {\n <span class=\"menu-meta\">{{ row.meta }}</span>\n }\n </span>\n\n @if (grid() && row.current) {\n <span class=\"menu-end\">\n <span class=\"menu-dot\" aria-hidden=\"true\"></span>\n </span>\n } @else if (!grid()) {\n <span class=\"menu-end\">\n @if (row.tag) {\n <span class=\"menu-tag\" [class.is-current]=\"row.current\">{{ row.tag }}</span>\n } @else if (!row.disabled && !row.current) {\n <i class=\"pi pi-chevron-right menu-chevron\" aria-hidden=\"true\"></i>\n }\n </span>\n }\n </button>\n }\n </div>\n }\n }\n </div>\n\n @if (showSearch() && keyboardHint()) {\n <p class=\"menu-foot\">{{ keyboardHint() }}</p>\n }\n</div>\n", styles: [":host{display:block;max-width:calc(100vw - 24px)}.menu{display:flex;flex-direction:column;min-width:0}.menu:focus-visible{outline:none}.menu-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 15px 10px;border-bottom:1px solid var(--ac-border);background:var(--ns-header-bg)}.menu-head h4{margin:0;overflow:hidden;color:var(--ns-header-ink);font-size:11px;font-weight:var(--ns-weight-heading);letter-spacing:.08em;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap}.menu-badge{flex:none;padding:1px 8px;border-radius:var(--ac-radius-pill);background:var(--ac-surface-alt);color:var(--ac-text-muted);font-size:10px;font-variant-numeric:tabular-nums}.menu-search{padding:9px 10px;border-bottom:1px solid var(--ac-border)}.menu-field{position:relative;display:block}.menu-field i{position:absolute;top:50%;left:11px;color:var(--ac-text-muted);font-size:12px;pointer-events:none;transform:translateY(-50%)}.menu-field input{width:100%;box-sizing:border-box;padding:7px 10px 7px 31px;border:1px solid var(--ac-border);border-radius:7px;background:var(--ac-bg);color:var(--ac-text);font:inherit;font-size:13px}.menu-field input::placeholder{color:var(--ac-text-muted)}.menu-field input:focus-visible{border-color:var(--ac-accent);outline:2px solid color-mix(in srgb,var(--ac-accent) 45%,transparent);outline-offset:1px}.menu-body{display:flex;max-height:348px;flex-direction:column;gap:1px;padding:6px;overflow-y:auto}.menu-section{margin:0;padding:11px 9px 5px;color:var(--ac-text-muted);font-size:10px;font-weight:var(--ns-weight-heading);letter-spacing:.08em;text-transform:uppercase}.menu-count:before{margin:0 5px;content:\"\\b7\"}.menu-group{display:flex;flex-direction:column;gap:1px}.menu-empty{margin:0;padding:26px 14px;color:var(--ac-text-muted);font-size:12px;text-align:center}.menu-row{display:flex;width:100%;align-items:center;gap:11px;padding:9px 10px;border:1px solid transparent;border-radius:10px;background:transparent;color:var(--ac-text);font:inherit;text-align:left;cursor:pointer}.menu-row:hover:not(:disabled),.menu-row.is-active:not(:disabled){border-color:color-mix(in srgb,var(--ac-accent) 38%,transparent);background:var(--ns-accent-wash)}.menu-row:focus-visible{outline:none}.menu-row.is-current{background:var(--ac-surface-alt);cursor:default}.menu-row.is-locked{cursor:default;opacity:.55}.menu-tile{display:inline-flex;width:34px;height:34px;flex:none;align-items:center;justify-content:center;border-radius:9px;font-size:11.5px;font-weight:var(--ns-weight-heading);letter-spacing:.02em}.menu-tile i{font-size:14px}.menu-tile.is-ghost{background:var(--ac-surface-alt);color:var(--ac-text-muted)}.menu-row:hover:not(:disabled) .menu-tile.is-ghost,.menu-row.is-active:not(:disabled) .menu-tile.is-ghost{color:var(--ac-accent)}.menu-text{display:flex;min-width:0;flex-direction:column;gap:1px}.menu-name{overflow:hidden;font-size:13px;font-weight:var(--ns-weight-emphasis);text-overflow:ellipsis;white-space:nowrap}.menu-meta{overflow:hidden;color:var(--ac-text-muted);font-size:11px;text-overflow:ellipsis;white-space:nowrap}.menu-end{display:flex;flex:none;align-items:center;margin-left:auto}.menu-chevron{color:var(--ac-accent);font-size:11px;opacity:0}.menu-row:hover:not(:disabled) .menu-chevron,.menu-row.is-active:not(:disabled) .menu-chevron{opacity:1}.menu-tag{padding:2px 7px;border-radius:4px;background:var(--ac-surface-alt);color:var(--ac-text-muted);font-size:9.5px;font-weight:var(--ns-weight-heading);letter-spacing:.04em;text-transform:uppercase;white-space:nowrap}.menu-tag.is-current{background:color-mix(in srgb,var(--ac-accent) 16%,transparent);color:var(--ac-accent)}.menu-foot{margin:0;padding:8px 14px;border-top:1px solid var(--ac-border);color:var(--ac-text-muted);font-size:10.5px}.menu-dot{width:8px;height:8px;border-radius:var(--ac-radius-pill);background:var(--ns-success)}.menu.is-grid .menu-search{padding:10px 10px 0;border-bottom:0}.menu.is-grid .menu-body{max-height:min(540px,calc(100dvh - 190px));gap:2px;padding:10px}.menu.is-grid .menu-section{padding:12px 6px 6px}.menu.is-grid .menu-group{display:grid;grid-template-columns:repeat(var(--menu-columns, 3),minmax(0,1fr));gap:4px}.menu.is-grid .menu-row{flex-direction:column;gap:7px;padding:11px 6px 9px;text-align:center}.menu.is-grid .menu-row.is-locked{opacity:1}.menu.is-grid .menu-tile{width:40px;height:40px;border-radius:11px;font-size:12px}.menu.is-grid .menu-tile i{font-size:16px}.menu.is-grid .menu-tile.is-outline{border:1px dashed color-mix(in srgb,var(--ac-text-muted) 55%,transparent);background:transparent;color:var(--ac-text-muted)}.menu.is-grid .menu-text{width:100%;align-items:center}.menu.is-grid .menu-name{display:-webkit-box;max-width:100%;font-size:12px;line-height:1.25;white-space:normal;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}.menu.is-grid .menu-row.is-locked .menu-name{color:var(--ac-text-muted);font-weight:var(--ns-weight-text)}.menu.is-grid .menu-row.is-current{grid-column:1 / -1;flex-direction:row;gap:12px;padding:10px 12px;background:var(--ac-text);color:var(--ac-surface);text-align:left}.menu.is-grid .menu-row.is-current .menu-tile{width:36px;height:36px;border-radius:10px}.menu.is-grid .menu-row.is-current .menu-text{width:auto;align-items:flex-start}.menu.is-grid .menu-row.is-current .menu-name{display:block;font-size:13px;white-space:nowrap}.menu.is-grid .menu-row.is-current .menu-meta{color:color-mix(in srgb,currentColor 64%,transparent)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3285
3696
|
}
|
|
3286
3697
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusMenu, decorators: [{
|
|
3287
3698
|
type: Component,
|
|
3288
3699
|
args: [{ selector: 'nucleus-menu', host: {
|
|
3289
3700
|
'[style.width.px]': 'width()',
|
|
3701
|
+
'[style.--menu-columns]': 'columns()',
|
|
3290
3702
|
'(keydown)': 'onKeydown($event)',
|
|
3291
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"menu\" #root tabindex=\"-1\">\n @if (heading()) {\n <div class=\"menu-head\">\n <h4>{{ heading() }}</h4>\n @if (badge(); as count) {\n <span class=\"menu-badge\">{{ count }}</span>\n }\n </div>\n }\n\n @if (showSearch()) {\n <div class=\"menu-search\">\n <label class=\"menu-field\">\n <i class=\"pi pi-search\" aria-hidden=\"true\"></i>\n <input\n #searchBox\n type=\"text\"\n autocomplete=\"off\"\n [attr.aria-label]=\"searchPlaceholder()\"\n [placeholder]=\"searchPlaceholder()\"\n [value]=\"term()\"\n (input)=\"onTerm($any($event.target).value)\"\n />\n </label>\n </div>\n }\n\n <div class=\"menu-body\" role=\"listbox\" [attr.aria-label]=\"heading()\">\n @if (isEmpty()) {\n <p class=\"menu-empty\">{{ emptyText() }}</p>\n }\n\n @for (section of visible(); track section.id) {\n @if (section.rows.length) {\n @if (section.label) {\n <p class=\"menu-section\"
|
|
3292
|
-
}], ctorParameters: () => [], propDecorators: { sections: [{ type: i0.Input, args: [{ isSignal: true, alias: "sections", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], keyboardHint: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyboardHint", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], select: [{ type: i0.Output, args: ["select"] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }], searchBox: [{ type: i0.ViewChild, args: ['searchBox', { isSignal: true }] }], root: [{ type: i0.ViewChild, args: ['root', { isSignal: true }] }] } });
|
|
3703
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"menu\" #root tabindex=\"-1\" [class.is-grid]=\"grid()\">\n @if (heading() && !grid()) {\n <div class=\"menu-head\">\n <h4>{{ heading() }}</h4>\n @if (badge(); as count) {\n <span class=\"menu-badge\">{{ count }}</span>\n }\n </div>\n }\n\n @if (showSearch()) {\n <div class=\"menu-search\">\n <label class=\"menu-field\">\n <i class=\"pi pi-search\" aria-hidden=\"true\"></i>\n <input\n #searchBox\n type=\"text\"\n autocomplete=\"off\"\n [attr.aria-label]=\"searchPlaceholder()\"\n [placeholder]=\"searchPlaceholder()\"\n [value]=\"term()\"\n (input)=\"onTerm($any($event.target).value)\"\n />\n </label>\n </div>\n }\n\n <div class=\"menu-body\" role=\"listbox\" [attr.aria-label]=\"heading()\">\n @if (isEmpty()) {\n <p class=\"menu-empty\">{{ emptyText() }}</p>\n }\n\n @for (section of visible(); track section.id) {\n @if (section.rows.length) {\n @if (section.label) {\n <p class=\"menu-section\">\n {{ section.label }}\n @if (grid()) {\n <span class=\"menu-count\">{{ section.rows.length }}</span>\n }\n </p>\n }\n\n <div class=\"menu-group\" role=\"group\" [attr.aria-label]=\"section.label\">\n @for (row of section.rows; track row.id) {\n <button\n type=\"button\"\n class=\"menu-row\"\n role=\"option\"\n [attr.data-row]=\"row.id\"\n [attr.title]=\"grid() && row.disabled ? row.tag : null\"\n [class.is-current]=\"row.current\"\n [class.is-locked]=\"row.disabled\"\n [class.is-active]=\"isActive(row)\"\n [attr.aria-selected]=\"isActive(row)\"\n [disabled]=\"row.disabled || row.current\"\n (click)=\"choose(row)\"\n >\n @if (row.tile; as tile) {\n <span\n class=\"menu-tile\"\n [class.is-ghost]=\"tile.ghost\"\n [class.is-outline]=\"grid() && row.disabled\"\n [style.background]=\"tile.ghost || (grid() && row.disabled) ? null : tile.color\"\n [style.color]=\"tile.ghost || (grid() && row.disabled) ? null : tile.ink\"\n aria-hidden=\"true\"\n >\n @if (tile.icon) {\n <i [class]=\"tile.icon\"></i>\n } @else {\n {{ tile.label }}\n }\n </span>\n }\n\n <span class=\"menu-text\">\n <span class=\"menu-name\">{{ row.name }}</span>\n @if (grid() && row.current && row.tag) {\n <span class=\"menu-meta\">{{ row.tag }}</span>\n } @else if (!grid() && row.meta) {\n <span class=\"menu-meta\">{{ row.meta }}</span>\n }\n </span>\n\n @if (grid() && row.current) {\n <span class=\"menu-end\">\n <span class=\"menu-dot\" aria-hidden=\"true\"></span>\n </span>\n } @else if (!grid()) {\n <span class=\"menu-end\">\n @if (row.tag) {\n <span class=\"menu-tag\" [class.is-current]=\"row.current\">{{ row.tag }}</span>\n } @else if (!row.disabled && !row.current) {\n <i class=\"pi pi-chevron-right menu-chevron\" aria-hidden=\"true\"></i>\n }\n </span>\n }\n </button>\n }\n </div>\n }\n }\n </div>\n\n @if (showSearch() && keyboardHint()) {\n <p class=\"menu-foot\">{{ keyboardHint() }}</p>\n }\n</div>\n", styles: [":host{display:block;max-width:calc(100vw - 24px)}.menu{display:flex;flex-direction:column;min-width:0}.menu:focus-visible{outline:none}.menu-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 15px 10px;border-bottom:1px solid var(--ac-border);background:var(--ns-header-bg)}.menu-head h4{margin:0;overflow:hidden;color:var(--ns-header-ink);font-size:11px;font-weight:var(--ns-weight-heading);letter-spacing:.08em;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap}.menu-badge{flex:none;padding:1px 8px;border-radius:var(--ac-radius-pill);background:var(--ac-surface-alt);color:var(--ac-text-muted);font-size:10px;font-variant-numeric:tabular-nums}.menu-search{padding:9px 10px;border-bottom:1px solid var(--ac-border)}.menu-field{position:relative;display:block}.menu-field i{position:absolute;top:50%;left:11px;color:var(--ac-text-muted);font-size:12px;pointer-events:none;transform:translateY(-50%)}.menu-field input{width:100%;box-sizing:border-box;padding:7px 10px 7px 31px;border:1px solid var(--ac-border);border-radius:7px;background:var(--ac-bg);color:var(--ac-text);font:inherit;font-size:13px}.menu-field input::placeholder{color:var(--ac-text-muted)}.menu-field input:focus-visible{border-color:var(--ac-accent);outline:2px solid color-mix(in srgb,var(--ac-accent) 45%,transparent);outline-offset:1px}.menu-body{display:flex;max-height:348px;flex-direction:column;gap:1px;padding:6px;overflow-y:auto}.menu-section{margin:0;padding:11px 9px 5px;color:var(--ac-text-muted);font-size:10px;font-weight:var(--ns-weight-heading);letter-spacing:.08em;text-transform:uppercase}.menu-count:before{margin:0 5px;content:\"\\b7\"}.menu-group{display:flex;flex-direction:column;gap:1px}.menu-empty{margin:0;padding:26px 14px;color:var(--ac-text-muted);font-size:12px;text-align:center}.menu-row{display:flex;width:100%;align-items:center;gap:11px;padding:9px 10px;border:1px solid transparent;border-radius:10px;background:transparent;color:var(--ac-text);font:inherit;text-align:left;cursor:pointer}.menu-row:hover:not(:disabled),.menu-row.is-active:not(:disabled){border-color:color-mix(in srgb,var(--ac-accent) 38%,transparent);background:var(--ns-accent-wash)}.menu-row:focus-visible{outline:none}.menu-row.is-current{background:var(--ac-surface-alt);cursor:default}.menu-row.is-locked{cursor:default;opacity:.55}.menu-tile{display:inline-flex;width:34px;height:34px;flex:none;align-items:center;justify-content:center;border-radius:9px;font-size:11.5px;font-weight:var(--ns-weight-heading);letter-spacing:.02em}.menu-tile i{font-size:14px}.menu-tile.is-ghost{background:var(--ac-surface-alt);color:var(--ac-text-muted)}.menu-row:hover:not(:disabled) .menu-tile.is-ghost,.menu-row.is-active:not(:disabled) .menu-tile.is-ghost{color:var(--ac-accent)}.menu-text{display:flex;min-width:0;flex-direction:column;gap:1px}.menu-name{overflow:hidden;font-size:13px;font-weight:var(--ns-weight-emphasis);text-overflow:ellipsis;white-space:nowrap}.menu-meta{overflow:hidden;color:var(--ac-text-muted);font-size:11px;text-overflow:ellipsis;white-space:nowrap}.menu-end{display:flex;flex:none;align-items:center;margin-left:auto}.menu-chevron{color:var(--ac-accent);font-size:11px;opacity:0}.menu-row:hover:not(:disabled) .menu-chevron,.menu-row.is-active:not(:disabled) .menu-chevron{opacity:1}.menu-tag{padding:2px 7px;border-radius:4px;background:var(--ac-surface-alt);color:var(--ac-text-muted);font-size:9.5px;font-weight:var(--ns-weight-heading);letter-spacing:.04em;text-transform:uppercase;white-space:nowrap}.menu-tag.is-current{background:color-mix(in srgb,var(--ac-accent) 16%,transparent);color:var(--ac-accent)}.menu-foot{margin:0;padding:8px 14px;border-top:1px solid var(--ac-border);color:var(--ac-text-muted);font-size:10.5px}.menu-dot{width:8px;height:8px;border-radius:var(--ac-radius-pill);background:var(--ns-success)}.menu.is-grid .menu-search{padding:10px 10px 0;border-bottom:0}.menu.is-grid .menu-body{max-height:min(540px,calc(100dvh - 190px));gap:2px;padding:10px}.menu.is-grid .menu-section{padding:12px 6px 6px}.menu.is-grid .menu-group{display:grid;grid-template-columns:repeat(var(--menu-columns, 3),minmax(0,1fr));gap:4px}.menu.is-grid .menu-row{flex-direction:column;gap:7px;padding:11px 6px 9px;text-align:center}.menu.is-grid .menu-row.is-locked{opacity:1}.menu.is-grid .menu-tile{width:40px;height:40px;border-radius:11px;font-size:12px}.menu.is-grid .menu-tile i{font-size:16px}.menu.is-grid .menu-tile.is-outline{border:1px dashed color-mix(in srgb,var(--ac-text-muted) 55%,transparent);background:transparent;color:var(--ac-text-muted)}.menu.is-grid .menu-text{width:100%;align-items:center}.menu.is-grid .menu-name{display:-webkit-box;max-width:100%;font-size:12px;line-height:1.25;white-space:normal;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}.menu.is-grid .menu-row.is-locked .menu-name{color:var(--ac-text-muted);font-weight:var(--ns-weight-text)}.menu.is-grid .menu-row.is-current{grid-column:1 / -1;flex-direction:row;gap:12px;padding:10px 12px;background:var(--ac-text);color:var(--ac-surface);text-align:left}.menu.is-grid .menu-row.is-current .menu-tile{width:36px;height:36px;border-radius:10px}.menu.is-grid .menu-row.is-current .menu-text{width:auto;align-items:flex-start}.menu.is-grid .menu-row.is-current .menu-name{display:block;font-size:13px;white-space:nowrap}.menu.is-grid .menu-row.is-current .menu-meta{color:color-mix(in srgb,currentColor 64%,transparent)}\n"] }]
|
|
3704
|
+
}], ctorParameters: () => [], propDecorators: { sections: [{ type: i0.Input, args: [{ isSignal: true, alias: "sections", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], keyboardHint: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyboardHint", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], select: [{ type: i0.Output, args: ["select"] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }], searchBox: [{ type: i0.ViewChild, args: ['searchBox', { isSignal: true }] }], root: [{ type: i0.ViewChild, args: ['root', { isSignal: true }] }] } });
|
|
3293
3705
|
|
|
3294
3706
|
const STORAGE_KEY = 'nucleus_recent_apps';
|
|
3295
3707
|
const KEEP = 8;
|
|
@@ -3438,11 +3850,10 @@ const SHELL_COPY = {
|
|
|
3438
3850
|
appsSwitch: 'Cambiar de aplicación',
|
|
3439
3851
|
appsSearch: 'Buscar aplicación',
|
|
3440
3852
|
appsNoMatch: 'Ninguna aplicación coincide con lo que escribiste.',
|
|
3441
|
-
appsRecent: 'Recientes',
|
|
3442
|
-
appsAll: 'Todas',
|
|
3443
3853
|
appsAvailable: 'Disponibles',
|
|
3444
|
-
|
|
3445
|
-
|
|
3854
|
+
appsUpcoming: 'En preparación',
|
|
3855
|
+
appsHere: 'Estás aquí',
|
|
3856
|
+
keyboardHint: '← ↑ ↓ → moverse · ↵ abrir · esc cerrar',
|
|
3446
3857
|
accountSwitchHint: 'Entrar con otro correo',
|
|
3447
3858
|
signOutHint: 'Salir de la suite',
|
|
3448
3859
|
settingsTitle: 'Ajustes',
|
|
@@ -3475,11 +3886,10 @@ const SHELL_COPY = {
|
|
|
3475
3886
|
appsSwitch: 'Switch application',
|
|
3476
3887
|
appsSearch: 'Search applications',
|
|
3477
3888
|
appsNoMatch: 'No application matches what you typed.',
|
|
3478
|
-
appsRecent: 'Recent',
|
|
3479
|
-
appsAll: 'All',
|
|
3480
3889
|
appsAvailable: 'Available',
|
|
3481
|
-
|
|
3482
|
-
|
|
3890
|
+
appsUpcoming: 'Coming soon',
|
|
3891
|
+
appsHere: 'You are here',
|
|
3892
|
+
keyboardHint: '← ↑ ↓ → move · ↵ open · esc close',
|
|
3483
3893
|
accountSwitchHint: 'Sign in with another address',
|
|
3484
3894
|
signOutHint: 'Leave the suite',
|
|
3485
3895
|
settingsTitle: 'Settings',
|
|
@@ -3508,7 +3918,7 @@ const SHELL_COPY = {
|
|
|
3508
3918
|
};
|
|
3509
3919
|
|
|
3510
3920
|
const LAUNCHER_RICH_THRESHOLD = 6;
|
|
3511
|
-
const
|
|
3921
|
+
const SUITE_PREFIX = 'Nucleus ';
|
|
3512
3922
|
const FALLBACK_APP_COLOR = '#64748b';
|
|
3513
3923
|
const HOME_MENU_ID = 'nucleus-home';
|
|
3514
3924
|
class NucleusShell {
|
|
@@ -3600,41 +4010,30 @@ class NucleusShell {
|
|
|
3600
4010
|
words = computed(() => commonCopyOf(this.lang()), ...(ngDevMode ? [{ debugName: "words" }] : /* istanbul ignore next */ []));
|
|
3601
4011
|
hasSiteContext = computed(() => this.session.scope() === 'site', ...(ngDevMode ? [{ debugName: "hasSiteContext" }] : /* istanbul ignore next */ []));
|
|
3602
4012
|
launcherRich = computed(() => this.launcherApps().length > LAUNCHER_RICH_THRESHOLD, ...(ngDevMode ? [{ debugName: "launcherRich" }] : /* istanbul ignore next */ []));
|
|
3603
|
-
launcherCount = computed(() => {
|
|
3604
|
-
const total = this.launcherApps().length + (this.session.currentApp() ? 1 : 0);
|
|
3605
|
-
return total > LAUNCHER_RICH_THRESHOLD ? String(total) : null;
|
|
3606
|
-
}, ...(ngDevMode ? [{ debugName: "launcherCount" }] : /* istanbul ignore next */ []));
|
|
3607
4013
|
launcherSections = computed(() => {
|
|
3608
4014
|
const t = this.copy();
|
|
3609
4015
|
const apps = this.launcherApps();
|
|
3610
4016
|
const current = this.session.currentApp();
|
|
4017
|
+
const open = apps.filter((app) => this.canOpen(app));
|
|
4018
|
+
const pending = apps.filter((app) => !this.canOpen(app));
|
|
3611
4019
|
const sections = [];
|
|
3612
4020
|
if (current) {
|
|
3613
4021
|
sections.push({ id: 'current', label: null, rows: [this.appRow(current, true)] });
|
|
3614
4022
|
}
|
|
3615
|
-
if (
|
|
3616
|
-
return sections;
|
|
3617
|
-
if (this.launcherRich()) {
|
|
3618
|
-
const recent = this.recents.pick(apps, RECENT_LIMIT);
|
|
3619
|
-
if (recent.length) {
|
|
3620
|
-
sections.push({
|
|
3621
|
-
id: 'recent',
|
|
3622
|
-
label: t.appsRecent,
|
|
3623
|
-
rows: recent.map((app) => this.appRow(app, false)),
|
|
3624
|
-
});
|
|
3625
|
-
}
|
|
4023
|
+
if (open.length) {
|
|
3626
4024
|
sections.push({
|
|
3627
|
-
id: '
|
|
3628
|
-
label: t.
|
|
3629
|
-
rows:
|
|
4025
|
+
id: 'available',
|
|
4026
|
+
label: t.appsAvailable,
|
|
4027
|
+
rows: open.map((app) => this.appRow(app, false)),
|
|
4028
|
+
});
|
|
4029
|
+
}
|
|
4030
|
+
if (pending.length) {
|
|
4031
|
+
sections.push({
|
|
4032
|
+
id: 'upcoming',
|
|
4033
|
+
label: t.appsUpcoming,
|
|
4034
|
+
rows: pending.map((app) => this.appRow(app, false)),
|
|
3630
4035
|
});
|
|
3631
|
-
return sections;
|
|
3632
4036
|
}
|
|
3633
|
-
sections.push({
|
|
3634
|
-
id: 'all',
|
|
3635
|
-
label: current ? t.appsAvailable : null,
|
|
3636
|
-
rows: apps.map((app) => this.appRow(app, false)),
|
|
3637
|
-
});
|
|
3638
4037
|
return sections;
|
|
3639
4038
|
}, ...(ngDevMode ? [{ debugName: "launcherSections" }] : /* istanbul ignore next */ []));
|
|
3640
4039
|
accountSections = computed(() => {
|
|
@@ -3801,11 +4200,12 @@ class NucleusShell {
|
|
|
3801
4200
|
}
|
|
3802
4201
|
appRow(app, current) {
|
|
3803
4202
|
const hint = current ? this.copy().appsHere : this.launchHint(app);
|
|
4203
|
+
const name = shortAppName(app.name);
|
|
3804
4204
|
return {
|
|
3805
4205
|
id: app.id,
|
|
3806
|
-
name
|
|
4206
|
+
name,
|
|
3807
4207
|
meta: app.description,
|
|
3808
|
-
tile: menuTile(initialsOf(
|
|
4208
|
+
tile: menuTile(initialsOf(name), app.icon, app.color ?? FALLBACK_APP_COLOR),
|
|
3809
4209
|
tag: hint || null,
|
|
3810
4210
|
current,
|
|
3811
4211
|
disabled: !current && !this.canOpen(app),
|
|
@@ -3879,7 +4279,7 @@ class NucleusShell {
|
|
|
3879
4279
|
}
|
|
3880
4280
|
}
|
|
3881
4281
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusShell, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3882
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: NucleusShell, isStandalone: true, selector: "nucleus-shell", inputs: { brand: { classPropertyName: "brand", publicName: "brand", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, navItems: { classPropertyName: "navItems", publicName: "navItems", isSignal: true, isRequired: false, transformFunction: null }, activeNavId: { classPropertyName: "activeNavId", publicName: "activeNavId", isSignal: true, isRequired: false, transformFunction: null }, selectedMenuId: { classPropertyName: "selectedMenuId", publicName: "selectedMenuId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { navSelect: "navSelect", menuSelect: "menuSelect" }, host: { properties: { "style.--ns-topbar-h": "topbarHeight()" } }, ngImport: i0, template: "@let t = copy();\n@let me = identity();\n\n@if (starfield()) {\n <nucleus-starfield />\n}\n\n<header class=\"topbar ns-frame\">\n <div class=\"side\">\n <p-button\n icon=\"pi pi-bars\"\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"t.navToggle\"\n [pTooltip]=\"t.navToggle\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSidebar()\"\n />\n\n <div class=\"brand\">\n <nucleus-mark [size]=\"20\" />\n <div class=\"brand-name\">\n <span class=\"brand-primary\">NUCLEUS</span>\n <span class=\"brand-secondary\">{{ brand() }}</span>\n </div>\n </div>\n\n </div>\n\n @if (hasSiteContext()) {\n <div class=\"context ns-context\">\n <p-select\n styleClass=\"context-select\"\n [options]=\"companyChoices()\"\n optionValue=\"id\"\n optionLabel=\"name\"\n [ngModel]=\"companyChoice()\"\n (ngModelChange)=\"onCompanyChange($event)\"\n [placeholder]=\"t.companyPlaceholder\"\n [disabled]=\"switching()\"\n [filter]=\"companyChoices().length > 8\"\n filterBy=\"name\"\n [filterPlaceholder]=\"words().search\"\n [autofocusFilter]=\"true\"\n [resetFilterOnHide]=\"true\"\n [ariaLabel]=\"t.companyLabel\"\n [ngModelOptions]=\"{ standalone: true }\"\n >\n <ng-template #item let-option>\n <span class=\"company-option\">\n <span class=\"company-name\">{{ option.name }}</span>\n <p-tag [value]=\"option.tag\" severity=\"secondary\" />\n </span>\n </ng-template>\n </p-select>\n\n <p-select\n styleClass=\"context-select\"\n [options]=\"siteOptions()\"\n optionValue=\"id\"\n optionLabel=\"name\"\n [ngModel]=\"siteChoice()\"\n (ngModelChange)=\"onSiteChange($event)\"\n [placeholder]=\"sitePlaceholder()\"\n [disabled]=\"switching() || sitesLoading() || !siteOptions().length\"\n [filter]=\"siteOptions().length > 8\"\n filterBy=\"name\"\n [filterPlaceholder]=\"words().search\"\n [autofocusFilter]=\"true\"\n [resetFilterOnHide]=\"true\"\n [ariaLabel]=\"t.siteLabel\"\n [ngModelOptions]=\"{ standalone: true }\"\n />\n </div>\n }\n\n <div class=\"side is-end\">\n <div class=\"lang-switch\" role=\"group\" aria-label=\"Idioma / Language\">\n <button\n type=\"button\"\n class=\"lang-pill\"\n [class.is-active]=\"lang() === 'es'\"\n [attr.aria-pressed]=\"lang() === 'es'\"\n (click)=\"setLang('es')\"\n >\n ES\n </button>\n <button\n type=\"button\"\n class=\"lang-pill\"\n [class.is-active]=\"lang() === 'en'\"\n [attr.aria-pressed]=\"lang() === 'en'\"\n (click)=\"setLang('en')\"\n >\n EN\n </button>\n </div>\n\n <p-button\n icon=\"pi pi-th-large\"\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"t.appsLauncher\"\n [pTooltip]=\"t.appsLauncher\"\n tooltipPosition=\"bottom\"\n (onClick)=\"launcher.toggle($event)\"\n />\n\n <p-popover #launcher styleClass=\"ns-flush-popover\">\n @if (!hasCompany()) {\n <div class=\"launcher-notice\">\n <i class=\"pi pi-building\" aria-hidden=\"true\"></i>\n <div>\n <p class=\"launcher-notice-title\">{{ t.noCompanyTitle }}</p>\n <p class=\"launcher-notice-body\">{{ t.noCompanyHint }}</p>\n </div>\n </div>\n }\n\n <nucleus-menu\n [heading]=\"t.appsSwitch\"\n [badge]=\"launcherCount()\"\n [sections]=\"launcherSections()\"\n [searchable]=\"launcherRich()\"\n [searchPlaceholder]=\"t.appsSearch\"\n [emptyText]=\"launcherRich() ? t.appsNoMatch : t.appsEmpty\"\n [keyboardHint]=\"t.keyboardHint\"\n [width]=\"336\"\n (select)=\"onLauncherSelect($event); launcher.hide()\"\n (dismiss)=\"launcher.hide()\"\n />\n </p-popover>\n\n <p-button\n icon=\"pi pi-cog\"\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"t.settingsTitle\"\n [pTooltip]=\"t.settingsTitle\"\n tooltipPosition=\"bottom\"\n (onClick)=\"settingsOpen.set(true)\"\n />\n\n @if (me) {\n <p-button\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n styleClass=\"avatar-trigger\"\n [ariaLabel]=\"me.name\"\n [pTooltip]=\"me.name\"\n tooltipPosition=\"bottom\"\n (onClick)=\"account.toggle($event)\"\n >\n <p-avatar\n [image]=\"me.photoUrl ?? undefined\"\n [label]=\"me.photoUrl ? undefined : initials()\"\n shape=\"circle\"\n size=\"normal\"\n />\n </p-button>\n }\n </div>\n</header>\n\n<p-popover #account styleClass=\"ns-flush-popover\">\n @if (me) {\n <div class=\"who\">\n @if (me.photoUrl) {\n <img class=\"who-photo\" [src]=\"me.photoUrl\" alt=\"\" width=\"42\" height=\"42\" />\n } @else {\n <span class=\"who-photo who-initials\">{{ initials() }}</span>\n }\n <span class=\"who-text\">\n <span class=\"who-name\">{{ me.name }}</span>\n <span class=\"who-mail\">{{ me.email }}</span>\n </span>\n </div>\n\n <p class=\"who-role\">\n <span class=\"who-dot\" aria-hidden=\"true\"></span>\n @if (roleName(); as role) {\n <b>{{ role }}</b>\n <span class=\"who-sep\">\u00B7</span>\n }\n <span class=\"who-context\">{{ accountContext() }}</span>\n </p>\n\n <nucleus-menu\n [sections]=\"accountSections()\"\n [width]=\"304\"\n (select)=\"onAccountSelect($event); account.hide()\"\n (dismiss)=\"account.hide()\"\n />\n }\n</p-popover>\n\n<div class=\"body\">\n @if (narrow() && sidebarOpen()) {\n <button\n type=\"button\"\n class=\"sidebar-scrim\"\n [attr.aria-label]=\"t.navToggle\"\n (click)=\"toggleSidebar()\"\n ></button>\n }\n\n <aside class=\"sidebar ns-frame\" [class.is-collapsed]=\"!sidebarOpen()\">\n @if (roleName(); as role) {\n <div class=\"role-badge\" [pTooltip]=\"sidebarOpen() ? '' : role\" tooltipPosition=\"right\">\n <i class=\"pi pi-key\" aria-hidden=\"true\"></i>\n <span class=\"nav-label role-text\">\n <span class=\"role-name\">{{ role }}</span>\n <span class=\"role-caption\">{{ t.roleCaption }}</span>\n </span>\n </div>\n }\n\n @if (navItems().length) {\n <nav>\n @for (item of navItems(); track item.id) {\n <button\n type=\"button\"\n class=\"nav-item\"\n [class.is-active]=\"activeNavId() === item.id\"\n [attr.aria-current]=\"activeNavId() === item.id ? 'page' : null\"\n [pTooltip]=\"sidebarOpen() ? '' : item.label\"\n tooltipPosition=\"right\"\n (click)=\"selectNav(item.id)\"\n >\n <i [class]=\"item.icon\" aria-hidden=\"true\"></i>\n <span class=\"nav-label\">{{ item.label }}</span>\n </button>\n }\n </nav>\n }\n\n <nav class=\"access-menu\">\n @if (menuLoading()) {\n <div class=\"nav-skeleton\" role=\"status\" [attr.aria-label]=\"t.accessLoading\">\n @for (width of menuPlaceholders; track $index) {\n <div class=\"nav-skeleton-item\">\n <p-skeleton shape=\"circle\" size=\"15px\" />\n <p-skeleton height=\"9px\" [width]=\"width\" />\n </div>\n }\n </div>\n } @else if (menuError()) {\n <p class=\"access-state is-error\">{{ menuError() }}</p>\n } @else if (!menu().length) {\n <p class=\"access-state\">{{ t.accessEmpty }}</p>\n } @else {\n @for (node of menu(); track node.id) {\n @let group = isGroup(node);\n @let open = isExpanded(node);\n\n <button\n type=\"button\"\n class=\"nav-item\"\n [class.is-active]=\"!group && isSelected(node)\"\n [class.is-inert]=\"!group && !node.route\"\n [attr.aria-expanded]=\"group ? open : null\"\n [disabled]=\"!group && !node.route\"\n [pTooltip]=\"sidebarOpen() ? '' : node.label\"\n tooltipPosition=\"right\"\n (click)=\"selectMenu(node)\"\n >\n <i [class]=\"node.icon ?? 'pi pi-circle'\" aria-hidden=\"true\"></i>\n <span class=\"nav-label\">{{ node.label }}</span>\n @if (group && sidebarOpen()) {\n <i\n class=\"pi nav-caret\"\n [class.pi-chevron-down]=\"open\"\n [class.pi-chevron-right]=\"!open\"\n aria-hidden=\"true\"\n ></i>\n }\n </button>\n\n @if (open) {\n @for (child of node.children; track child.id) {\n <button\n type=\"button\"\n class=\"nav-item is-child\"\n [class.is-active]=\"isSelected(child)\"\n [pTooltip]=\"sidebarOpen() ? '' : child.label\"\n tooltipPosition=\"right\"\n (click)=\"selectMenu(child)\"\n >\n <i [class]=\"child.icon ?? 'pi pi-circle'\" aria-hidden=\"true\"></i>\n <span class=\"nav-label\">{{ child.label }}</span>\n </button>\n }\n }\n }\n }\n </nav>\n </aside>\n\n <main class=\"content\">\n <div class=\"measure\">\n <ng-content select=\"[nucleusTop]\" />\n\n @if (crumbs().length || title() || pageActions()) {\n <header class=\"page-head\">\n <div class=\"page-head-main\">\n @if (crumbs().length) {\n <p-breadcrumb [model]=\"crumbs()\" [home]=\"home()\" styleClass=\"ns-crumbs\" />\n }\n\n @if (title()) {\n <h1>{{ title() }}</h1>\n }\n </div>\n\n @if (pageActions(); as actions) {\n <div class=\"page-head-actions\">\n <ng-container [ngTemplateOutlet]=\"actions\" />\n </div>\n }\n </header>\n }\n\n <ng-content />\n </div>\n </main>\n</div>\n\n<p-drawer\n [visible]=\"settingsOpen()\"\n (visibleChange)=\"settingsOpen.set($event)\"\n position=\"right\"\n [header]=\"t.settingsTitle\"\n [modal]=\"false\"\n [blockScroll]=\"false\"\n styleClass=\"ns-settings-drawer\"\n [style]=\"{ width: '380px' }\"\n>\n <nucleus-appearance />\n</p-drawer>\n\n<p-toast position=\"bottom-right\" styleClass=\"ns-toast\">\n <ng-template #message let-message>\n <nucleus-lordicon\n [src]=\"message.severity === 'success' ? icons.check : icons.warning\"\n [tone]=\"message.severity === 'success' ? 'accent' : 'danger'\"\n [size]=\"34\"\n trigger=\"in\"\n />\n <div class=\"toast-text\">\n <p class=\"toast-summary\">{{ message.summary }}</p>\n @if (message.detail) {\n <p class=\"toast-detail\">{{ message.detail }}</p>\n }\n </div>\n </ng-template>\n</p-toast>\n\n<p-confirmdialog [style]=\"{ width: '420px' }\">\n <ng-template #headless let-message let-onAccept=\"onAccept\" let-onReject=\"onReject\">\n <div class=\"confirm\">\n <nucleus-lordicon\n [src]=\"message.icon\"\n [tone]=\"message.acceptButtonStyleClass ? 'danger' : 'accent'\"\n [size]=\"64\"\n trigger=\"loop\"\n />\n <h2>{{ message.header }}</h2>\n <p>{{ message.message }}</p>\n <div class=\"confirm-actions\">\n <p-button\n [label]=\"message.rejectLabel\"\n severity=\"secondary\"\n [text]=\"true\"\n (onClick)=\"onReject()\"\n />\n <p-button\n [label]=\"message.acceptLabel\"\n [severity]=\"message.acceptButtonStyleClass ? 'danger' : 'primary'\"\n (onClick)=\"onAccept()\"\n />\n </div>\n </div>\n </ng-template>\n</p-confirmdialog>\n", styles: [":host{display:flex;flex-direction:column;min-height:100dvh;background:var(--ac-bg);color:var(--ac-text)}.topbar{position:sticky;top:0;z-index:20;display:flex;align-items:center;justify-content:flex-start;gap:16px;height:56px;padding:0 12px 0 8px;border-bottom:1px solid var(--ns-frame-line)}.side{display:flex;min-width:0;align-items:center;gap:4px}.side.is-end{margin-left:auto}.brand{display:flex;align-items:center;gap:9px;margin-left:4px}.brand-name{display:flex;align-items:baseline;gap:7px}.brand-primary{font-size:13px;font-weight:700;letter-spacing:.15em}.brand-secondary{font-size:9px;font-weight:500;letter-spacing:.22em;color:var(--ns-frame-muted)}.lang-switch{display:flex;align-items:center;gap:2px;margin-right:6px;border:1px solid var(--ns-frame-line);border-radius:999px;padding:2px}.lang-pill{font-size:10px;font-weight:600;letter-spacing:.08em;padding:4px 10px;border:none;border-radius:999px;background:transparent;color:var(--ns-frame-muted);cursor:pointer}.lang-pill:hover{color:var(--ns-frame-ink)}.lang-pill.is-active{background:var(--ns-frame-glow);color:var(--ns-frame-on-glow)}.body{display:flex;flex:1;min-height:0}.sidebar{flex:none;width:max-content;min-width:224px;max-width:340px;padding:12px 10px;border-right:1px solid var(--ns-frame-line);transition:width .18s ease}.sidebar.is-collapsed{width:60px;min-width:0}.sidebar nav{display:flex;flex-direction:column;gap:3px}.nav-item{display:flex;align-items:center;gap:12px;width:100%;padding:var(--ns-nav-y, 9px) 12px;border:none;border-radius:6px;background:transparent;color:var(--ns-frame-muted);font-size:13px;font-weight:500;text-align:left;white-space:nowrap;cursor:pointer}.nav-item i{flex:none;font-size:15px}.nav-item:hover{background:var(--ns-frame-raised);color:var(--ns-frame-ink)}.nav-item.is-active{background:var(--ns-frame-raised);box-shadow:inset 2px 0 0 var(--ns-frame-glow);color:var(--ns-frame-ink)}.nav-item.is-active i{color:var(--ns-frame-glow)}.nav-caret{margin-left:auto;font-size:11px!important;opacity:.7}.nav-item.is-inert{opacity:.45;cursor:default}.nav-item.is-inert:hover{background:transparent;color:var(--ns-frame-muted)}.nav-label{overflow:hidden;text-overflow:ellipsis}.sidebar.is-collapsed .nav-label{display:none}.sidebar.is-collapsed .nav-item{justify-content:center;padding-inline:0}.content{flex:1;min-width:0;padding:28px 28px 64px;display:flex;flex-direction:column;gap:14px}.page-head{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:46px;padding:7px 16px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}.page-head-main{display:flex;min-width:0;flex:1;align-items:center;gap:14px}.page-head-actions{display:flex;flex:none;align-items:center;gap:8px}.page-head h1{margin:0;font-size:19px;font-weight:600}.measure{display:flex;width:100%;max-width:var(--ac-content-max, 1440px);flex-direction:column;gap:14px;margin-inline:0}h1{margin:0;font-size:26px;line-height:1.2;font-weight:500;letter-spacing:-.02em}.access-menu{display:flex;flex-direction:column;gap:.15rem;margin-top:.75rem;padding-top:.75rem;border-top:1px solid var(--ns-frame-line)}.access-caption{margin:0 0 .4rem;padding:0 .75rem;color:var(--ns-frame-muted);font-size:.68rem;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.access-state{margin:0;padding:.35rem .75rem;color:var(--ns-frame-muted);font-size:.78rem}.access-state.is-error{color:var(--p-red-400, #f87171)}.nav-item.is-child{padding-left:2.1rem;font-size:.86rem}@media(max-width:720px){.sidebar{max-width:none;position:fixed;top:var(--ns-topbar-h, 56px);bottom:0;left:0;z-index:30;width:268px;max-width:82vw;overflow-y:auto;box-shadow:0 18px 44px #00000073;transform:translate(-100%);transition:transform .18s ease}.sidebar.is-collapsed{width:268px;max-width:82vw;transform:translate(-100%)}.sidebar:not(.is-collapsed){transform:translate(0)}.sidebar.is-collapsed .nav-label{display:inline}.sidebar.is-collapsed .role-text{display:flex}.sidebar.is-collapsed .nav-item,.sidebar.is-collapsed .role-badge{justify-content:flex-start;padding-inline:12px}.brand-secondary{display:none}.topbar{height:auto;min-height:56px;flex-wrap:wrap;padding-bottom:8px;row-gap:8px}.context{order:3;width:100%;margin-left:0}.context-select{min-width:0;max-width:none;flex:1 1 0}.content{padding:20px 16px 48px}h1{font-size:22px}.page-head{align-items:stretch;flex-direction:column;gap:10px;padding:10px 14px}.page-head-actions{justify-content:flex-end}}.who{display:flex;align-items:center;gap:12px;padding:15px 15px 13px;border-bottom:1px solid var(--ac-border);background:var(--ns-header-bg)}.who-photo{width:42px;height:42px;flex:none;border-radius:999px;object-fit:cover}.who-initials{display:inline-flex;align-items:center;justify-content:center;background:var(--ac-accent);color:var(--ac-on-accent);font-size:15px;font-weight:600}.who-text{display:flex;min-width:0;flex-direction:column}.who-name{overflow:hidden;font-size:14px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.who-mail{overflow:hidden;color:var(--ac-text-muted);font-size:11.5px;text-overflow:ellipsis;white-space:nowrap}.who-role{display:flex;align-items:center;gap:7px;margin:0;overflow:hidden;padding:9px 15px;border-bottom:1px solid var(--ac-border);color:var(--ac-text-muted);font-size:11.5px;white-space:nowrap}.who-role b{flex:none;color:var(--ac-text);font-size:12px;font-weight:600}.who-sep{flex:none}.who-context{overflow:hidden;text-overflow:ellipsis}.who-dot{width:5px;height:5px;flex:none;border-radius:50%;background:var(--ac-accent)}.company-option{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%}.company-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.launcher-notice{display:flex;gap:10px;margin:12px 12px 0;padding:12px;border:1px solid color-mix(in srgb,var(--ac-accent) 40%,transparent);border-radius:8px;background:color-mix(in srgb,var(--ac-accent) 10%,transparent)}.launcher-notice i{margin-top:2px;color:var(--ac-accent);font-size:15px}.launcher-notice-title{margin:0 0 4px;font-size:13px;font-weight:600}.launcher-notice-body{margin:0;color:var(--ac-text-muted);font-size:12px;line-height:1.45}.confirm{display:flex;flex-direction:column;align-items:center;gap:6px;padding:26px 24px 20px;border:1px solid var(--ac-border);border-radius:14px;background:var(--ac-surface);text-align:center}.confirm h2{margin:8px 0 0;font-size:17px;font-weight:600}.confirm p{margin:0;max-width:34ch;color:var(--ac-text-muted);font-size:13px;line-height:1.5}.confirm-actions{display:flex;justify-content:center;gap:8px;margin-top:18px}.toast-text{flex:1;margin-left:12px}.toast-summary{margin:0;font-size:13px;font-weight:600}.toast-detail{margin:2px 0 0;color:var(--ac-text-muted);font-size:12px}.context{display:flex;min-width:0;align-items:center;gap:8px;margin-left:14px}.context-select{min-width:150px;max-width:210px}.role-badge{display:flex;align-items:center;gap:12px;margin-bottom:10px;padding:9px 12px;border-left:2px solid var(--ns-frame-glow);border-radius:0 7px 7px 0;background:var(--ns-frame-raised);box-shadow:-2px 0 12px -3px color-mix(in srgb,var(--ns-frame-glow) 65%,transparent)}.role-badge>i{flex:none;color:var(--ns-frame-glow);font-size:14px}.role-text{display:flex;min-width:0;flex-direction:column;gap:1px}.role-name{overflow:hidden;color:var(--ns-frame-ink);font-size:13px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.role-caption{color:var(--ns-frame-muted);font-size:10px;letter-spacing:.06em;text-transform:uppercase}.sidebar.is-collapsed .role-badge{justify-content:center;padding-inline:0}.sidebar-scrim{position:fixed;top:var(--ns-topbar-h, 56px);right:0;bottom:0;left:0;z-index:29;padding:0;border:0;background:#00000073;cursor:pointer}.nav-skeleton{display:flex;flex-direction:column;gap:3px}.nav-skeleton-item{display:flex;align-items:center;gap:12px;padding:11px 12px}.sidebar.is-collapsed .nav-skeleton-item .p-skeleton:last-child{display:none}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i1$3.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: BreadcrumbModule }, { kind: "component", type: i2$3.Breadcrumb, selector: "p-breadcrumb", inputs: ["model", "style", "styleClass", "home", "homeAriaLabel"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ConfirmDialogModule }, { kind: "component", type: i4$1.ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "modal", "visible", "position", "draggable"], outputs: ["onHide"] }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i5$2.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "motionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i6$1.Drawer, selector: "p-drawer", inputs: ["appendTo", "motionOptions", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i3.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i4.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: NucleusAppearance, selector: "nucleus-appearance" }, { kind: "component", type: NucleusLordicon, selector: "nucleus-lordicon", inputs: ["src", "trigger", "state", "size", "tone"] }, { kind: "component", type: NucleusMenu, selector: "nucleus-menu", inputs: ["sections", "heading", "badge", "searchable", "searchPlaceholder", "emptyText", "keyboardHint", "width"], outputs: ["select", "dismiss"] }, { kind: "component", type: NucleusMark, selector: "nucleus-mark", inputs: ["accent", "size"] }, { kind: "component", type: NucleusStarfield, selector: "nucleus-starfield" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4282
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: NucleusShell, isStandalone: true, selector: "nucleus-shell", inputs: { brand: { classPropertyName: "brand", publicName: "brand", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, navItems: { classPropertyName: "navItems", publicName: "navItems", isSignal: true, isRequired: false, transformFunction: null }, activeNavId: { classPropertyName: "activeNavId", publicName: "activeNavId", isSignal: true, isRequired: false, transformFunction: null }, selectedMenuId: { classPropertyName: "selectedMenuId", publicName: "selectedMenuId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { navSelect: "navSelect", menuSelect: "menuSelect" }, host: { properties: { "style.--ns-topbar-h": "topbarHeight()" } }, ngImport: i0, template: "@let t = copy();\n@let me = identity();\n\n@if (starfield()) {\n <nucleus-starfield />\n}\n\n<header class=\"topbar ns-frame\">\n <div class=\"side\">\n <p-button\n icon=\"pi pi-bars\"\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"t.navToggle\"\n [pTooltip]=\"t.navToggle\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSidebar()\"\n />\n\n <div class=\"brand\">\n <nucleus-mark [size]=\"20\" />\n <div class=\"brand-name\">\n <span class=\"brand-primary\">NUCLEUS</span>\n <span class=\"brand-secondary\">{{ brand() }}</span>\n </div>\n </div>\n\n </div>\n\n @if (hasSiteContext()) {\n <div class=\"context ns-context\">\n <p-select\n styleClass=\"context-select\"\n [options]=\"companyChoices()\"\n optionValue=\"id\"\n optionLabel=\"name\"\n [ngModel]=\"companyChoice()\"\n (ngModelChange)=\"onCompanyChange($event)\"\n [placeholder]=\"t.companyPlaceholder\"\n [disabled]=\"switching()\"\n [filter]=\"companyChoices().length > 8\"\n filterBy=\"name\"\n [filterPlaceholder]=\"words().search\"\n [autofocusFilter]=\"true\"\n [resetFilterOnHide]=\"true\"\n [ariaLabel]=\"t.companyLabel\"\n [ngModelOptions]=\"{ standalone: true }\"\n >\n <ng-template #item let-option>\n <span class=\"company-option\">\n <span class=\"company-name\">{{ option.name }}</span>\n <p-tag [value]=\"option.tag\" severity=\"secondary\" />\n </span>\n </ng-template>\n </p-select>\n\n <p-select\n styleClass=\"context-select\"\n [options]=\"siteOptions()\"\n optionValue=\"id\"\n optionLabel=\"name\"\n [ngModel]=\"siteChoice()\"\n (ngModelChange)=\"onSiteChange($event)\"\n [placeholder]=\"sitePlaceholder()\"\n [disabled]=\"switching() || sitesLoading() || !siteOptions().length\"\n [filter]=\"siteOptions().length > 8\"\n filterBy=\"name\"\n [filterPlaceholder]=\"words().search\"\n [autofocusFilter]=\"true\"\n [resetFilterOnHide]=\"true\"\n [ariaLabel]=\"t.siteLabel\"\n [ngModelOptions]=\"{ standalone: true }\"\n />\n </div>\n }\n\n <div class=\"side is-end\">\n <div class=\"lang-switch\" role=\"group\" aria-label=\"Idioma / Language\">\n <button\n type=\"button\"\n class=\"lang-pill\"\n [class.is-active]=\"lang() === 'es'\"\n [attr.aria-pressed]=\"lang() === 'es'\"\n (click)=\"setLang('es')\"\n >\n ES\n </button>\n <button\n type=\"button\"\n class=\"lang-pill\"\n [class.is-active]=\"lang() === 'en'\"\n [attr.aria-pressed]=\"lang() === 'en'\"\n (click)=\"setLang('en')\"\n >\n EN\n </button>\n </div>\n\n <p-button\n icon=\"pi pi-th-large\"\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"t.appsLauncher\"\n [pTooltip]=\"t.appsLauncher\"\n tooltipPosition=\"bottom\"\n (onClick)=\"launcher.toggle($event)\"\n />\n\n <p-popover #launcher styleClass=\"ns-flush-popover\">\n @if (!hasCompany()) {\n <div class=\"launcher-notice\">\n <i class=\"pi pi-building\" aria-hidden=\"true\"></i>\n <div>\n <p class=\"launcher-notice-title\">{{ t.noCompanyTitle }}</p>\n <p class=\"launcher-notice-body\">{{ t.noCompanyHint }}</p>\n </div>\n </div>\n }\n\n <nucleus-menu\n layout=\"grid\"\n [heading]=\"t.appsSwitch\"\n [sections]=\"launcherSections()\"\n [searchable]=\"launcherRich()\"\n [searchPlaceholder]=\"t.appsSearch\"\n [emptyText]=\"launcherRich() ? t.appsNoMatch : t.appsEmpty\"\n [keyboardHint]=\"t.keyboardHint\"\n [width]=\"384\"\n (select)=\"onLauncherSelect($event); launcher.hide()\"\n (dismiss)=\"launcher.hide()\"\n />\n </p-popover>\n\n <p-button\n icon=\"pi pi-cog\"\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"t.settingsTitle\"\n [pTooltip]=\"t.settingsTitle\"\n tooltipPosition=\"bottom\"\n (onClick)=\"settingsOpen.set(true)\"\n />\n\n @if (me) {\n <p-button\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n styleClass=\"avatar-trigger\"\n [ariaLabel]=\"me.name\"\n [pTooltip]=\"me.name\"\n tooltipPosition=\"bottom\"\n (onClick)=\"account.toggle($event)\"\n >\n <p-avatar\n [image]=\"me.photoUrl ?? undefined\"\n [label]=\"me.photoUrl ? undefined : initials()\"\n shape=\"circle\"\n size=\"normal\"\n />\n </p-button>\n }\n </div>\n</header>\n\n<p-popover #account styleClass=\"ns-flush-popover\">\n @if (me) {\n <div class=\"who\">\n @if (me.photoUrl) {\n <img class=\"who-photo\" [src]=\"me.photoUrl\" alt=\"\" width=\"42\" height=\"42\" />\n } @else {\n <span class=\"who-photo who-initials\">{{ initials() }}</span>\n }\n <span class=\"who-text\">\n <span class=\"who-name\">{{ me.name }}</span>\n <span class=\"who-mail\">{{ me.email }}</span>\n </span>\n </div>\n\n <p class=\"who-role\">\n <span class=\"who-dot\" aria-hidden=\"true\"></span>\n @if (roleName(); as role) {\n <b>{{ role }}</b>\n <span class=\"who-sep\">\u00B7</span>\n }\n <span class=\"who-context\">{{ accountContext() }}</span>\n </p>\n\n <nucleus-menu\n [sections]=\"accountSections()\"\n [width]=\"304\"\n (select)=\"onAccountSelect($event); account.hide()\"\n (dismiss)=\"account.hide()\"\n />\n }\n</p-popover>\n\n<div class=\"body\">\n @if (narrow() && sidebarOpen()) {\n <button\n type=\"button\"\n class=\"sidebar-scrim\"\n [attr.aria-label]=\"t.navToggle\"\n (click)=\"toggleSidebar()\"\n ></button>\n }\n\n <aside class=\"sidebar ns-frame\" [class.is-collapsed]=\"!sidebarOpen()\">\n @if (roleName(); as role) {\n <div class=\"role-badge\" [pTooltip]=\"sidebarOpen() ? '' : role\" tooltipPosition=\"right\">\n <i class=\"pi pi-key\" aria-hidden=\"true\"></i>\n <span class=\"nav-label role-text\">\n <span class=\"role-name\">{{ role }}</span>\n <span class=\"role-caption\">{{ t.roleCaption }}</span>\n </span>\n </div>\n }\n\n @if (navItems().length) {\n <nav>\n @for (item of navItems(); track item.id) {\n <button\n type=\"button\"\n class=\"nav-item\"\n [class.is-active]=\"activeNavId() === item.id\"\n [attr.aria-current]=\"activeNavId() === item.id ? 'page' : null\"\n [pTooltip]=\"sidebarOpen() ? '' : item.label\"\n tooltipPosition=\"right\"\n (click)=\"selectNav(item.id)\"\n >\n <i [class]=\"item.icon\" aria-hidden=\"true\"></i>\n <span class=\"nav-label\">{{ item.label }}</span>\n </button>\n }\n </nav>\n }\n\n <nav class=\"access-menu\">\n @if (menuLoading()) {\n <div class=\"nav-skeleton\" role=\"status\" [attr.aria-label]=\"t.accessLoading\">\n @for (width of menuPlaceholders; track $index) {\n <div class=\"nav-skeleton-item\">\n <p-skeleton shape=\"circle\" size=\"15px\" />\n <p-skeleton height=\"9px\" [width]=\"width\" />\n </div>\n }\n </div>\n } @else if (menuError()) {\n <p class=\"access-state is-error\">{{ menuError() }}</p>\n } @else if (!menu().length) {\n <p class=\"access-state\">{{ t.accessEmpty }}</p>\n } @else {\n @for (node of menu(); track node.id) {\n @let group = isGroup(node);\n @let open = isExpanded(node);\n\n <button\n type=\"button\"\n class=\"nav-item\"\n [class.is-active]=\"!group && isSelected(node)\"\n [class.is-inert]=\"!group && !node.route\"\n [attr.aria-expanded]=\"group ? open : null\"\n [disabled]=\"!group && !node.route\"\n [pTooltip]=\"sidebarOpen() ? '' : node.label\"\n tooltipPosition=\"right\"\n (click)=\"selectMenu(node)\"\n >\n <i [class]=\"node.icon ?? 'pi pi-circle'\" aria-hidden=\"true\"></i>\n <span class=\"nav-label\">{{ node.label }}</span>\n @if (group && sidebarOpen()) {\n <i\n class=\"pi nav-caret\"\n [class.pi-chevron-down]=\"open\"\n [class.pi-chevron-right]=\"!open\"\n aria-hidden=\"true\"\n ></i>\n }\n </button>\n\n @if (open) {\n @for (child of node.children; track child.id) {\n <button\n type=\"button\"\n class=\"nav-item is-child\"\n [class.is-active]=\"isSelected(child)\"\n [pTooltip]=\"sidebarOpen() ? '' : child.label\"\n tooltipPosition=\"right\"\n (click)=\"selectMenu(child)\"\n >\n <i [class]=\"child.icon ?? 'pi pi-circle'\" aria-hidden=\"true\"></i>\n <span class=\"nav-label\">{{ child.label }}</span>\n </button>\n }\n }\n }\n }\n </nav>\n </aside>\n\n <main class=\"content\">\n <div class=\"measure\">\n <ng-content select=\"[nucleusTop]\" />\n\n @if (crumbs().length || title() || pageActions()) {\n <header class=\"page-head\">\n <div class=\"page-head-main\">\n @if (crumbs().length) {\n <p-breadcrumb [model]=\"crumbs()\" [home]=\"home()\" styleClass=\"ns-crumbs\" />\n }\n\n @if (title()) {\n <h1>{{ title() }}</h1>\n }\n </div>\n\n @if (pageActions(); as actions) {\n <div class=\"page-head-actions\">\n <ng-container [ngTemplateOutlet]=\"actions\" />\n </div>\n }\n </header>\n }\n\n <ng-content />\n </div>\n </main>\n</div>\n\n<p-drawer\n [visible]=\"settingsOpen()\"\n (visibleChange)=\"settingsOpen.set($event)\"\n position=\"right\"\n [header]=\"t.settingsTitle\"\n [modal]=\"false\"\n [blockScroll]=\"false\"\n styleClass=\"ns-settings-drawer\"\n [style]=\"{ width: '380px' }\"\n>\n <nucleus-appearance />\n</p-drawer>\n\n<p-toast position=\"bottom-right\" styleClass=\"ns-toast\">\n <ng-template #message let-message>\n <nucleus-lordicon\n [src]=\"message.severity === 'success' ? icons.check : icons.warning\"\n [tone]=\"message.severity === 'success' ? 'accent' : 'danger'\"\n [size]=\"34\"\n trigger=\"in\"\n />\n <div class=\"toast-text\">\n <p class=\"toast-summary\">{{ message.summary }}</p>\n @if (message.detail) {\n <p class=\"toast-detail\">{{ message.detail }}</p>\n }\n </div>\n </ng-template>\n</p-toast>\n\n<p-confirmdialog [style]=\"{ width: '420px' }\">\n <ng-template #headless let-message let-onAccept=\"onAccept\" let-onReject=\"onReject\">\n <div class=\"confirm\">\n <nucleus-lordicon\n [src]=\"message.icon\"\n [tone]=\"message.acceptButtonStyleClass ? 'danger' : 'accent'\"\n [size]=\"64\"\n trigger=\"loop\"\n />\n <h2>{{ message.header }}</h2>\n <p>{{ message.message }}</p>\n <div class=\"confirm-actions\">\n <p-button\n [label]=\"message.rejectLabel\"\n severity=\"secondary\"\n [text]=\"true\"\n (onClick)=\"onReject()\"\n />\n <p-button\n [label]=\"message.acceptLabel\"\n [severity]=\"message.acceptButtonStyleClass ? 'danger' : 'primary'\"\n (onClick)=\"onAccept()\"\n />\n </div>\n </div>\n </ng-template>\n</p-confirmdialog>\n", styles: [":host{display:flex;flex-direction:column;min-height:100dvh;background:var(--ac-bg);color:var(--ac-text)}.topbar{position:sticky;top:0;z-index:20;display:flex;align-items:center;justify-content:flex-start;gap:16px;height:56px;padding:0 12px 0 8px;border-bottom:1px solid var(--ns-frame-line)}.side{display:flex;min-width:0;align-items:center;gap:4px}.side.is-end{margin-left:auto}.brand{display:flex;align-items:center;gap:9px;margin-left:4px}.brand-name{display:flex;align-items:baseline;gap:7px}.brand-primary{font-size:13px;font-weight:700;letter-spacing:.15em}.brand-secondary{font-size:9px;font-weight:var(--ns-weight-emphasis);letter-spacing:.22em;color:var(--ns-frame-muted)}.lang-switch{display:flex;align-items:center;gap:2px;margin-right:6px;border:1px solid var(--ns-frame-line);border-radius:999px;padding:2px}.lang-pill{font-size:10px;font-weight:var(--ns-weight-emphasis);letter-spacing:.08em;padding:4px 10px;border:none;border-radius:999px;background:transparent;color:var(--ns-frame-muted);cursor:pointer}.lang-pill:hover{color:var(--ns-frame-ink)}.lang-pill.is-active{background:var(--ns-frame-glow);color:var(--ns-frame-on-glow)}.body{display:flex;flex:1;min-height:0}.sidebar{flex:none;width:max-content;min-width:224px;max-width:340px;padding:12px 10px;border-right:1px solid var(--ns-frame-line);transition:width .18s ease}.sidebar.is-collapsed{width:60px;min-width:0}.sidebar nav{display:flex;flex-direction:column;gap:3px}.nav-item{display:flex;align-items:center;gap:12px;width:100%;padding:var(--ns-nav-y, 9px) 12px;border:none;border-radius:6px;background:transparent;color:var(--ns-frame-muted);font-size:13px;font-weight:var(--ns-weight-text);text-align:left;white-space:nowrap;cursor:pointer}.nav-item i{flex:none;font-size:15px}.nav-item:hover{background:var(--ns-frame-raised);color:var(--ns-frame-ink)}.nav-item.is-active{background:var(--ns-nav-active-bg, var(--ns-frame-raised));color:var(--ns-nav-active-ink, var(--ns-frame-ink));font-weight:var(--ns-weight-emphasis)}.nav-item.is-active i{color:inherit}.nav-caret{margin-left:auto;font-size:11px!important;opacity:.7}.nav-item.is-inert{opacity:.45;cursor:default}.nav-item.is-inert:hover{background:transparent;color:var(--ns-frame-muted)}.nav-label{overflow:hidden;text-overflow:ellipsis}.sidebar.is-collapsed .nav-label{display:none}.sidebar.is-collapsed .nav-item{justify-content:center;padding-inline:0}.content{flex:1;min-width:0;padding:28px 28px 64px;display:flex;flex-direction:column;gap:14px}.page-head{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:46px;padding:7px 16px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}.page-head-main{display:flex;min-width:0;flex:1;align-items:center;gap:14px}.page-head-actions{display:flex;flex:none;align-items:center;gap:8px}.page-head h1{margin:0;font-size:19px;font-weight:var(--ns-weight-heading)}.measure{display:flex;width:100%;max-width:var(--ac-content-max, 1440px);flex-direction:column;gap:14px;margin-inline:0}h1{margin:0;font-size:26px;line-height:1.2;font-weight:var(--ns-weight-emphasis);letter-spacing:-.02em}.access-menu{display:flex;flex-direction:column;gap:.15rem;margin-top:.75rem;padding-top:.75rem;border-top:1px solid var(--ns-frame-line)}.access-caption{margin:0 0 .4rem;padding:0 .75rem;color:var(--ns-frame-muted);font-size:.68rem;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.access-state{margin:0;padding:.35rem .75rem;color:var(--ns-frame-muted);font-size:.78rem}.access-state.is-error{color:var(--p-red-400, #f87171)}.nav-item.is-child{padding-left:2.1rem;font-size:.86rem}@media(max-width:720px){.sidebar{max-width:none;position:fixed;top:var(--ns-topbar-h, 56px);bottom:0;left:0;z-index:30;width:268px;max-width:82vw;overflow-y:auto;box-shadow:0 18px 44px #00000073;transform:translate(-100%);transition:transform .18s ease}.sidebar.is-collapsed{width:268px;max-width:82vw;transform:translate(-100%)}.sidebar:not(.is-collapsed){transform:translate(0)}.sidebar.is-collapsed .nav-label{display:inline}.sidebar.is-collapsed .role-text{display:flex}.sidebar.is-collapsed .nav-item,.sidebar.is-collapsed .role-badge{justify-content:flex-start;padding-inline:12px}.brand-secondary{display:none}.topbar{height:auto;min-height:56px;flex-wrap:wrap;padding-bottom:8px;row-gap:8px}.context{order:3;width:100%;margin-left:0}.context-select{min-width:0;max-width:none;flex:1 1 0}.content{padding:20px 16px 48px}h1{font-size:22px}.page-head{gap:10px;min-height:42px;padding:7px 12px}.page-head-main{gap:8px}.page-head h1{overflow:hidden;min-width:0;font-size:16px;text-overflow:ellipsis;white-space:nowrap}.page-head-actions{flex-wrap:wrap;justify-content:flex-end;gap:6px}.page-head-actions ::ng-deep .p-button{padding-block:6px;padding-inline:11px;font-size:13px;white-space:nowrap}.page-head-actions ::ng-deep .p-button-icon{font-size:13px}}.who{display:flex;align-items:center;gap:12px;margin:6px 6px 0;padding:12px;border-radius:10px;background:var(--ac-text);color:var(--ac-surface)}.who-photo{width:42px;height:42px;flex:none;border-radius:999px;object-fit:cover}.who-initials{display:inline-flex;align-items:center;justify-content:center;background:var(--ac-accent);color:var(--ac-on-accent);font-size:15px;font-weight:var(--ns-weight-emphasis)}.who-text{display:flex;min-width:0;flex-direction:column}.who-name{overflow:hidden;font-size:14px;font-weight:var(--ns-weight-emphasis);text-overflow:ellipsis;white-space:nowrap}.who-mail{overflow:hidden;color:color-mix(in srgb,currentColor 64%,transparent);font-size:12px;text-overflow:ellipsis;white-space:nowrap}.who-role{display:flex;align-items:center;gap:7px;margin:0;overflow:hidden;padding:11px 17px 5px;color:var(--ac-text-muted);font-size:12px;white-space:nowrap}.who-role b{flex:none;color:var(--ac-text);font-size:12px;font-weight:var(--ns-weight-emphasis)}.who-sep{flex:none}.who-context{overflow:hidden;text-overflow:ellipsis}.who-dot{width:7px;height:7px;flex:none;border-radius:50%;background:var(--ns-success)}.company-option{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%}.company-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.launcher-notice{display:flex;gap:10px;margin:12px 12px 0;padding:12px;border:1px solid color-mix(in srgb,var(--ac-accent) 40%,transparent);border-radius:8px;background:color-mix(in srgb,var(--ac-accent) 10%,transparent)}.launcher-notice i{margin-top:2px;color:var(--ac-accent);font-size:15px}.launcher-notice-title{margin:0 0 4px;font-size:13px;font-weight:var(--ns-weight-emphasis)}.launcher-notice-body{margin:0;color:var(--ac-text-muted);font-size:12px;line-height:1.45}.confirm{display:flex;flex-direction:column;align-items:center;gap:6px;padding:26px 24px 20px;border:1px solid var(--ac-border);border-radius:14px;background:var(--ac-surface);text-align:center}.confirm h2{margin:8px 0 0;font-size:17px;font-weight:var(--ns-weight-heading)}.confirm p{margin:0;max-width:34ch;color:var(--ac-text-muted);font-size:13px;line-height:1.5}.confirm-actions{display:flex;justify-content:center;gap:8px;margin-top:18px}.toast-text{flex:1;margin-left:12px}.toast-summary{margin:0;font-size:13px;font-weight:var(--ns-weight-emphasis)}.toast-detail{margin:2px 0 0;color:var(--ac-text-muted);font-size:12px}.context{display:flex;min-width:0;align-items:center;gap:8px;margin-left:14px}.context-select{min-width:150px;max-width:210px}.role-badge{display:flex;align-items:center;gap:12px;padding:4px 12px 2px}.role-badge>i{flex:none;color:var(--ns-frame-muted);font-size:14px}.role-text{display:flex;min-width:0;flex-direction:column;gap:1px}.role-name{overflow:hidden;color:var(--ns-frame-ink);font-size:13px;font-weight:var(--ns-weight-emphasis);text-overflow:ellipsis;white-space:nowrap}.role-caption{color:var(--ns-frame-muted);font-size:10px;letter-spacing:.06em;text-transform:uppercase}.sidebar.is-collapsed .role-badge{justify-content:center;padding-inline:0}.sidebar-scrim{position:fixed;top:var(--ns-topbar-h, 56px);right:0;bottom:0;left:0;z-index:29;padding:0;border:0;background:#00000073;cursor:pointer}.nav-skeleton{display:flex;flex-direction:column;gap:3px}.nav-skeleton-item{display:flex;align-items:center;gap:12px;padding:11px 12px}.sidebar.is-collapsed .nav-skeleton-item .p-skeleton:last-child{display:none}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i1$3.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: BreadcrumbModule }, { kind: "component", type: i2$4.Breadcrumb, selector: "p-breadcrumb", inputs: ["model", "style", "styleClass", "home", "homeAriaLabel"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ConfirmDialogModule }, { kind: "component", type: i4$1.ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "modal", "visible", "position", "draggable"], outputs: ["onHide"] }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i5$2.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "motionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i6$2.Drawer, selector: "p-drawer", inputs: ["appendTo", "motionOptions", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i3.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i5$1.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: NucleusAppearance, selector: "nucleus-appearance" }, { kind: "component", type: NucleusLordicon, selector: "nucleus-lordicon", inputs: ["src", "trigger", "state", "size", "tone"] }, { kind: "component", type: NucleusMenu, selector: "nucleus-menu", inputs: ["sections", "heading", "badge", "searchable", "searchPlaceholder", "emptyText", "keyboardHint", "width", "layout", "columns"], outputs: ["select", "dismiss"] }, { kind: "component", type: NucleusMark, selector: "nucleus-mark", inputs: ["accent", "size"] }, { kind: "component", type: NucleusStarfield, selector: "nucleus-starfield" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3883
4283
|
}
|
|
3884
4284
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusShell, decorators: [{
|
|
3885
4285
|
type: Component,
|
|
@@ -3902,8 +4302,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
3902
4302
|
NucleusMenu,
|
|
3903
4303
|
NucleusMark,
|
|
3904
4304
|
NucleusStarfield,
|
|
3905
|
-
], host: { '[style.--ns-topbar-h]': 'topbarHeight()' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let t = copy();\n@let me = identity();\n\n@if (starfield()) {\n <nucleus-starfield />\n}\n\n<header class=\"topbar ns-frame\">\n <div class=\"side\">\n <p-button\n icon=\"pi pi-bars\"\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"t.navToggle\"\n [pTooltip]=\"t.navToggle\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSidebar()\"\n />\n\n <div class=\"brand\">\n <nucleus-mark [size]=\"20\" />\n <div class=\"brand-name\">\n <span class=\"brand-primary\">NUCLEUS</span>\n <span class=\"brand-secondary\">{{ brand() }}</span>\n </div>\n </div>\n\n </div>\n\n @if (hasSiteContext()) {\n <div class=\"context ns-context\">\n <p-select\n styleClass=\"context-select\"\n [options]=\"companyChoices()\"\n optionValue=\"id\"\n optionLabel=\"name\"\n [ngModel]=\"companyChoice()\"\n (ngModelChange)=\"onCompanyChange($event)\"\n [placeholder]=\"t.companyPlaceholder\"\n [disabled]=\"switching()\"\n [filter]=\"companyChoices().length > 8\"\n filterBy=\"name\"\n [filterPlaceholder]=\"words().search\"\n [autofocusFilter]=\"true\"\n [resetFilterOnHide]=\"true\"\n [ariaLabel]=\"t.companyLabel\"\n [ngModelOptions]=\"{ standalone: true }\"\n >\n <ng-template #item let-option>\n <span class=\"company-option\">\n <span class=\"company-name\">{{ option.name }}</span>\n <p-tag [value]=\"option.tag\" severity=\"secondary\" />\n </span>\n </ng-template>\n </p-select>\n\n <p-select\n styleClass=\"context-select\"\n [options]=\"siteOptions()\"\n optionValue=\"id\"\n optionLabel=\"name\"\n [ngModel]=\"siteChoice()\"\n (ngModelChange)=\"onSiteChange($event)\"\n [placeholder]=\"sitePlaceholder()\"\n [disabled]=\"switching() || sitesLoading() || !siteOptions().length\"\n [filter]=\"siteOptions().length > 8\"\n filterBy=\"name\"\n [filterPlaceholder]=\"words().search\"\n [autofocusFilter]=\"true\"\n [resetFilterOnHide]=\"true\"\n [ariaLabel]=\"t.siteLabel\"\n [ngModelOptions]=\"{ standalone: true }\"\n />\n </div>\n }\n\n <div class=\"side is-end\">\n <div class=\"lang-switch\" role=\"group\" aria-label=\"Idioma / Language\">\n <button\n type=\"button\"\n class=\"lang-pill\"\n [class.is-active]=\"lang() === 'es'\"\n [attr.aria-pressed]=\"lang() === 'es'\"\n (click)=\"setLang('es')\"\n >\n ES\n </button>\n <button\n type=\"button\"\n class=\"lang-pill\"\n [class.is-active]=\"lang() === 'en'\"\n [attr.aria-pressed]=\"lang() === 'en'\"\n (click)=\"setLang('en')\"\n >\n EN\n </button>\n </div>\n\n <p-button\n icon=\"pi pi-th-large\"\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"t.appsLauncher\"\n [pTooltip]=\"t.appsLauncher\"\n tooltipPosition=\"bottom\"\n (onClick)=\"launcher.toggle($event)\"\n />\n\n <p-popover #launcher styleClass=\"ns-flush-popover\">\n @if (!hasCompany()) {\n <div class=\"launcher-notice\">\n <i class=\"pi pi-building\" aria-hidden=\"true\"></i>\n <div>\n <p class=\"launcher-notice-title\">{{ t.noCompanyTitle }}</p>\n <p class=\"launcher-notice-body\">{{ t.noCompanyHint }}</p>\n </div>\n </div>\n }\n\n <nucleus-menu\n [heading]=\"t.appsSwitch\"\n [badge]=\"launcherCount()\"\n [sections]=\"launcherSections()\"\n [searchable]=\"launcherRich()\"\n [searchPlaceholder]=\"t.appsSearch\"\n [emptyText]=\"launcherRich() ? t.appsNoMatch : t.appsEmpty\"\n [keyboardHint]=\"t.keyboardHint\"\n [width]=\"336\"\n (select)=\"onLauncherSelect($event); launcher.hide()\"\n (dismiss)=\"launcher.hide()\"\n />\n </p-popover>\n\n <p-button\n icon=\"pi pi-cog\"\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"t.settingsTitle\"\n [pTooltip]=\"t.settingsTitle\"\n tooltipPosition=\"bottom\"\n (onClick)=\"settingsOpen.set(true)\"\n />\n\n @if (me) {\n <p-button\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n styleClass=\"avatar-trigger\"\n [ariaLabel]=\"me.name\"\n [pTooltip]=\"me.name\"\n tooltipPosition=\"bottom\"\n (onClick)=\"account.toggle($event)\"\n >\n <p-avatar\n [image]=\"me.photoUrl ?? undefined\"\n [label]=\"me.photoUrl ? undefined : initials()\"\n shape=\"circle\"\n size=\"normal\"\n />\n </p-button>\n }\n </div>\n</header>\n\n<p-popover #account styleClass=\"ns-flush-popover\">\n @if (me) {\n <div class=\"who\">\n @if (me.photoUrl) {\n <img class=\"who-photo\" [src]=\"me.photoUrl\" alt=\"\" width=\"42\" height=\"42\" />\n } @else {\n <span class=\"who-photo who-initials\">{{ initials() }}</span>\n }\n <span class=\"who-text\">\n <span class=\"who-name\">{{ me.name }}</span>\n <span class=\"who-mail\">{{ me.email }}</span>\n </span>\n </div>\n\n <p class=\"who-role\">\n <span class=\"who-dot\" aria-hidden=\"true\"></span>\n @if (roleName(); as role) {\n <b>{{ role }}</b>\n <span class=\"who-sep\">\u00B7</span>\n }\n <span class=\"who-context\">{{ accountContext() }}</span>\n </p>\n\n <nucleus-menu\n [sections]=\"accountSections()\"\n [width]=\"304\"\n (select)=\"onAccountSelect($event); account.hide()\"\n (dismiss)=\"account.hide()\"\n />\n }\n</p-popover>\n\n<div class=\"body\">\n @if (narrow() && sidebarOpen()) {\n <button\n type=\"button\"\n class=\"sidebar-scrim\"\n [attr.aria-label]=\"t.navToggle\"\n (click)=\"toggleSidebar()\"\n ></button>\n }\n\n <aside class=\"sidebar ns-frame\" [class.is-collapsed]=\"!sidebarOpen()\">\n @if (roleName(); as role) {\n <div class=\"role-badge\" [pTooltip]=\"sidebarOpen() ? '' : role\" tooltipPosition=\"right\">\n <i class=\"pi pi-key\" aria-hidden=\"true\"></i>\n <span class=\"nav-label role-text\">\n <span class=\"role-name\">{{ role }}</span>\n <span class=\"role-caption\">{{ t.roleCaption }}</span>\n </span>\n </div>\n }\n\n @if (navItems().length) {\n <nav>\n @for (item of navItems(); track item.id) {\n <button\n type=\"button\"\n class=\"nav-item\"\n [class.is-active]=\"activeNavId() === item.id\"\n [attr.aria-current]=\"activeNavId() === item.id ? 'page' : null\"\n [pTooltip]=\"sidebarOpen() ? '' : item.label\"\n tooltipPosition=\"right\"\n (click)=\"selectNav(item.id)\"\n >\n <i [class]=\"item.icon\" aria-hidden=\"true\"></i>\n <span class=\"nav-label\">{{ item.label }}</span>\n </button>\n }\n </nav>\n }\n\n <nav class=\"access-menu\">\n @if (menuLoading()) {\n <div class=\"nav-skeleton\" role=\"status\" [attr.aria-label]=\"t.accessLoading\">\n @for (width of menuPlaceholders; track $index) {\n <div class=\"nav-skeleton-item\">\n <p-skeleton shape=\"circle\" size=\"15px\" />\n <p-skeleton height=\"9px\" [width]=\"width\" />\n </div>\n }\n </div>\n } @else if (menuError()) {\n <p class=\"access-state is-error\">{{ menuError() }}</p>\n } @else if (!menu().length) {\n <p class=\"access-state\">{{ t.accessEmpty }}</p>\n } @else {\n @for (node of menu(); track node.id) {\n @let group = isGroup(node);\n @let open = isExpanded(node);\n\n <button\n type=\"button\"\n class=\"nav-item\"\n [class.is-active]=\"!group && isSelected(node)\"\n [class.is-inert]=\"!group && !node.route\"\n [attr.aria-expanded]=\"group ? open : null\"\n [disabled]=\"!group && !node.route\"\n [pTooltip]=\"sidebarOpen() ? '' : node.label\"\n tooltipPosition=\"right\"\n (click)=\"selectMenu(node)\"\n >\n <i [class]=\"node.icon ?? 'pi pi-circle'\" aria-hidden=\"true\"></i>\n <span class=\"nav-label\">{{ node.label }}</span>\n @if (group && sidebarOpen()) {\n <i\n class=\"pi nav-caret\"\n [class.pi-chevron-down]=\"open\"\n [class.pi-chevron-right]=\"!open\"\n aria-hidden=\"true\"\n ></i>\n }\n </button>\n\n @if (open) {\n @for (child of node.children; track child.id) {\n <button\n type=\"button\"\n class=\"nav-item is-child\"\n [class.is-active]=\"isSelected(child)\"\n [pTooltip]=\"sidebarOpen() ? '' : child.label\"\n tooltipPosition=\"right\"\n (click)=\"selectMenu(child)\"\n >\n <i [class]=\"child.icon ?? 'pi pi-circle'\" aria-hidden=\"true\"></i>\n <span class=\"nav-label\">{{ child.label }}</span>\n </button>\n }\n }\n }\n }\n </nav>\n </aside>\n\n <main class=\"content\">\n <div class=\"measure\">\n <ng-content select=\"[nucleusTop]\" />\n\n @if (crumbs().length || title() || pageActions()) {\n <header class=\"page-head\">\n <div class=\"page-head-main\">\n @if (crumbs().length) {\n <p-breadcrumb [model]=\"crumbs()\" [home]=\"home()\" styleClass=\"ns-crumbs\" />\n }\n\n @if (title()) {\n <h1>{{ title() }}</h1>\n }\n </div>\n\n @if (pageActions(); as actions) {\n <div class=\"page-head-actions\">\n <ng-container [ngTemplateOutlet]=\"actions\" />\n </div>\n }\n </header>\n }\n\n <ng-content />\n </div>\n </main>\n</div>\n\n<p-drawer\n [visible]=\"settingsOpen()\"\n (visibleChange)=\"settingsOpen.set($event)\"\n position=\"right\"\n [header]=\"t.settingsTitle\"\n [modal]=\"false\"\n [blockScroll]=\"false\"\n styleClass=\"ns-settings-drawer\"\n [style]=\"{ width: '380px' }\"\n>\n <nucleus-appearance />\n</p-drawer>\n\n<p-toast position=\"bottom-right\" styleClass=\"ns-toast\">\n <ng-template #message let-message>\n <nucleus-lordicon\n [src]=\"message.severity === 'success' ? icons.check : icons.warning\"\n [tone]=\"message.severity === 'success' ? 'accent' : 'danger'\"\n [size]=\"34\"\n trigger=\"in\"\n />\n <div class=\"toast-text\">\n <p class=\"toast-summary\">{{ message.summary }}</p>\n @if (message.detail) {\n <p class=\"toast-detail\">{{ message.detail }}</p>\n }\n </div>\n </ng-template>\n</p-toast>\n\n<p-confirmdialog [style]=\"{ width: '420px' }\">\n <ng-template #headless let-message let-onAccept=\"onAccept\" let-onReject=\"onReject\">\n <div class=\"confirm\">\n <nucleus-lordicon\n [src]=\"message.icon\"\n [tone]=\"message.acceptButtonStyleClass ? 'danger' : 'accent'\"\n [size]=\"64\"\n trigger=\"loop\"\n />\n <h2>{{ message.header }}</h2>\n <p>{{ message.message }}</p>\n <div class=\"confirm-actions\">\n <p-button\n [label]=\"message.rejectLabel\"\n severity=\"secondary\"\n [text]=\"true\"\n (onClick)=\"onReject()\"\n />\n <p-button\n [label]=\"message.acceptLabel\"\n [severity]=\"message.acceptButtonStyleClass ? 'danger' : 'primary'\"\n (onClick)=\"onAccept()\"\n />\n </div>\n </div>\n </ng-template>\n</p-confirmdialog>\n", styles: [":host{display:flex;flex-direction:column;min-height:100dvh;background:var(--ac-bg);color:var(--ac-text)}.topbar{position:sticky;top:0;z-index:20;display:flex;align-items:center;justify-content:flex-start;gap:16px;height:56px;padding:0 12px 0 8px;border-bottom:1px solid var(--ns-frame-line)}.side{display:flex;min-width:0;align-items:center;gap:4px}.side.is-end{margin-left:auto}.brand{display:flex;align-items:center;gap:9px;margin-left:4px}.brand-name{display:flex;align-items:baseline;gap:7px}.brand-primary{font-size:13px;font-weight:700;letter-spacing:.15em}.brand-secondary{font-size:9px;font-weight:500;letter-spacing:.22em;color:var(--ns-frame-muted)}.lang-switch{display:flex;align-items:center;gap:2px;margin-right:6px;border:1px solid var(--ns-frame-line);border-radius:999px;padding:2px}.lang-pill{font-size:10px;font-weight:600;letter-spacing:.08em;padding:4px 10px;border:none;border-radius:999px;background:transparent;color:var(--ns-frame-muted);cursor:pointer}.lang-pill:hover{color:var(--ns-frame-ink)}.lang-pill.is-active{background:var(--ns-frame-glow);color:var(--ns-frame-on-glow)}.body{display:flex;flex:1;min-height:0}.sidebar{flex:none;width:max-content;min-width:224px;max-width:340px;padding:12px 10px;border-right:1px solid var(--ns-frame-line);transition:width .18s ease}.sidebar.is-collapsed{width:60px;min-width:0}.sidebar nav{display:flex;flex-direction:column;gap:3px}.nav-item{display:flex;align-items:center;gap:12px;width:100%;padding:var(--ns-nav-y, 9px) 12px;border:none;border-radius:6px;background:transparent;color:var(--ns-frame-muted);font-size:13px;font-weight:500;text-align:left;white-space:nowrap;cursor:pointer}.nav-item i{flex:none;font-size:15px}.nav-item:hover{background:var(--ns-frame-raised);color:var(--ns-frame-ink)}.nav-item.is-active{background:var(--ns-frame-raised);box-shadow:inset 2px 0 0 var(--ns-frame-glow);color:var(--ns-frame-ink)}.nav-item.is-active i{color:var(--ns-frame-glow)}.nav-caret{margin-left:auto;font-size:11px!important;opacity:.7}.nav-item.is-inert{opacity:.45;cursor:default}.nav-item.is-inert:hover{background:transparent;color:var(--ns-frame-muted)}.nav-label{overflow:hidden;text-overflow:ellipsis}.sidebar.is-collapsed .nav-label{display:none}.sidebar.is-collapsed .nav-item{justify-content:center;padding-inline:0}.content{flex:1;min-width:0;padding:28px 28px 64px;display:flex;flex-direction:column;gap:14px}.page-head{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:46px;padding:7px 16px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}.page-head-main{display:flex;min-width:0;flex:1;align-items:center;gap:14px}.page-head-actions{display:flex;flex:none;align-items:center;gap:8px}.page-head h1{margin:0;font-size:19px;font-weight:600}.measure{display:flex;width:100%;max-width:var(--ac-content-max, 1440px);flex-direction:column;gap:14px;margin-inline:0}h1{margin:0;font-size:26px;line-height:1.2;font-weight:500;letter-spacing:-.02em}.access-menu{display:flex;flex-direction:column;gap:.15rem;margin-top:.75rem;padding-top:.75rem;border-top:1px solid var(--ns-frame-line)}.access-caption{margin:0 0 .4rem;padding:0 .75rem;color:var(--ns-frame-muted);font-size:.68rem;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.access-state{margin:0;padding:.35rem .75rem;color:var(--ns-frame-muted);font-size:.78rem}.access-state.is-error{color:var(--p-red-400, #f87171)}.nav-item.is-child{padding-left:2.1rem;font-size:.86rem}@media(max-width:720px){.sidebar{max-width:none;position:fixed;top:var(--ns-topbar-h, 56px);bottom:0;left:0;z-index:30;width:268px;max-width:82vw;overflow-y:auto;box-shadow:0 18px 44px #00000073;transform:translate(-100%);transition:transform .18s ease}.sidebar.is-collapsed{width:268px;max-width:82vw;transform:translate(-100%)}.sidebar:not(.is-collapsed){transform:translate(0)}.sidebar.is-collapsed .nav-label{display:inline}.sidebar.is-collapsed .role-text{display:flex}.sidebar.is-collapsed .nav-item,.sidebar.is-collapsed .role-badge{justify-content:flex-start;padding-inline:12px}.brand-secondary{display:none}.topbar{height:auto;min-height:56px;flex-wrap:wrap;padding-bottom:8px;row-gap:8px}.context{order:3;width:100%;margin-left:0}.context-select{min-width:0;max-width:none;flex:1 1 0}.content{padding:20px 16px 48px}h1{font-size:22px}.page-head{align-items:stretch;flex-direction:column;gap:10px;padding:10px 14px}.page-head-actions{justify-content:flex-end}}.who{display:flex;align-items:center;gap:12px;padding:15px 15px 13px;border-bottom:1px solid var(--ac-border);background:var(--ns-header-bg)}.who-photo{width:42px;height:42px;flex:none;border-radius:999px;object-fit:cover}.who-initials{display:inline-flex;align-items:center;justify-content:center;background:var(--ac-accent);color:var(--ac-on-accent);font-size:15px;font-weight:600}.who-text{display:flex;min-width:0;flex-direction:column}.who-name{overflow:hidden;font-size:14px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.who-mail{overflow:hidden;color:var(--ac-text-muted);font-size:11.5px;text-overflow:ellipsis;white-space:nowrap}.who-role{display:flex;align-items:center;gap:7px;margin:0;overflow:hidden;padding:9px 15px;border-bottom:1px solid var(--ac-border);color:var(--ac-text-muted);font-size:11.5px;white-space:nowrap}.who-role b{flex:none;color:var(--ac-text);font-size:12px;font-weight:600}.who-sep{flex:none}.who-context{overflow:hidden;text-overflow:ellipsis}.who-dot{width:5px;height:5px;flex:none;border-radius:50%;background:var(--ac-accent)}.company-option{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%}.company-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.launcher-notice{display:flex;gap:10px;margin:12px 12px 0;padding:12px;border:1px solid color-mix(in srgb,var(--ac-accent) 40%,transparent);border-radius:8px;background:color-mix(in srgb,var(--ac-accent) 10%,transparent)}.launcher-notice i{margin-top:2px;color:var(--ac-accent);font-size:15px}.launcher-notice-title{margin:0 0 4px;font-size:13px;font-weight:600}.launcher-notice-body{margin:0;color:var(--ac-text-muted);font-size:12px;line-height:1.45}.confirm{display:flex;flex-direction:column;align-items:center;gap:6px;padding:26px 24px 20px;border:1px solid var(--ac-border);border-radius:14px;background:var(--ac-surface);text-align:center}.confirm h2{margin:8px 0 0;font-size:17px;font-weight:600}.confirm p{margin:0;max-width:34ch;color:var(--ac-text-muted);font-size:13px;line-height:1.5}.confirm-actions{display:flex;justify-content:center;gap:8px;margin-top:18px}.toast-text{flex:1;margin-left:12px}.toast-summary{margin:0;font-size:13px;font-weight:600}.toast-detail{margin:2px 0 0;color:var(--ac-text-muted);font-size:12px}.context{display:flex;min-width:0;align-items:center;gap:8px;margin-left:14px}.context-select{min-width:150px;max-width:210px}.role-badge{display:flex;align-items:center;gap:12px;margin-bottom:10px;padding:9px 12px;border-left:2px solid var(--ns-frame-glow);border-radius:0 7px 7px 0;background:var(--ns-frame-raised);box-shadow:-2px 0 12px -3px color-mix(in srgb,var(--ns-frame-glow) 65%,transparent)}.role-badge>i{flex:none;color:var(--ns-frame-glow);font-size:14px}.role-text{display:flex;min-width:0;flex-direction:column;gap:1px}.role-name{overflow:hidden;color:var(--ns-frame-ink);font-size:13px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.role-caption{color:var(--ns-frame-muted);font-size:10px;letter-spacing:.06em;text-transform:uppercase}.sidebar.is-collapsed .role-badge{justify-content:center;padding-inline:0}.sidebar-scrim{position:fixed;top:var(--ns-topbar-h, 56px);right:0;bottom:0;left:0;z-index:29;padding:0;border:0;background:#00000073;cursor:pointer}.nav-skeleton{display:flex;flex-direction:column;gap:3px}.nav-skeleton-item{display:flex;align-items:center;gap:12px;padding:11px 12px}.sidebar.is-collapsed .nav-skeleton-item .p-skeleton:last-child{display:none}\n"] }]
|
|
4305
|
+
], host: { '[style.--ns-topbar-h]': 'topbarHeight()' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let t = copy();\n@let me = identity();\n\n@if (starfield()) {\n <nucleus-starfield />\n}\n\n<header class=\"topbar ns-frame\">\n <div class=\"side\">\n <p-button\n icon=\"pi pi-bars\"\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"t.navToggle\"\n [pTooltip]=\"t.navToggle\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSidebar()\"\n />\n\n <div class=\"brand\">\n <nucleus-mark [size]=\"20\" />\n <div class=\"brand-name\">\n <span class=\"brand-primary\">NUCLEUS</span>\n <span class=\"brand-secondary\">{{ brand() }}</span>\n </div>\n </div>\n\n </div>\n\n @if (hasSiteContext()) {\n <div class=\"context ns-context\">\n <p-select\n styleClass=\"context-select\"\n [options]=\"companyChoices()\"\n optionValue=\"id\"\n optionLabel=\"name\"\n [ngModel]=\"companyChoice()\"\n (ngModelChange)=\"onCompanyChange($event)\"\n [placeholder]=\"t.companyPlaceholder\"\n [disabled]=\"switching()\"\n [filter]=\"companyChoices().length > 8\"\n filterBy=\"name\"\n [filterPlaceholder]=\"words().search\"\n [autofocusFilter]=\"true\"\n [resetFilterOnHide]=\"true\"\n [ariaLabel]=\"t.companyLabel\"\n [ngModelOptions]=\"{ standalone: true }\"\n >\n <ng-template #item let-option>\n <span class=\"company-option\">\n <span class=\"company-name\">{{ option.name }}</span>\n <p-tag [value]=\"option.tag\" severity=\"secondary\" />\n </span>\n </ng-template>\n </p-select>\n\n <p-select\n styleClass=\"context-select\"\n [options]=\"siteOptions()\"\n optionValue=\"id\"\n optionLabel=\"name\"\n [ngModel]=\"siteChoice()\"\n (ngModelChange)=\"onSiteChange($event)\"\n [placeholder]=\"sitePlaceholder()\"\n [disabled]=\"switching() || sitesLoading() || !siteOptions().length\"\n [filter]=\"siteOptions().length > 8\"\n filterBy=\"name\"\n [filterPlaceholder]=\"words().search\"\n [autofocusFilter]=\"true\"\n [resetFilterOnHide]=\"true\"\n [ariaLabel]=\"t.siteLabel\"\n [ngModelOptions]=\"{ standalone: true }\"\n />\n </div>\n }\n\n <div class=\"side is-end\">\n <div class=\"lang-switch\" role=\"group\" aria-label=\"Idioma / Language\">\n <button\n type=\"button\"\n class=\"lang-pill\"\n [class.is-active]=\"lang() === 'es'\"\n [attr.aria-pressed]=\"lang() === 'es'\"\n (click)=\"setLang('es')\"\n >\n ES\n </button>\n <button\n type=\"button\"\n class=\"lang-pill\"\n [class.is-active]=\"lang() === 'en'\"\n [attr.aria-pressed]=\"lang() === 'en'\"\n (click)=\"setLang('en')\"\n >\n EN\n </button>\n </div>\n\n <p-button\n icon=\"pi pi-th-large\"\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"t.appsLauncher\"\n [pTooltip]=\"t.appsLauncher\"\n tooltipPosition=\"bottom\"\n (onClick)=\"launcher.toggle($event)\"\n />\n\n <p-popover #launcher styleClass=\"ns-flush-popover\">\n @if (!hasCompany()) {\n <div class=\"launcher-notice\">\n <i class=\"pi pi-building\" aria-hidden=\"true\"></i>\n <div>\n <p class=\"launcher-notice-title\">{{ t.noCompanyTitle }}</p>\n <p class=\"launcher-notice-body\">{{ t.noCompanyHint }}</p>\n </div>\n </div>\n }\n\n <nucleus-menu\n layout=\"grid\"\n [heading]=\"t.appsSwitch\"\n [sections]=\"launcherSections()\"\n [searchable]=\"launcherRich()\"\n [searchPlaceholder]=\"t.appsSearch\"\n [emptyText]=\"launcherRich() ? t.appsNoMatch : t.appsEmpty\"\n [keyboardHint]=\"t.keyboardHint\"\n [width]=\"384\"\n (select)=\"onLauncherSelect($event); launcher.hide()\"\n (dismiss)=\"launcher.hide()\"\n />\n </p-popover>\n\n <p-button\n icon=\"pi pi-cog\"\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n [ariaLabel]=\"t.settingsTitle\"\n [pTooltip]=\"t.settingsTitle\"\n tooltipPosition=\"bottom\"\n (onClick)=\"settingsOpen.set(true)\"\n />\n\n @if (me) {\n <p-button\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [rounded]=\"true\"\n styleClass=\"avatar-trigger\"\n [ariaLabel]=\"me.name\"\n [pTooltip]=\"me.name\"\n tooltipPosition=\"bottom\"\n (onClick)=\"account.toggle($event)\"\n >\n <p-avatar\n [image]=\"me.photoUrl ?? undefined\"\n [label]=\"me.photoUrl ? undefined : initials()\"\n shape=\"circle\"\n size=\"normal\"\n />\n </p-button>\n }\n </div>\n</header>\n\n<p-popover #account styleClass=\"ns-flush-popover\">\n @if (me) {\n <div class=\"who\">\n @if (me.photoUrl) {\n <img class=\"who-photo\" [src]=\"me.photoUrl\" alt=\"\" width=\"42\" height=\"42\" />\n } @else {\n <span class=\"who-photo who-initials\">{{ initials() }}</span>\n }\n <span class=\"who-text\">\n <span class=\"who-name\">{{ me.name }}</span>\n <span class=\"who-mail\">{{ me.email }}</span>\n </span>\n </div>\n\n <p class=\"who-role\">\n <span class=\"who-dot\" aria-hidden=\"true\"></span>\n @if (roleName(); as role) {\n <b>{{ role }}</b>\n <span class=\"who-sep\">\u00B7</span>\n }\n <span class=\"who-context\">{{ accountContext() }}</span>\n </p>\n\n <nucleus-menu\n [sections]=\"accountSections()\"\n [width]=\"304\"\n (select)=\"onAccountSelect($event); account.hide()\"\n (dismiss)=\"account.hide()\"\n />\n }\n</p-popover>\n\n<div class=\"body\">\n @if (narrow() && sidebarOpen()) {\n <button\n type=\"button\"\n class=\"sidebar-scrim\"\n [attr.aria-label]=\"t.navToggle\"\n (click)=\"toggleSidebar()\"\n ></button>\n }\n\n <aside class=\"sidebar ns-frame\" [class.is-collapsed]=\"!sidebarOpen()\">\n @if (roleName(); as role) {\n <div class=\"role-badge\" [pTooltip]=\"sidebarOpen() ? '' : role\" tooltipPosition=\"right\">\n <i class=\"pi pi-key\" aria-hidden=\"true\"></i>\n <span class=\"nav-label role-text\">\n <span class=\"role-name\">{{ role }}</span>\n <span class=\"role-caption\">{{ t.roleCaption }}</span>\n </span>\n </div>\n }\n\n @if (navItems().length) {\n <nav>\n @for (item of navItems(); track item.id) {\n <button\n type=\"button\"\n class=\"nav-item\"\n [class.is-active]=\"activeNavId() === item.id\"\n [attr.aria-current]=\"activeNavId() === item.id ? 'page' : null\"\n [pTooltip]=\"sidebarOpen() ? '' : item.label\"\n tooltipPosition=\"right\"\n (click)=\"selectNav(item.id)\"\n >\n <i [class]=\"item.icon\" aria-hidden=\"true\"></i>\n <span class=\"nav-label\">{{ item.label }}</span>\n </button>\n }\n </nav>\n }\n\n <nav class=\"access-menu\">\n @if (menuLoading()) {\n <div class=\"nav-skeleton\" role=\"status\" [attr.aria-label]=\"t.accessLoading\">\n @for (width of menuPlaceholders; track $index) {\n <div class=\"nav-skeleton-item\">\n <p-skeleton shape=\"circle\" size=\"15px\" />\n <p-skeleton height=\"9px\" [width]=\"width\" />\n </div>\n }\n </div>\n } @else if (menuError()) {\n <p class=\"access-state is-error\">{{ menuError() }}</p>\n } @else if (!menu().length) {\n <p class=\"access-state\">{{ t.accessEmpty }}</p>\n } @else {\n @for (node of menu(); track node.id) {\n @let group = isGroup(node);\n @let open = isExpanded(node);\n\n <button\n type=\"button\"\n class=\"nav-item\"\n [class.is-active]=\"!group && isSelected(node)\"\n [class.is-inert]=\"!group && !node.route\"\n [attr.aria-expanded]=\"group ? open : null\"\n [disabled]=\"!group && !node.route\"\n [pTooltip]=\"sidebarOpen() ? '' : node.label\"\n tooltipPosition=\"right\"\n (click)=\"selectMenu(node)\"\n >\n <i [class]=\"node.icon ?? 'pi pi-circle'\" aria-hidden=\"true\"></i>\n <span class=\"nav-label\">{{ node.label }}</span>\n @if (group && sidebarOpen()) {\n <i\n class=\"pi nav-caret\"\n [class.pi-chevron-down]=\"open\"\n [class.pi-chevron-right]=\"!open\"\n aria-hidden=\"true\"\n ></i>\n }\n </button>\n\n @if (open) {\n @for (child of node.children; track child.id) {\n <button\n type=\"button\"\n class=\"nav-item is-child\"\n [class.is-active]=\"isSelected(child)\"\n [pTooltip]=\"sidebarOpen() ? '' : child.label\"\n tooltipPosition=\"right\"\n (click)=\"selectMenu(child)\"\n >\n <i [class]=\"child.icon ?? 'pi pi-circle'\" aria-hidden=\"true\"></i>\n <span class=\"nav-label\">{{ child.label }}</span>\n </button>\n }\n }\n }\n }\n </nav>\n </aside>\n\n <main class=\"content\">\n <div class=\"measure\">\n <ng-content select=\"[nucleusTop]\" />\n\n @if (crumbs().length || title() || pageActions()) {\n <header class=\"page-head\">\n <div class=\"page-head-main\">\n @if (crumbs().length) {\n <p-breadcrumb [model]=\"crumbs()\" [home]=\"home()\" styleClass=\"ns-crumbs\" />\n }\n\n @if (title()) {\n <h1>{{ title() }}</h1>\n }\n </div>\n\n @if (pageActions(); as actions) {\n <div class=\"page-head-actions\">\n <ng-container [ngTemplateOutlet]=\"actions\" />\n </div>\n }\n </header>\n }\n\n <ng-content />\n </div>\n </main>\n</div>\n\n<p-drawer\n [visible]=\"settingsOpen()\"\n (visibleChange)=\"settingsOpen.set($event)\"\n position=\"right\"\n [header]=\"t.settingsTitle\"\n [modal]=\"false\"\n [blockScroll]=\"false\"\n styleClass=\"ns-settings-drawer\"\n [style]=\"{ width: '380px' }\"\n>\n <nucleus-appearance />\n</p-drawer>\n\n<p-toast position=\"bottom-right\" styleClass=\"ns-toast\">\n <ng-template #message let-message>\n <nucleus-lordicon\n [src]=\"message.severity === 'success' ? icons.check : icons.warning\"\n [tone]=\"message.severity === 'success' ? 'accent' : 'danger'\"\n [size]=\"34\"\n trigger=\"in\"\n />\n <div class=\"toast-text\">\n <p class=\"toast-summary\">{{ message.summary }}</p>\n @if (message.detail) {\n <p class=\"toast-detail\">{{ message.detail }}</p>\n }\n </div>\n </ng-template>\n</p-toast>\n\n<p-confirmdialog [style]=\"{ width: '420px' }\">\n <ng-template #headless let-message let-onAccept=\"onAccept\" let-onReject=\"onReject\">\n <div class=\"confirm\">\n <nucleus-lordicon\n [src]=\"message.icon\"\n [tone]=\"message.acceptButtonStyleClass ? 'danger' : 'accent'\"\n [size]=\"64\"\n trigger=\"loop\"\n />\n <h2>{{ message.header }}</h2>\n <p>{{ message.message }}</p>\n <div class=\"confirm-actions\">\n <p-button\n [label]=\"message.rejectLabel\"\n severity=\"secondary\"\n [text]=\"true\"\n (onClick)=\"onReject()\"\n />\n <p-button\n [label]=\"message.acceptLabel\"\n [severity]=\"message.acceptButtonStyleClass ? 'danger' : 'primary'\"\n (onClick)=\"onAccept()\"\n />\n </div>\n </div>\n </ng-template>\n</p-confirmdialog>\n", styles: [":host{display:flex;flex-direction:column;min-height:100dvh;background:var(--ac-bg);color:var(--ac-text)}.topbar{position:sticky;top:0;z-index:20;display:flex;align-items:center;justify-content:flex-start;gap:16px;height:56px;padding:0 12px 0 8px;border-bottom:1px solid var(--ns-frame-line)}.side{display:flex;min-width:0;align-items:center;gap:4px}.side.is-end{margin-left:auto}.brand{display:flex;align-items:center;gap:9px;margin-left:4px}.brand-name{display:flex;align-items:baseline;gap:7px}.brand-primary{font-size:13px;font-weight:700;letter-spacing:.15em}.brand-secondary{font-size:9px;font-weight:var(--ns-weight-emphasis);letter-spacing:.22em;color:var(--ns-frame-muted)}.lang-switch{display:flex;align-items:center;gap:2px;margin-right:6px;border:1px solid var(--ns-frame-line);border-radius:999px;padding:2px}.lang-pill{font-size:10px;font-weight:var(--ns-weight-emphasis);letter-spacing:.08em;padding:4px 10px;border:none;border-radius:999px;background:transparent;color:var(--ns-frame-muted);cursor:pointer}.lang-pill:hover{color:var(--ns-frame-ink)}.lang-pill.is-active{background:var(--ns-frame-glow);color:var(--ns-frame-on-glow)}.body{display:flex;flex:1;min-height:0}.sidebar{flex:none;width:max-content;min-width:224px;max-width:340px;padding:12px 10px;border-right:1px solid var(--ns-frame-line);transition:width .18s ease}.sidebar.is-collapsed{width:60px;min-width:0}.sidebar nav{display:flex;flex-direction:column;gap:3px}.nav-item{display:flex;align-items:center;gap:12px;width:100%;padding:var(--ns-nav-y, 9px) 12px;border:none;border-radius:6px;background:transparent;color:var(--ns-frame-muted);font-size:13px;font-weight:var(--ns-weight-text);text-align:left;white-space:nowrap;cursor:pointer}.nav-item i{flex:none;font-size:15px}.nav-item:hover{background:var(--ns-frame-raised);color:var(--ns-frame-ink)}.nav-item.is-active{background:var(--ns-nav-active-bg, var(--ns-frame-raised));color:var(--ns-nav-active-ink, var(--ns-frame-ink));font-weight:var(--ns-weight-emphasis)}.nav-item.is-active i{color:inherit}.nav-caret{margin-left:auto;font-size:11px!important;opacity:.7}.nav-item.is-inert{opacity:.45;cursor:default}.nav-item.is-inert:hover{background:transparent;color:var(--ns-frame-muted)}.nav-label{overflow:hidden;text-overflow:ellipsis}.sidebar.is-collapsed .nav-label{display:none}.sidebar.is-collapsed .nav-item{justify-content:center;padding-inline:0}.content{flex:1;min-width:0;padding:28px 28px 64px;display:flex;flex-direction:column;gap:14px}.page-head{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:46px;padding:7px 16px;border:1px solid var(--ac-border);border-radius:12px;background:var(--ac-surface);box-shadow:var(--ns-shadow-1)}.page-head-main{display:flex;min-width:0;flex:1;align-items:center;gap:14px}.page-head-actions{display:flex;flex:none;align-items:center;gap:8px}.page-head h1{margin:0;font-size:19px;font-weight:var(--ns-weight-heading)}.measure{display:flex;width:100%;max-width:var(--ac-content-max, 1440px);flex-direction:column;gap:14px;margin-inline:0}h1{margin:0;font-size:26px;line-height:1.2;font-weight:var(--ns-weight-emphasis);letter-spacing:-.02em}.access-menu{display:flex;flex-direction:column;gap:.15rem;margin-top:.75rem;padding-top:.75rem;border-top:1px solid var(--ns-frame-line)}.access-caption{margin:0 0 .4rem;padding:0 .75rem;color:var(--ns-frame-muted);font-size:.68rem;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.access-state{margin:0;padding:.35rem .75rem;color:var(--ns-frame-muted);font-size:.78rem}.access-state.is-error{color:var(--p-red-400, #f87171)}.nav-item.is-child{padding-left:2.1rem;font-size:.86rem}@media(max-width:720px){.sidebar{max-width:none;position:fixed;top:var(--ns-topbar-h, 56px);bottom:0;left:0;z-index:30;width:268px;max-width:82vw;overflow-y:auto;box-shadow:0 18px 44px #00000073;transform:translate(-100%);transition:transform .18s ease}.sidebar.is-collapsed{width:268px;max-width:82vw;transform:translate(-100%)}.sidebar:not(.is-collapsed){transform:translate(0)}.sidebar.is-collapsed .nav-label{display:inline}.sidebar.is-collapsed .role-text{display:flex}.sidebar.is-collapsed .nav-item,.sidebar.is-collapsed .role-badge{justify-content:flex-start;padding-inline:12px}.brand-secondary{display:none}.topbar{height:auto;min-height:56px;flex-wrap:wrap;padding-bottom:8px;row-gap:8px}.context{order:3;width:100%;margin-left:0}.context-select{min-width:0;max-width:none;flex:1 1 0}.content{padding:20px 16px 48px}h1{font-size:22px}.page-head{gap:10px;min-height:42px;padding:7px 12px}.page-head-main{gap:8px}.page-head h1{overflow:hidden;min-width:0;font-size:16px;text-overflow:ellipsis;white-space:nowrap}.page-head-actions{flex-wrap:wrap;justify-content:flex-end;gap:6px}.page-head-actions ::ng-deep .p-button{padding-block:6px;padding-inline:11px;font-size:13px;white-space:nowrap}.page-head-actions ::ng-deep .p-button-icon{font-size:13px}}.who{display:flex;align-items:center;gap:12px;margin:6px 6px 0;padding:12px;border-radius:10px;background:var(--ac-text);color:var(--ac-surface)}.who-photo{width:42px;height:42px;flex:none;border-radius:999px;object-fit:cover}.who-initials{display:inline-flex;align-items:center;justify-content:center;background:var(--ac-accent);color:var(--ac-on-accent);font-size:15px;font-weight:var(--ns-weight-emphasis)}.who-text{display:flex;min-width:0;flex-direction:column}.who-name{overflow:hidden;font-size:14px;font-weight:var(--ns-weight-emphasis);text-overflow:ellipsis;white-space:nowrap}.who-mail{overflow:hidden;color:color-mix(in srgb,currentColor 64%,transparent);font-size:12px;text-overflow:ellipsis;white-space:nowrap}.who-role{display:flex;align-items:center;gap:7px;margin:0;overflow:hidden;padding:11px 17px 5px;color:var(--ac-text-muted);font-size:12px;white-space:nowrap}.who-role b{flex:none;color:var(--ac-text);font-size:12px;font-weight:var(--ns-weight-emphasis)}.who-sep{flex:none}.who-context{overflow:hidden;text-overflow:ellipsis}.who-dot{width:7px;height:7px;flex:none;border-radius:50%;background:var(--ns-success)}.company-option{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%}.company-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.launcher-notice{display:flex;gap:10px;margin:12px 12px 0;padding:12px;border:1px solid color-mix(in srgb,var(--ac-accent) 40%,transparent);border-radius:8px;background:color-mix(in srgb,var(--ac-accent) 10%,transparent)}.launcher-notice i{margin-top:2px;color:var(--ac-accent);font-size:15px}.launcher-notice-title{margin:0 0 4px;font-size:13px;font-weight:var(--ns-weight-emphasis)}.launcher-notice-body{margin:0;color:var(--ac-text-muted);font-size:12px;line-height:1.45}.confirm{display:flex;flex-direction:column;align-items:center;gap:6px;padding:26px 24px 20px;border:1px solid var(--ac-border);border-radius:14px;background:var(--ac-surface);text-align:center}.confirm h2{margin:8px 0 0;font-size:17px;font-weight:var(--ns-weight-heading)}.confirm p{margin:0;max-width:34ch;color:var(--ac-text-muted);font-size:13px;line-height:1.5}.confirm-actions{display:flex;justify-content:center;gap:8px;margin-top:18px}.toast-text{flex:1;margin-left:12px}.toast-summary{margin:0;font-size:13px;font-weight:var(--ns-weight-emphasis)}.toast-detail{margin:2px 0 0;color:var(--ac-text-muted);font-size:12px}.context{display:flex;min-width:0;align-items:center;gap:8px;margin-left:14px}.context-select{min-width:150px;max-width:210px}.role-badge{display:flex;align-items:center;gap:12px;padding:4px 12px 2px}.role-badge>i{flex:none;color:var(--ns-frame-muted);font-size:14px}.role-text{display:flex;min-width:0;flex-direction:column;gap:1px}.role-name{overflow:hidden;color:var(--ns-frame-ink);font-size:13px;font-weight:var(--ns-weight-emphasis);text-overflow:ellipsis;white-space:nowrap}.role-caption{color:var(--ns-frame-muted);font-size:10px;letter-spacing:.06em;text-transform:uppercase}.sidebar.is-collapsed .role-badge{justify-content:center;padding-inline:0}.sidebar-scrim{position:fixed;top:var(--ns-topbar-h, 56px);right:0;bottom:0;left:0;z-index:29;padding:0;border:0;background:#00000073;cursor:pointer}.nav-skeleton{display:flex;flex-direction:column;gap:3px}.nav-skeleton-item{display:flex;align-items:center;gap:12px;padding:11px 12px}.sidebar.is-collapsed .nav-skeleton-item .p-skeleton:last-child{display:none}\n"] }]
|
|
3906
4306
|
}], ctorParameters: () => [], propDecorators: { brand: [{ type: i0.Input, args: [{ isSignal: true, alias: "brand", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], navItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "navItems", required: false }] }], activeNavId: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeNavId", required: false }] }], selectedMenuId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedMenuId", required: false }] }], navSelect: [{ type: i0.Output, args: ["navSelect"] }], menuSelect: [{ type: i0.Output, args: ["menuSelect"] }] } });
|
|
4307
|
+
function shortAppName(name) {
|
|
4308
|
+
if (!name.startsWith(SUITE_PREFIX))
|
|
4309
|
+
return name;
|
|
4310
|
+
return name.slice(SUITE_PREFIX.length).trim() || name;
|
|
4311
|
+
}
|
|
3907
4312
|
function initialsOf(source) {
|
|
3908
4313
|
const parts = source.trim().split(/\s+/).filter(Boolean);
|
|
3909
4314
|
if (!parts.length)
|
|
@@ -3935,5 +4340,5 @@ function homeNode(route, label) {
|
|
|
3935
4340
|
* Generated bundle index. Do not edit.
|
|
3936
4341
|
*/
|
|
3937
4342
|
|
|
3938
|
-
export { ACCENTS, CANVASES, COMMON_COPY, CONTROL_CONTRAST, DEFAULT_APPEARANCE, DENSITIES, EMPTY_GEO_VALUE, FIELD_TARGETS, FRAMES, GEO_COPY, LEGACY_THEMES, NO_PERMISSIONS, NUCLEUS_ACCENTS, NUCLEUS_CONFIG, NUCLEUS_DARK_SELECTOR, NUCLEUS_FORCE_BEARER, NUCLEUS_HOME, NUCLEUS_ICONS, NUCLEUS_ICON_CATALOG, NUCLEUS_LANGS, NUCLEUS_LOGOUT_PARAM, NUCLEUS_SKIP_AUTH, NucleusAppearance, NucleusAuth, NucleusCache, NucleusCard, NucleusCell, NucleusColorPicker, NucleusEnterAdvance, NucleusFeedback, NucleusForm, NucleusGeo, NucleusGeoSelect, NucleusIconPicker, NucleusLanguage, NucleusList, NucleusLordicon, NucleusMark, NucleusMenu, NucleusMetric, NucleusMetrics, NucleusPage, NucleusPageActions, NucleusPreset, NucleusRecentApps, NucleusSessionAuth, NucleusShell, NucleusShortcut, NucleusShortcuts, NucleusStarfield, NucleusTabs, SHELL_COPY, SessionService, TEXT_CONTRAST, THEME_COPY, ThemeService, UserSyncService, accentById, accentLabelOf, accentOn, ariaKeysOf, auditAppearance, canvasById, clock, comboOf, commonCopyOf, consumeNucleusLogout, contrastIssue, contrastRatio, day, densityById, endOfDayUtc, fieldsIn, findMenuByRoute, flagOf, foldText, frameById, geoCopyOf, hasChildren, hasModifier, iconClassOf, iconNameOf, integer, isAccentPreference, isApplePlatform, isBeforeToday, isCanvasPreference, isDarkCanvas, isDensityId, isFieldSearchable, isFrameId, isHomeRoute, isNucleusConfigured, isOnOrBeforeToday, isReachable, isToday, isTypingTarget, isUnderRoute, isoDay, levelLabel, loadLordicon, loadNucleusConfig, matchMenuByRoute, matchesRow, meetsContrast, menuGlyph, menuTile, minutesAsClock, mixHex, money, moveTo, normalizeHomeRoute, normalizeKeys, nucleusAccessGuard, nucleusAuthInterceptor, nucleusErrorMessage, nucleusLang, nucleusLogoutUrl, nucleusParseDate, ownsUrl, percent, permissionsOf, provideNucleus, provideNucleusFeedback, provideNucleusHome, provideNucleusTheme, qty, readableOn, relativeLuminance, resolveAccent, resolveFieldSize, routePath, searchIcons, selectableRows, shiftDay, shortcutHint, signedMoney, stamp, startOfDayUtc, themeCopyOf, toNumber, toggleCollapsed, visibleTreeRows };
|
|
4343
|
+
export { ACCENTS, CANVASES, COMMON_COPY, CONTROL_CONTRAST, DEFAULT_APPEARANCE, DENSITIES, EMPTY_GEO_VALUE, FIELD_TARGETS, FRAMES, GEO_COPY, LEGACY_THEMES, NO_PERMISSIONS, NUCLEUS_ACCENTS, NUCLEUS_CONFIG, NUCLEUS_DARK_SELECTOR, NUCLEUS_FORCE_BEARER, NUCLEUS_HOME, NUCLEUS_ICONS, NUCLEUS_ICON_CATALOG, NUCLEUS_LANGS, NUCLEUS_LOGOUT_PARAM, NUCLEUS_NARROW_QUERY, NUCLEUS_SKIP_AUTH, NucleusAppearance, NucleusAuth, NucleusBytes, NucleusCache, NucleusCard, NucleusCell, NucleusColorPicker, NucleusCompact, NucleusEnterAdvance, NucleusFeedback, NucleusForm, NucleusGeo, NucleusGeoSelect, NucleusIconPicker, NucleusLanguage, NucleusLink, NucleusList, NucleusLordicon, NucleusMark, NucleusMegabytes, NucleusMenu, NucleusMetric, NucleusMetrics, NucleusPage, NucleusPageActions, NucleusPreset, NucleusRecentApps, NucleusSessionAuth, NucleusShell, NucleusShortcut, NucleusShortcuts, NucleusStarfield, NucleusTabs, NucleusViewport, SHELL_COPY, SessionService, TEXT_CONTRAST, THEME_COPY, ThemeService, UserSyncService, accentById, accentLabelOf, accentOn, ariaKeysOf, auditAppearance, canvasById, clock, comboOf, commonCopyOf, compactBytes, compactMegabytes, compactNumber, consumeNucleusLogout, contrastIssue, contrastRatio, day, densityById, endOfDayUtc, fieldsIn, findMenuByRoute, flagOf, foldText, frameById, geoCopyOf, hasChildren, hasModifier, iconClassOf, iconNameOf, integer, isAccentPreference, isApplePlatform, isBeforeToday, isCanvasPreference, isDarkCanvas, isDensityId, isFieldSearchable, isFrameId, isHomeRoute, isNucleusConfigured, isOnOrBeforeToday, isReachable, isToday, isTypingTarget, isUnderRoute, isoDay, levelLabel, loadLordicon, loadNucleusConfig, matchMenuByRoute, matchesRow, meetsContrast, menuGlyph, menuTile, minutesAsClock, mixHex, money, moveTo, normalizeHomeRoute, normalizeKeys, nucleusAccessGuard, nucleusAuthInterceptor, nucleusErrorMessage, nucleusLang, nucleusLogoutUrl, nucleusParseDate, ownsUrl, percent, permissionsOf, provideNucleus, provideNucleusFeedback, provideNucleusHome, provideNucleusTheme, qty, readableOn, relativeLuminance, resolveAccent, resolveFieldSize, routePath, searchIcons, selectableRows, shiftDay, shortcutHint, signedMoney, stamp, startOfDayUtc, themeCopyOf, toNumber$1 as toNumber, toggleCollapsed, visibleTreeRows };
|
|
3939
4344
|
//# sourceMappingURL=nucleus-suite-pe-core.mjs.map
|