@nucleus-suite-pe/core 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/nucleus-suite-pe-core-charts.mjs +256 -0
- package/fesm2022/nucleus-suite-pe-core-charts.mjs.map +1 -0
- package/fesm2022/nucleus-suite-pe-core.mjs +69 -25
- package/fesm2022/nucleus-suite-pe-core.mjs.map +1 -1
- package/package.json +12 -2
- package/styles/tokens.css +11 -2
- package/types/nucleus-suite-pe-core-charts.d.ts +129 -0
- package/types/nucleus-suite-pe-core.d.ts +22 -8
|
@@ -1,7 +1,7 @@
|
|
|
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, viewChild, output, afterNextRender,
|
|
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';
|
|
3
3
|
import { HttpContextToken, HttpClient, HttpContext, HttpErrorResponse } from '@angular/common/http';
|
|
4
|
-
import { firstValueFrom,
|
|
4
|
+
import { firstValueFrom, from, switchMap, catchError, throwError } from 'rxjs';
|
|
5
5
|
import { DOCUMENT, NgTemplateOutlet } from '@angular/common';
|
|
6
6
|
import * as i1 from '@angular/forms';
|
|
7
7
|
import { FormsModule } from '@angular/forms';
|
|
@@ -90,11 +90,19 @@ class NucleusSessionAuth {
|
|
|
90
90
|
injector = inject(Injector);
|
|
91
91
|
_ticket = signal(null, ...(ngDevMode ? [{ debugName: "_ticket" }] : /* istanbul ignore next */ []));
|
|
92
92
|
_failed = signal(false, ...(ngDevMode ? [{ debugName: "_failed" }] : /* istanbul ignore next */ []));
|
|
93
|
+
_usable = signal(true, ...(ngDevMode ? [{ debugName: "_usable" }] : /* istanbul ignore next */ []));
|
|
93
94
|
pending = null;
|
|
94
95
|
ticket = this._ticket.asReadonly();
|
|
95
96
|
failed = this._failed.asReadonly();
|
|
96
|
-
established = computed(() => this._ticket() !== null, ...(ngDevMode ? [{ debugName: "established" }] : /* istanbul ignore next */ []));
|
|
97
|
+
established = computed(() => this._usable() && this._ticket() !== null, ...(ngDevMode ? [{ debugName: "established" }] : /* istanbul ignore next */ []));
|
|
98
|
+
usable = this._usable.asReadonly();
|
|
99
|
+
disable() {
|
|
100
|
+
this._usable.set(false);
|
|
101
|
+
this._ticket.set(null);
|
|
102
|
+
}
|
|
97
103
|
establish(force = false) {
|
|
104
|
+
if (!this._usable())
|
|
105
|
+
return Promise.resolve(false);
|
|
98
106
|
if (!force && this._ticket() !== null)
|
|
99
107
|
return Promise.resolve(true);
|
|
100
108
|
this.pending ??= this.request().finally(() => {
|
|
@@ -105,6 +113,7 @@ class NucleusSessionAuth {
|
|
|
105
113
|
async clear() {
|
|
106
114
|
this._ticket.set(null);
|
|
107
115
|
this._failed.set(false);
|
|
116
|
+
this._usable.set(true);
|
|
108
117
|
if (!isNucleusConfigured(this.config))
|
|
109
118
|
return;
|
|
110
119
|
try {
|
|
@@ -154,18 +163,26 @@ const nucleusAuthInterceptor = (req, next) => {
|
|
|
154
163
|
const session = inject(NucleusSessionAuth);
|
|
155
164
|
const auth = inject(NucleusAuth, { optional: true });
|
|
156
165
|
const request = req.clone({ withCredentials: true });
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
166
|
+
const withBearer = () => {
|
|
167
|
+
if (!auth)
|
|
168
|
+
return next(request);
|
|
169
|
+
return from(auth.idToken()).pipe(switchMap((token) => next(token ? request.clone({ setHeaders: { Authorization: `Bearer ${token}` } }) : request)));
|
|
170
|
+
};
|
|
171
|
+
if (req.context.get(NUCLEUS_FORCE_BEARER) || !session.established()) {
|
|
172
|
+
return withBearer();
|
|
173
|
+
}
|
|
174
|
+
return next(request).pipe(catchError((error) => {
|
|
175
|
+
if (!(error instanceof HttpErrorResponse) || error.status !== 401) {
|
|
176
|
+
return throwError(() => error);
|
|
177
|
+
}
|
|
178
|
+
return from(session.establish(true)).pipe(switchMap((renewed) => (renewed ? next(request) : throwError(() => error))), catchError((retried) => {
|
|
179
|
+
if (!(retried instanceof HttpErrorResponse) || retried.status !== 401) {
|
|
180
|
+
return throwError(() => retried);
|
|
161
181
|
}
|
|
162
|
-
|
|
182
|
+
session.disable();
|
|
183
|
+
return withBearer();
|
|
163
184
|
}));
|
|
164
|
-
}
|
|
165
|
-
if (!auth) {
|
|
166
|
-
return next(request);
|
|
167
|
-
}
|
|
168
|
-
return from(auth.idToken()).pipe(switchMap((token) => next(token ? request.clone({ setHeaders: { Authorization: `Bearer ${token}` } }) : request)));
|
|
185
|
+
}));
|
|
169
186
|
};
|
|
170
187
|
|
|
171
188
|
const NUCLEUS_LOGOUT_PARAM = 'nucleus_logout';
|
|
@@ -2386,11 +2403,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
2386
2403
|
|
|
2387
2404
|
class NucleusPage {
|
|
2388
2405
|
heading = signal('', ...(ngDevMode ? [{ debugName: "heading" }] : /* istanbul ignore next */ []));
|
|
2389
|
-
lead = signal('', ...(ngDevMode ? [{ debugName: "lead" }] : /* istanbul ignore next */ []));
|
|
2390
2406
|
crumbs = signal([], ...(ngDevMode ? [{ debugName: "crumbs" }] : /* istanbul ignore next */ []));
|
|
2391
|
-
|
|
2407
|
+
actions = signal(null, ...(ngDevMode ? [{ debugName: "actions" }] : /* istanbul ignore next */ []));
|
|
2408
|
+
set(heading, crumbs = []) {
|
|
2392
2409
|
this.heading.set(heading);
|
|
2393
|
-
this.lead.set(lead);
|
|
2394
2410
|
this.crumbs.set(crumbs);
|
|
2395
2411
|
}
|
|
2396
2412
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusPage, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -2401,6 +2417,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
2401
2417
|
args: [{ providedIn: 'root' }]
|
|
2402
2418
|
}] });
|
|
2403
2419
|
|
|
2420
|
+
class NucleusPageActions {
|
|
2421
|
+
page = inject(NucleusPage);
|
|
2422
|
+
template = inject(TemplateRef);
|
|
2423
|
+
constructor() {
|
|
2424
|
+
this.page.actions.set(this.template);
|
|
2425
|
+
}
|
|
2426
|
+
ngOnDestroy() {
|
|
2427
|
+
if (this.page.actions() === this.template)
|
|
2428
|
+
this.page.actions.set(null);
|
|
2429
|
+
}
|
|
2430
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusPageActions, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2431
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: NucleusPageActions, isStandalone: true, selector: "[nucleusPageActions]", ngImport: i0 });
|
|
2432
|
+
}
|
|
2433
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusPageActions, decorators: [{
|
|
2434
|
+
type: Directive,
|
|
2435
|
+
args: [{
|
|
2436
|
+
selector: '[nucleusPageActions]',
|
|
2437
|
+
}]
|
|
2438
|
+
}], ctorParameters: () => [] });
|
|
2439
|
+
|
|
2404
2440
|
function provideNucleusFeedback() {
|
|
2405
2441
|
return makeEnvironmentProviders([ConfirmationService, MessageService]);
|
|
2406
2442
|
}
|
|
@@ -2868,9 +2904,12 @@ class NucleusList {
|
|
|
2868
2904
|
minWidth = input('640px', ...(ngDevMode ? [{ debugName: "minWidth" }] : /* istanbul ignore next */ []));
|
|
2869
2905
|
skeletonRows = input(5, ...(ngDevMode ? [{ debugName: "skeletonRows" }] : /* istanbul ignore next */ []));
|
|
2870
2906
|
rowClass = input(() => '', ...(ngDevMode ? [{ debugName: "rowClass" }] : /* istanbul ignore next */ []));
|
|
2907
|
+
pageSize = input(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
|
|
2908
|
+
pageSizes = input([5, 10, 20, 25], ...(ngDevMode ? [{ debugName: "pageSizes" }] : /* istanbul ignore next */ []));
|
|
2871
2909
|
action = output();
|
|
2872
2910
|
toggle = output();
|
|
2873
2911
|
cells = contentChildren(NucleusCell, ...(ngDevMode ? [{ debugName: "cells" }] : /* istanbul ignore next */ []));
|
|
2912
|
+
paginate = computed(() => !this.loading(), ...(ngDevMode ? [{ debugName: "paginate" }] : /* istanbul ignore next */ []));
|
|
2874
2913
|
tableStyle = computed(() => ({ 'min-width': this.minWidth() }), ...(ngDevMode ? [{ debugName: "tableStyle" }] : /* istanbul ignore next */ []));
|
|
2875
2914
|
showEmpty = computed(() => !this.loading() && this.rows().length === 0, ...(ngDevMode ? [{ debugName: "showEmpty" }] : /* istanbul ignore next */ []));
|
|
2876
2915
|
placeholders = computed(() => Array.from({ length: Math.max(this.skeletonRows(), 1) }, (_, index) => ({ index })), ...(ngDevMode ? [{ debugName: "placeholders" }] : /* istanbul ignore next */ []));
|
|
@@ -2920,12 +2959,12 @@ class NucleusList {
|
|
|
2920
2959
|
this.toggle.emit({ key: column.key, row, value: !this.isChecked(column, row) });
|
|
2921
2960
|
}
|
|
2922
2961
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusList, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2923
|
-
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 } }, 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 [value]=\"data()\" styleClass=\"ns-table\" [tableStyle]=\"tableStyle()\">\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;min-height:34px;align-items:center;justify-content:space-between;gap:12px;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 });
|
|
2962
|
+
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 });
|
|
2924
2963
|
}
|
|
2925
2964
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusList, decorators: [{
|
|
2926
2965
|
type: Component,
|
|
2927
|
-
args: [{ selector: 'nucleus-list', imports: [NgTemplateOutlet, ButtonModule, SkeletonModule, TableModule, TagModule, TooltipModule], 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 <p-table
|
|
2928
|
-
}], 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 }] }], action: [{ type: i0.Output, args: ["action"] }], toggle: [{ type: i0.Output, args: ["toggle"] }], cells: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => NucleusCell), { isSignal: true }] }] } });
|
|
2966
|
+
args: [{ selector: 'nucleus-list', imports: [NgTemplateOutlet, ButtonModule, SkeletonModule, TableModule, TagModule, TooltipModule], 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 <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"] }]
|
|
2967
|
+
}], 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 }] }], action: [{ type: i0.Output, args: ["action"] }], toggle: [{ type: i0.Output, args: ["toggle"] }], cells: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => NucleusCell), { isSignal: true }] }] } });
|
|
2929
2968
|
|
|
2930
2969
|
function toggleCollapsed(collapsed, id) {
|
|
2931
2970
|
const next = new Set(collapsed);
|
|
@@ -3416,7 +3455,6 @@ class NucleusShell {
|
|
|
3416
3455
|
router = inject(Router);
|
|
3417
3456
|
brand = input('SUITE', ...(ngDevMode ? [{ debugName: "brand" }] : /* istanbul ignore next */ []));
|
|
3418
3457
|
heading = input('', ...(ngDevMode ? [{ debugName: "heading" }] : /* istanbul ignore next */ []));
|
|
3419
|
-
lead = input('', ...(ngDevMode ? [{ debugName: "lead" }] : /* istanbul ignore next */ []));
|
|
3420
3458
|
navItems = input([], ...(ngDevMode ? [{ debugName: "navItems" }] : /* istanbul ignore next */ []));
|
|
3421
3459
|
activeNavId = input(null, ...(ngDevMode ? [{ debugName: "activeNavId" }] : /* istanbul ignore next */ []));
|
|
3422
3460
|
selectedMenuId = input(null, ...(ngDevMode ? [{ debugName: "selectedMenuId" }] : /* istanbul ignore next */ []));
|
|
@@ -3426,7 +3464,7 @@ class NucleusShell {
|
|
|
3426
3464
|
icons = NUCLEUS_ICONS;
|
|
3427
3465
|
menuPlaceholders = ['64%', '80%', '52%', '72%', '58%'];
|
|
3428
3466
|
title = computed(() => this.heading() || this.page.heading(), ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
3429
|
-
|
|
3467
|
+
pageActions = this.page.actions;
|
|
3430
3468
|
home = computed(() => ({ icon: 'pi pi-home', routerLink: '/' }), ...(ngDevMode ? [{ debugName: "home" }] : /* istanbul ignore next */ []));
|
|
3431
3469
|
crumbs = computed(() => this.page.crumbs().map((crumb) => ({
|
|
3432
3470
|
label: crumb.label,
|
|
@@ -3680,6 +3718,11 @@ class NucleusShell {
|
|
|
3680
3718
|
if (!this.canOpen(app))
|
|
3681
3719
|
return;
|
|
3682
3720
|
this.recents.remember(app.id);
|
|
3721
|
+
const target = new URL(app.url, window.location.origin);
|
|
3722
|
+
if (target.origin === window.location.origin) {
|
|
3723
|
+
void this.router.navigateByUrl(target.pathname + target.search);
|
|
3724
|
+
return;
|
|
3725
|
+
}
|
|
3683
3726
|
window.location.href = app.url;
|
|
3684
3727
|
}
|
|
3685
3728
|
appInitials(app) {
|
|
@@ -3724,11 +3767,12 @@ class NucleusShell {
|
|
|
3724
3767
|
}
|
|
3725
3768
|
}
|
|
3726
3769
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusShell, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3727
|
-
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 }, lead: { classPropertyName: "lead", publicName: "lead", 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) {\n <p-breadcrumb [model]=\"crumbs()\" [home]=\"home()\" styleClass=\"ns-crumbs\" />\n }\n\n @if (title()) {\n <h1>{{ title() }}</h1>\n }\n @if (subtitle()) {\n <p class=\"lead\">{{ subtitle() }}</p>\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}.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}.lead{margin:0;font-size:14px;line-height:1.6;font-weight:300;color:var(--ac-text-muted)}.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}}.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: "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 });
|
|
3770
|
+
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 });
|
|
3728
3771
|
}
|
|
3729
3772
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: NucleusShell, decorators: [{
|
|
3730
3773
|
type: Component,
|
|
3731
3774
|
args: [{ selector: 'nucleus-shell', imports: [
|
|
3775
|
+
NgTemplateOutlet,
|
|
3732
3776
|
AvatarModule,
|
|
3733
3777
|
BreadcrumbModule,
|
|
3734
3778
|
ButtonModule,
|
|
@@ -3746,8 +3790,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
3746
3790
|
NucleusMenu,
|
|
3747
3791
|
NucleusMark,
|
|
3748
3792
|
NucleusStarfield,
|
|
3749
|
-
], 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) {\n <p-breadcrumb [model]=\"crumbs()\" [home]=\"home()\" styleClass=\"ns-crumbs\" />\n }\n\n @if (title()) {\n <h1>{{ title() }}</h1>\n }\n @if (subtitle()) {\n <p class=\"lead\">{{ subtitle() }}</p>\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}.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}.lead{margin:0;font-size:14px;line-height:1.6;font-weight:300;color:var(--ac-text-muted)}.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}}.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"] }]
|
|
3750
|
-
}], ctorParameters: () => [], propDecorators: { brand: [{ type: i0.Input, args: [{ isSignal: true, alias: "brand", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }],
|
|
3793
|
+
], 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"] }]
|
|
3794
|
+
}], 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"] }] } });
|
|
3751
3795
|
function initialsOf(source) {
|
|
3752
3796
|
const parts = source.trim().split(/\s+/).filter(Boolean);
|
|
3753
3797
|
if (!parts.length)
|
|
@@ -3761,5 +3805,5 @@ function initialsOf(source) {
|
|
|
3761
3805
|
* Generated bundle index. Do not edit.
|
|
3762
3806
|
*/
|
|
3763
3807
|
|
|
3764
|
-
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_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, 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, isNucleusConfigured, isOnOrBeforeToday, isReachable, isToday, isTypingTarget, isoDay, levelLabel, loadLordicon, loadNucleusConfig, matchesRow, meetsContrast, menuGlyph, menuTile, minutesAsClock, mixHex, money, moveTo, normalizeKeys, nucleusAuthInterceptor, nucleusErrorMessage, nucleusLang, nucleusLogoutUrl, nucleusParseDate, ownsUrl, percent, permissionsOf, provideNucleus, provideNucleusFeedback, provideNucleusTheme, qty, readableOn, relativeLuminance, resolveAccent, resolveFieldSize, searchIcons, selectableRows, shiftDay, shortcutHint, signedMoney, stamp, startOfDayUtc, themeCopyOf, toNumber, toggleCollapsed, visibleTreeRows };
|
|
3808
|
+
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_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, isNucleusConfigured, isOnOrBeforeToday, isReachable, isToday, isTypingTarget, isoDay, levelLabel, loadLordicon, loadNucleusConfig, matchesRow, meetsContrast, menuGlyph, menuTile, minutesAsClock, mixHex, money, moveTo, normalizeKeys, nucleusAuthInterceptor, nucleusErrorMessage, nucleusLang, nucleusLogoutUrl, nucleusParseDate, ownsUrl, percent, permissionsOf, provideNucleus, provideNucleusFeedback, provideNucleusTheme, qty, readableOn, relativeLuminance, resolveAccent, resolveFieldSize, searchIcons, selectableRows, shiftDay, shortcutHint, signedMoney, stamp, startOfDayUtc, themeCopyOf, toNumber, toggleCollapsed, visibleTreeRows };
|
|
3765
3809
|
//# sourceMappingURL=nucleus-suite-pe-core.mjs.map
|