@ardimedia/angular-portal-azure 0.3.0 → 0.3.3

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.
@@ -204,6 +204,7 @@ function createAvatarMenu() {
204
204
  return {
205
205
  userAccount: { userName: '', firstName: '', lastName: '' },
206
206
  isOpen: false,
207
+ items: [],
207
208
  };
208
209
  }
209
210
 
@@ -338,6 +339,10 @@ class PortalService {
338
339
  closeAvatarMenu() {
339
340
  this.avatarMenu.update((m) => ({ ...m, isOpen: false }));
340
341
  }
342
+ /** Set avatar menu items */
343
+ setAvatarMenuItems(items) {
344
+ this.avatarMenu.update((m) => ({ ...m, items }));
345
+ }
341
346
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PortalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
342
347
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PortalService, providedIn: 'root' });
343
348
  }
@@ -609,7 +614,7 @@ class PanoramaComponent {
609
614
  <header class="fxs-part-title" style="color:var(--apa-text)">
610
615
  <h3 class="msportalfx-tooltip-overflow">Keine Applikationen zugeordnet</h3>
611
616
  <p class="msportalfx-tooltip-overflow" style="margin:0;padding:0">
612
- Wenden Sie sich bitte an den Administrator damit die entsprechenden Applikationen zugeordnet werden koennen.
617
+ Wende dich bitte an den Administrator, damit die Applikationen zugeordnet werden können.
613
618
  </p>
614
619
  </header>
615
620
  </div>
@@ -637,7 +642,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
637
642
  <header class="fxs-part-title" style="color:var(--apa-text)">
638
643
  <h3 class="msportalfx-tooltip-overflow">Keine Applikationen zugeordnet</h3>
639
644
  <p class="msportalfx-tooltip-overflow" style="margin:0;padding:0">
640
- Wenden Sie sich bitte an den Administrator damit die entsprechenden Applikationen zugeordnet werden koennen.
645
+ Wende dich bitte an den Administrator, damit die Applikationen zugeordnet werden können.
641
646
  </p>
642
647
  </header>
643
648
  </div>
@@ -707,6 +712,12 @@ class PortalLayoutComponent {
707
712
  const account = this.portal.avatarMenu().userAccount;
708
713
  return getUserDisplayName(account);
709
714
  }
715
+ initials() {
716
+ const a = this.portal.avatarMenu().userAccount;
717
+ const f = (a.firstName || '')[0] || '';
718
+ const l = (a.lastName || '')[0] || '';
719
+ return (f + l).toUpperCase() || '?';
720
+ }
710
721
  notificationMargin() {
711
722
  const notif = this.portal.notification();
712
723
  return notif.isVisible ? notif.width : 0;
@@ -750,7 +761,7 @@ class PortalLayoutComponent {
750
761
  scrollContainer.scrollTo({ left: targetScroll, behavior: 'smooth' });
751
762
  }
752
763
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PortalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
753
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.5", type: PortalLayoutComponent, isStandalone: true, selector: "apa-portal-layout", ngImport: i0, template: `
764
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: PortalLayoutComponent, isStandalone: true, selector: "apa-portal-layout", ngImport: i0, template: `
754
765
  <div class="fxs-portal fxs-theme-blue">
755
766
  <!-- Top bar -->
756
767
  <div class="fxs-topbar">
@@ -766,11 +777,28 @@ class PortalLayoutComponent {
766
777
  [attr.title]="isDark() ? 'Light mode' : 'Dark mode'">
767
778
  <i [class]="isDark() ? 'ti ti-sun' : 'ti ti-moon'"></i>
768
779
  </button>
769
- <div class="fxs-avatarmenu-tenant-container">
770
- <a class="fxs-has-hover" (click)="portal.toggleAvatarMenu()">
771
- <span>{{ displayName() }}</span><br />
772
- <span>{{ portal.avatarMenu().userAccount.userName }}</span>
780
+ <div class="fxs-avatarmenu-tenant-container" style="position:relative;">
781
+ <a class="apa-avatar-trigger fxs-has-hover" (click)="portal.toggleAvatarMenu()">
782
+ <span class="apa-avatar-initials">{{ initials() }}</span>
783
+ <span class="apa-avatar-info">
784
+ <span class="apa-avatar-name">{{ displayName() }}</span>
785
+ <span class="apa-avatar-email">{{ portal.avatarMenu().userAccount.userName }}</span>
786
+ </span>
787
+ <i class="ti" [class.ti-chevron-down]="!portal.avatarMenu().isOpen"
788
+ [class.ti-chevron-up]="portal.avatarMenu().isOpen"></i>
773
789
  </a>
790
+ @if (portal.avatarMenu().isOpen && portal.avatarMenu().items.length > 0) {
791
+ <div class="apa-avatar-dropdown">
792
+ @for (item of portal.avatarMenu().items; track item.href) {
793
+ <a class="apa-avatar-dropdown-item" [href]="item.href">
794
+ @if (item.icon) {
795
+ <i [class]="item.icon"></i>
796
+ }
797
+ <span>{{ item.label }}</span>
798
+ </a>
799
+ }
800
+ </div>
801
+ }
774
802
  </div>
775
803
  </div>
776
804
  </div>
@@ -805,11 +833,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
805
833
  [attr.title]="isDark() ? 'Light mode' : 'Dark mode'">
806
834
  <i [class]="isDark() ? 'ti ti-sun' : 'ti ti-moon'"></i>
807
835
  </button>
808
- <div class="fxs-avatarmenu-tenant-container">
809
- <a class="fxs-has-hover" (click)="portal.toggleAvatarMenu()">
810
- <span>{{ displayName() }}</span><br />
811
- <span>{{ portal.avatarMenu().userAccount.userName }}</span>
836
+ <div class="fxs-avatarmenu-tenant-container" style="position:relative;">
837
+ <a class="apa-avatar-trigger fxs-has-hover" (click)="portal.toggleAvatarMenu()">
838
+ <span class="apa-avatar-initials">{{ initials() }}</span>
839
+ <span class="apa-avatar-info">
840
+ <span class="apa-avatar-name">{{ displayName() }}</span>
841
+ <span class="apa-avatar-email">{{ portal.avatarMenu().userAccount.userName }}</span>
842
+ </span>
843
+ <i class="ti" [class.ti-chevron-down]="!portal.avatarMenu().isOpen"
844
+ [class.ti-chevron-up]="portal.avatarMenu().isOpen"></i>
812
845
  </a>
846
+ @if (portal.avatarMenu().isOpen && portal.avatarMenu().items.length > 0) {
847
+ <div class="apa-avatar-dropdown">
848
+ @for (item of portal.avatarMenu().items; track item.href) {
849
+ <a class="apa-avatar-dropdown-item" [href]="item.href">
850
+ @if (item.icon) {
851
+ <i [class]="item.icon"></i>
852
+ }
853
+ <span>{{ item.label }}</span>
854
+ </a>
855
+ }
856
+ </div>
857
+ }
813
858
  </div>
814
859
  </div>
815
860
  </div>
@@ -1 +1 @@
1
- {"version":3,"file":"ardimedia-angular-portal-azure.mjs","sources":["../../../../projects/ardimedia/angular-portal-azure/src/lib/models/status-bar.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/blade.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/blade-command.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/blade-data.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/blade-nav-item.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/tile-definition.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/user-account.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/notification.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/panorama.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/avatar-menu.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/filter.util.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/services/portal.service.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/services/blade.service.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/services/provide-portal-azure.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/tile/tile.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/panorama/panorama.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/portal-layout/portal-layout.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/command-bar/command-bar.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/blade/blade.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/blade-host/blade-host.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/blade-nav/blade-nav.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/blade-grid/blade-grid.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/blade-detail/blade-detail.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/notification-panel/notification-panel.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/avatar-menu/avatar-menu.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/sidebar/sidebar.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/public-api.ts","../../../../projects/ardimedia/angular-portal-azure/src/ardimedia-angular-portal-azure.ts"],"sourcesContent":["/**\n * Status bar display state for a blade.\n * Ported from UserControlBase.statusBar / statusBarClass in v0.2.346.\n */\nexport interface StatusBarState {\n /** Status bar text message */\n text: string;\n /** CSS class for styling (e.g. 'info', 'error', 'success') */\n style: StatusBarStyle;\n}\n\nexport type StatusBarStyle = 'none' | 'info' | 'error' | 'success' | 'warning';\n\nexport function clearStatusBar(): StatusBarState {\n return { text: '', style: 'none' };\n}\n\nexport function statusBarInfo(text: string): StatusBarState {\n return { text, style: 'info' };\n}\n\nexport function statusBarError(text: string): StatusBarState {\n return { text, style: 'error' };\n}\n\nexport function statusBarSuccess(text: string): StatusBarState {\n return { text, style: 'success' };\n}\n","import { BladeCommand } from './blade-command.model';\nimport { StatusBarState, clearStatusBar } from './status-bar.model';\n\n/**\n * Base blade definition used by BladeService to manage the blade stack.\n * Ported from Blade class in v0.2.346 — flattened from the UserControlBase → Blade hierarchy.\n *\n * In v0.2.346 this was a class with 18 command boolean groups and deep inheritance.\n * In v0.3.0 commands are a BladeCommand[] array and blade state is managed by the service.\n */\nexport interface BladeDefinition {\n /** Unique path identifying this blade (lowercased) */\n path: string;\n /** Blade header title */\n title: string;\n /** Blade header subtitle */\n subtitle: string;\n /** Blade width in pixels */\n width: number;\n /** Whether the blade content uses inner HTML (ng-content) vs structured content */\n isInnerHtml: boolean;\n /** Command bar buttons */\n commands: BladeCommand[];\n /** Status bar state */\n statusBar: StatusBarState;\n}\n\n/** Creates a blade definition with sensible defaults */\nexport function createBlade(path: string, title: string, width: number = 315): BladeDefinition {\n return {\n path: path.toLowerCase(),\n title,\n subtitle: '',\n width,\n isInnerHtml: true,\n commands: [],\n statusBar: clearStatusBar(),\n };\n}\n\n/**\n * Event args for blade navigation.\n * Ported from IAddBladeEventArgs in v0.2.346.\n */\nexport interface AddBladeEventArgs {\n path: string;\n pathSender: string;\n}\n","/**\n * Defines a command button in a blade's command bar.\n *\n * Replaces the 18 individual command boolean groups from v0.2.346.\n * Each command has visibility, enabled state, label text, icon, and action callback.\n */\nexport interface BladeCommand {\n /** Unique key identifying the command (e.g. 'save', 'delete', 'new') */\n key: string;\n /** Display text for the command button */\n label: string;\n /** Whether the command button is visible */\n visible: boolean;\n /** Whether the command button is enabled (clickable) */\n enabled: boolean;\n /** SVG icon identifier or CSS class for the command icon */\n icon?: string;\n /** Callback executed when the command is clicked */\n action: () => void;\n}\n\n/**\n * Standard command keys matching the 18 commands from v0.2.346:\n * browse, cancel, copy, delete, document, document2, document3, document4, document5,\n * new, order, restart, save, search, start, stop, swap, excel\n */\nexport type StandardCommandKey =\n | 'browse' | 'cancel' | 'copy' | 'delete'\n | 'document' | 'document2' | 'document3' | 'document4' | 'document5'\n | 'new' | 'order' | 'restart' | 'save' | 'search'\n | 'start' | 'stop' | 'swap' | 'excel';\n\n/** Creates a command with sensible defaults (visible, enabled, no-op action) */\nexport function createCommand(key: string, label: string, action: () => void, icon?: string): BladeCommand {\n return { key, label, visible: true, enabled: true, icon, action };\n}\n","import { BladeDefinition, createBlade } from './blade.model';\nimport { StatusBarState, statusBarInfo, statusBarError, statusBarSuccess, clearStatusBar } from './status-bar.model';\n\n/**\n * Exception model for API error responses.\n * Ported from Exception / ExceptionDotNet in v0.2.346.\n */\nexport interface ApiException {\n message: string;\n status?: number;\n statusText?: string;\n data?: Array<{ key: number; value: string }>;\n validationResults?: Array<{ errorMessage: string; memberNames: string[] }>;\n}\n\n/**\n * Lifecycle hooks for CRUD operations on a blade.\n * Ported from BladeData<T> template method pattern in v0.2.346.\n *\n * Each operation follows the pattern: onBefore → execute → onSuccess | onError\n */\nexport interface BladeDataLifecycle<T> {\n // Load single item\n onLoadItem?: () => void;\n onLoadedItem?: () => void;\n onLoadItemError?: (ex: ApiException) => void;\n\n // Load multiple items\n onLoadItems?: () => void;\n onLoadedItems?: () => void;\n onLoadItemsError?: (ex: ApiException) => void;\n\n // Save item\n onSaveItem?: () => void;\n onSavedItem?: () => void;\n onSaveItemError?: (ex: ApiException) => void;\n\n // Delete item\n onDeleteItem?: () => void;\n onDeletedItem?: () => boolean; // return false to prevent blade close\n onDeleteItemError?: (ex: ApiException) => void;\n\n // New item\n onNewItem?: () => void;\n onNewedItem?: () => void;\n onNewItemError?: (ex: ApiException) => void;\n\n // Execute generic action\n onExecute?: () => void;\n onExecuted?: () => void;\n onExecuteError?: (ex: ApiException) => void;\n\n // Form validation\n isFormValid?: () => boolean;\n}\n\n/**\n * Extended blade definition for data-driven blades with CRUD operations.\n * Ported from BladeData<T> in v0.2.346.\n */\nexport interface BladeDataDefinition<T> extends BladeDefinition {\n /** Current item being edited/viewed */\n item: T;\n /** List of items (for grid/list blades) */\n items: T[];\n /** Lifecycle hooks for CRUD operations */\n lifecycle: BladeDataLifecycle<T>;\n}\n\n/** Creates a data blade definition with sensible defaults */\nexport function createDataBlade<T>(\n path: string,\n title: string,\n width: number = 315,\n): BladeDataDefinition<T> {\n return {\n ...createBlade(path, title, width),\n item: {} as T,\n items: [],\n lifecycle: {},\n };\n}\n\n/**\n * Execute a load-item operation with lifecycle hooks and status bar updates.\n * Replaces the BladeData.loadItem() template method from v0.2.346.\n */\nexport async function executeLoadItem<T>(\n blade: BladeDataDefinition<T>,\n loadFn: () => Promise<T>,\n): Promise<T | void> {\n blade.lifecycle.onLoadItem?.();\n blade.statusBar = statusBarInfo('Laden...');\n try {\n const result = await loadFn();\n blade.item = result;\n blade.statusBar = clearStatusBar();\n blade.lifecycle.onLoadedItem?.();\n return result;\n } catch (ex) {\n blade.statusBar = statusBarError((ex as ApiException).message || 'Fehler beim Laden');\n blade.lifecycle.onLoadItemError?.(ex as ApiException);\n }\n}\n\n/**\n * Execute a load-items operation with lifecycle hooks and status bar updates.\n */\nexport async function executeLoadItems<T>(\n blade: BladeDataDefinition<T>,\n loadFn: () => Promise<T[]>,\n): Promise<T[] | void> {\n blade.lifecycle.onLoadItems?.();\n blade.statusBar = statusBarInfo('Laden...');\n try {\n const result = await loadFn();\n blade.items = result;\n blade.statusBar = clearStatusBar();\n blade.lifecycle.onLoadedItems?.();\n return result;\n } catch (ex) {\n blade.statusBar = statusBarError((ex as ApiException).message || 'Fehler beim Laden');\n blade.lifecycle.onLoadItemsError?.(ex as ApiException);\n }\n}\n\n/**\n * Execute a save-item operation with lifecycle hooks and status bar updates.\n */\nexport async function executeSaveItem<T>(\n blade: BladeDataDefinition<T>,\n saveFn: () => Promise<T>,\n): Promise<T | void> {\n if (blade.lifecycle.isFormValid && !blade.lifecycle.isFormValid()) {\n return;\n }\n blade.lifecycle.onSaveItem?.();\n blade.statusBar = statusBarInfo('Speichern...');\n try {\n const result = await saveFn();\n blade.item = result;\n blade.statusBar = statusBarSuccess('Gespeichert');\n blade.lifecycle.onSavedItem?.();\n return result;\n } catch (ex) {\n blade.statusBar = statusBarError((ex as ApiException).message || 'Fehler beim Speichern');\n blade.lifecycle.onSaveItemError?.(ex as ApiException);\n }\n}\n\n/**\n * Execute a delete-item operation with lifecycle hooks and status bar updates.\n * Returns true if the blade should be closed after deletion.\n */\nexport async function executeDeleteItem<T>(\n blade: BladeDataDefinition<T>,\n deleteFn: () => Promise<void>,\n): Promise<boolean> {\n blade.lifecycle.onDeleteItem?.();\n blade.statusBar = statusBarInfo('Loeschen...');\n try {\n await deleteFn();\n blade.statusBar = statusBarSuccess('Geloescht');\n const shouldClose = blade.lifecycle.onDeletedItem?.() ?? true;\n return shouldClose;\n } catch (ex) {\n blade.statusBar = statusBarError((ex as ApiException).message || 'Fehler beim Loeschen');\n blade.lifecycle.onDeleteItemError?.(ex as ApiException);\n return false;\n }\n}\n","/**\n * Navigation item displayed in a BladeNav component.\n * Ported from BladeNavItem in v0.2.346.\n */\nexport interface BladeNavItem {\n /** Display title */\n title: string;\n /** CSS class for the icon */\n cssClass?: string;\n /** Path of the blade to open when clicked */\n bladePath: string;\n /** External href link (alternative to bladePath) */\n hrefPath?: string;\n /** Comma-separated role names for visibility control */\n roles?: string;\n /** Whether this nav item is visible */\n isVisible: boolean;\n /** Optional callback executed on click (in addition to navigation) */\n callback?: () => void;\n}\n\nexport function createNavItem(title: string, bladePath: string, cssClass?: string): BladeNavItem {\n return { title, bladePath, cssClass, isVisible: true };\n}\n","/**\n * Tile size enum matching v0.2.346 TileSizes.\n * The names are used in CSS class names (e.g. 'fxs-tilesize-normal').\n */\nexport enum TileSize {\n Small = 'small',\n Mini = 'mini',\n Normal = 'normal',\n HeroWide = 'herowide',\n}\n\n/** Pixel dimensions for each tile size */\nexport const TILE_DIMENSIONS: Record<TileSize, { width: number; height: number }> = {\n [TileSize.Small]: { width: 90, height: 90 },\n [TileSize.Mini]: { width: 180, height: 90 },\n [TileSize.Normal]: { width: 180, height: 180 },\n [TileSize.HeroWide]: { width: 540, height: 360 },\n};\n\n/**\n * Tile definition for the panorama/startboard.\n * Ported from Tile in v0.2.346.\n */\nexport interface TileDefinition {\n /** Display title on the tile */\n title: string;\n /** Optional subtitle */\n subtitle?: string;\n /** Path of the blade to open when the tile is clicked */\n bladePath: string;\n /** Tile size (determines CSS class and dimensions) */\n size: TileSize;\n /** Optional CSS class for tile icon/content */\n cssClass?: string;\n}\n\nexport function createTile(title: string, bladePath: string, size: TileSize = TileSize.Normal): TileDefinition {\n return { title, bladePath, size };\n}\n","/**\n * User account information for the avatar menu.\n * Ported from UserAccount in v0.2.346.\n */\nexport interface UserAccount {\n userName: string;\n firstName: string;\n lastName: string;\n emailAddress?: string;\n}\n\n/** Computed full name from first and last name */\nexport function getUserDisplayName(account: UserAccount): string {\n return `${account.firstName || ''} ${account.lastName || ''}`.trim();\n}\n","/**\n * Notification panel definition.\n * Ported from AreaNotification in v0.2.346.\n */\nexport interface NotificationDefinition {\n /** Path/identifier for the content shown in the notification area */\n path: string;\n /** Panel width in pixels (default 250) */\n width: number;\n /** Whether the notification panel is currently visible */\n isVisible: boolean;\n /** Background color (default '#32383f') */\n backgroundColor: string;\n}\n\n/** Lifecycle hooks for the notification panel */\nexport interface NotificationLifecycle {\n /** Called before hide; return false to prevent hiding */\n onHide?: () => boolean;\n /** Called before showing */\n onShow?: () => void;\n /** Called after the panel is shown */\n onShowed?: () => void;\n}\n\nexport function createNotificationPanel(): NotificationDefinition {\n return {\n path: '',\n width: 250,\n isVisible: false,\n backgroundColor: '#32383f',\n };\n}\n","import { TileDefinition, TileSize, TILE_DIMENSIONS } from './tile-definition.model';\n\n/**\n * Panorama (startboard) definition.\n * Ported from Panorama + Startboard + Tiles in v0.2.346.\n *\n * The panorama is the dashboard view that shows tiles and toggles\n * visibility with the blade area.\n */\nexport interface PanoramaDefinition {\n /** Portal title displayed in the panorama header */\n title: string;\n /** Whether the panorama/startboard is visible (hidden when blades are open) */\n isVisible: boolean;\n /** Whether tiles have been loaded */\n isTilesLoaded: boolean;\n /** Whether to show tiles at all */\n showTiles: boolean;\n /** Hide the tile section if only one tile exists */\n hideTileIfOnlyOne: boolean;\n /** Positioned tiles with layout coordinates */\n tiles: PositionedTile[];\n}\n\n/** A tile with computed layout position (left/top in pixels) */\nexport interface PositionedTile extends TileDefinition {\n /** Horizontal offset in pixels */\n left: number;\n /** Vertical offset in pixels */\n top: number;\n}\n\n/**\n * Lay out tiles in a flowing grid pattern matching v0.2.346's Tiles.addTile() algorithm.\n * Tiles wrap after 540px width (3 normal tiles or 1 hero-wide tile).\n */\nexport function layoutTiles(tiles: TileDefinition[]): PositionedTile[] {\n const maxWidth = 720;\n let nextLeft = 0;\n let nextTop = 0;\n let columnHeightMax = 0;\n\n return tiles.map((tile) => {\n const dim = TILE_DIMENSIONS[tile.size];\n\n // Wrap to next row if tile exceeds max width\n if (nextLeft + dim.width > maxWidth && nextLeft > 0) {\n nextLeft = 0;\n nextTop += columnHeightMax;\n columnHeightMax = 0;\n }\n\n const positioned: PositionedTile = {\n ...tile,\n left: nextLeft,\n top: nextTop,\n };\n\n nextLeft += dim.width;\n if (dim.height > columnHeightMax) {\n columnHeightMax = dim.height;\n }\n\n return positioned;\n });\n}\n\nexport function createPanorama(title: string): PanoramaDefinition {\n return {\n title,\n isVisible: true,\n isTilesLoaded: false,\n showTiles: true,\n hideTileIfOnlyOne: true,\n tiles: [],\n };\n}\n","import { UserAccount } from './user-account.model';\n\n/**\n * Avatar menu definition for the user menu in the portal header.\n * Ported from AvatarMenu in v0.2.346.\n */\nexport interface AvatarMenuDefinition {\n /** The logged-in user's account info */\n userAccount: UserAccount;\n /** Whether the avatar dropdown is currently open */\n isOpen: boolean;\n}\n\nexport function createAvatarMenu(): AvatarMenuDefinition {\n return {\n userAccount: { userName: '', firstName: '', lastName: '' },\n isOpen: false,\n };\n}\n","/**\n * Multi-word search filter for grid/list blades.\n * Ported from BladeGrid.onFilter() in v0.2.346.\n *\n * Splits the search string by spaces and checks if ALL words\n * are found in ANY string property of the item.\n */\nexport function filterItems<T>(items: T[], searchText: string): T[] {\n if (!searchText || !searchText.trim()) {\n return items;\n }\n\n const words = searchText.toLowerCase().split(/\\s+/).filter(Boolean);\n\n return items.filter((item) => {\n const allValues = getAllStringValues(item).toLowerCase();\n return words.every((word) => allValues.includes(word));\n });\n}\n\n/** Concatenate all string property values of an object into one searchable string */\nfunction getAllStringValues(obj: unknown): string {\n if (obj === null || obj === undefined) return '';\n if (typeof obj === 'string') return obj;\n if (typeof obj !== 'object') return String(obj);\n\n return Object.values(obj as Record<string, unknown>)\n .filter((v) => typeof v === 'string')\n .join(' ');\n}\n","import { Injectable, signal, computed, WritableSignal } from '@angular/core';\nimport { BladeDefinition } from '../models/blade.model';\nimport { BladeParameter } from '../models/blade-parameter.model';\nimport { PanoramaDefinition, createPanorama, PositionedTile, layoutTiles } from '../models/panorama.model';\nimport { NotificationDefinition, createNotificationPanel } from '../models/notification.model';\nimport { AvatarMenuDefinition, createAvatarMenu } from '../models/avatar-menu.model';\nimport { TileDefinition } from '../models/tile-definition.model';\nimport { UserAccount } from '../models/user-account.model';\nimport { PortalConfig } from '../models/portal-config.model';\n\n/**\n * Central state service for the angular-portal-azure library.\n * Replaces v0.2.346's PortalService + Panorama + AreaNotification state.\n *\n * All state is managed via Angular signals for reactive updates.\n */\n@Injectable({ providedIn: 'root' })\nexport class PortalService {\n /** The blade stack — ordered left-to-right */\n readonly blades: WritableSignal<BladeDefinition[]> = signal([]);\n\n /** Panorama (startboard/dashboard) state */\n readonly panorama: WritableSignal<PanoramaDefinition> = signal(createPanorama(''));\n\n /** Notification panel state */\n readonly notification: WritableSignal<NotificationDefinition> = signal(createNotificationPanel());\n\n /** Avatar menu state */\n readonly avatarMenu: WritableSignal<AvatarMenuDefinition> = signal(createAvatarMenu());\n\n /** Shared parameter for passing data between blades */\n readonly parameter: WritableSignal<BladeParameter> = signal({ action: 'none', itemId: 0 });\n\n /** Portal theme identifier */\n readonly theme: WritableSignal<string> = signal('azure-blue');\n\n /** Whether the panorama is visible (true when no blades are open) */\n readonly isPanoramaVisible = computed(() => this.blades().length === 0);\n\n /** Number of open blades */\n readonly bladeCount = computed(() => this.blades().length);\n\n /** Positioned tiles with layout coordinates */\n readonly positionedTiles = computed(() => {\n const pano = this.panorama();\n return pano.tiles;\n });\n\n /**\n * Initialize the portal with configuration.\n * Called by providePortalAzure() during app bootstrap.\n */\n configure(config: PortalConfig): void {\n this.panorama.update((p) => ({\n ...p,\n title: config.title,\n tiles: config.tiles ? layoutTiles(config.tiles) : [],\n isTilesLoaded: !!config.tiles,\n showTiles: true,\n }));\n\n if (config.userAccount) {\n this.avatarMenu.update((m) => ({\n ...m,\n userAccount: config.userAccount!,\n }));\n }\n\n if (config.theme) {\n this.theme.set(config.theme);\n }\n }\n\n /** Update the portal title */\n setTitle(title: string): void {\n this.panorama.update((p) => ({ ...p, title }));\n }\n\n /** Update the user account */\n setUserAccount(userAccount: UserAccount): void {\n this.avatarMenu.update((m) => ({ ...m, userAccount }));\n }\n\n /** Set tiles on the startboard */\n setTiles(tiles: TileDefinition[]): void {\n this.panorama.update((p) => ({\n ...p,\n tiles: layoutTiles(tiles),\n isTilesLoaded: true,\n }));\n }\n\n /** Set blade parameter for inter-blade communication */\n setParameter(param: Partial<BladeParameter>): void {\n this.parameter.update((p) => ({ ...p, ...param }));\n }\n\n /** Clear the blade parameter back to defaults */\n clearParameter(): void {\n this.parameter.set({ action: 'none', itemId: 0 });\n }\n\n // --- Notification panel ---\n\n /** Show the notification panel */\n showNotification(path: string, width: number = 250): void {\n this.notification.update((n) => ({\n ...n,\n path,\n width,\n isVisible: true,\n }));\n }\n\n /** Hide the notification panel */\n hideNotification(): void {\n this.notification.update((n) => ({\n ...n,\n path: '',\n isVisible: false,\n }));\n }\n\n // --- Avatar menu ---\n\n /** Toggle avatar menu open/close */\n toggleAvatarMenu(): void {\n this.avatarMenu.update((m) => ({ ...m, isOpen: !m.isOpen }));\n }\n\n /** Close avatar menu */\n closeAvatarMenu(): void {\n this.avatarMenu.update((m) => ({ ...m, isOpen: false }));\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { PortalService } from './portal.service';\nimport { BladeDefinition, createBlade, AddBladeEventArgs } from '../models/blade.model';\n\n/**\n * Blade stack management service.\n * Replaces v0.2.346's AreaBlades class.\n *\n * Manages the blade stack: adding, removing, cascade-closing,\n * and panorama visibility toggling.\n */\n@Injectable({ providedIn: 'root' })\nexport class BladeService {\n private readonly portal = inject(PortalService);\n\n /**\n * Set the first blade (e.g., when opening a top-level item from a tile).\n * Clears all existing blades, hides panorama, and adds the new blade.\n *\n * Ported from AreaBlades.setFirstBlade() in v0.2.346.\n */\n setFirstBlade(path: string, title: string = '', width: number = 315): BladeDefinition {\n this.portal.blades.set([]);\n const blade = createBlade(path.toLowerCase(), title, width);\n this.portal.blades.set([blade]);\n return blade;\n }\n\n /**\n * Add a blade to the stack. If senderPath is provided, all blades\n * after the sender are removed first (cascade close).\n *\n * Ported from AreaBlades.addBlade() in v0.2.346.\n */\n addBlade(path: string, senderPath: string = '', title: string = '', width: number = 315): BladeDefinition | undefined {\n if (!path) return undefined;\n\n const normalizedPath = path.toLowerCase();\n const blades = this.portal.blades();\n\n // Check if blade already exists\n const existing = blades.find((b) => b.path === normalizedPath);\n if (existing) {\n return existing;\n }\n\n // Cascade close: remove blades after the sender\n if (senderPath) {\n this.clearChild(senderPath);\n }\n\n const blade = createBlade(normalizedPath, title, width);\n this.portal.blades.update((b) => [...b, blade]);\n return blade;\n }\n\n /**\n * Open a blade from a navigation event (e.g., tile click, nav item click).\n * Wraps addBlade with AddBladeEventArgs for compatibility.\n */\n openBlade(args: AddBladeEventArgs, title: string = '', width: number = 315): BladeDefinition | undefined {\n return this.addBlade(args.path, args.pathSender, title, width);\n }\n\n /**\n * Clear all blades. Shows panorama if appropriate.\n * Ported from AreaBlades.clearAll() in v0.2.346.\n */\n clearAll(): void {\n this.portal.blades.set([]);\n }\n\n /**\n * Remove a specific blade and all blades to its right.\n * This is what happens when a blade is closed.\n *\n * Ported from AreaBlades.clearPath() in v0.2.346.\n */\n clearPath(path: string): void {\n const normalizedPath = path.toLowerCase();\n const blades = this.portal.blades();\n const index = blades.findIndex((b) => b.path === normalizedPath);\n\n if (index >= 0) {\n this.portal.blades.set(blades.slice(0, index));\n } else {\n // Check notification area\n const notif = this.portal.notification();\n if (notif.path === normalizedPath) {\n this.portal.hideNotification();\n }\n }\n }\n\n /**\n * Remove all blades AFTER a given path (keeps the blade itself).\n * Used for cascade close when a blade opens a child.\n *\n * Ported from AreaBlades.clearChild() in v0.2.346.\n */\n clearChild(path: string): void {\n if (!path) return;\n\n const normalizedPath = path.toLowerCase();\n const blades = this.portal.blades();\n const index = blades.findIndex((b) => b.path === normalizedPath);\n\n if (index >= 0) {\n this.portal.blades.set(blades.slice(0, index + 1));\n }\n }\n\n /**\n * Remove blades at and beyond a specific 1-based level.\n * Ported from AreaBlades.clearLevel() in v0.2.346.\n */\n clearLevel(level: number): void {\n const adjustedLevel = level <= 0 ? 1 : level;\n const blades = this.portal.blades();\n if (adjustedLevel <= blades.length) {\n this.portal.blades.set(blades.slice(0, adjustedLevel - 1));\n }\n }\n\n /**\n * Remove only the last (rightmost) blade.\n * Ported from AreaBlades.clearLastLevel() in v0.2.346.\n */\n clearLastLevel(): void {\n const blades = this.portal.blades();\n if (blades.length > 0) {\n this.portal.blades.set(blades.slice(0, -1));\n }\n }\n\n /**\n * Close a specific blade by its definition reference.\n * Removes the blade and all blades to its right.\n */\n closeBlade(blade: BladeDefinition): void {\n this.clearPath(blade.path);\n }\n\n /**\n * Get a blade by path, if it exists in the stack.\n */\n getBlade(path: string): BladeDefinition | undefined {\n return this.portal.blades().find((b) => b.path === path.toLowerCase());\n }\n\n /**\n * Check if a blade with the given path is currently open.\n */\n isBladOpen(path: string): boolean {\n return this.portal.blades().some((b) => b.path === path.toLowerCase());\n }\n}\n","import { EnvironmentProviders, makeEnvironmentProviders, APP_INITIALIZER, inject } from '@angular/core';\nimport { PortalConfig } from '../models/portal-config.model';\nimport { PortalService } from './portal.service';\n\n/**\n * Provide the angular-portal-azure library configuration.\n *\n * Usage in app.config.ts:\n * ```typescript\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * providePortalAzure({\n * title: 'My Portal',\n * tiles: [...],\n * theme: 'azure-blue',\n * }),\n * ],\n * };\n * ```\n *\n * New in v0.3.0 — no equivalent in v0.2.346 (which used PortalShell constructor).\n */\nexport function providePortalAzure(config: PortalConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: APP_INITIALIZER,\n multi: true,\n useFactory: () => {\n const portalService = inject(PortalService);\n return () => portalService.configure(config);\n },\n },\n ]);\n}\n","import { Component, input, output } from '@angular/core';\nimport { PositionedTile } from '../../models/panorama.model';\n\n/**\n * Individual dashboard tile.\n * Ported from the tile section in home.html (v0.2.346).\n *\n * Usage:\n * ```html\n * <apa-tile [tile]=\"myTile\" (tileClick)=\"onTileClick($event)\" />\n * ```\n */\n@Component({\n selector: 'apa-tile',\n standalone: true,\n styles: [`:host { display: contents; }`],\n template: `\n <section\n class=\"fxs-tile fx-rightClick fxs-flowlayout-element\"\n [class.fxs-tilesize-normal]=\"tile().size === 'normal'\"\n [class.fxs-tilesize-mini]=\"tile().size === 'mini'\"\n [class.fxs-tilesize-herowide]=\"tile().size === 'herowide'\"\n [class.fxs-tilesize-small]=\"tile().size === 'small'\">\n <div class=\"fxs-part fxs-part-clickable\" (click)=\"onClick()\" style=\"cursor:pointer;\">\n <header class=\"fxs-part-title\">\n <h2 class=\"msportalfx-tooltip-overflow\">{{ tile().title }}</h2>\n @if (tile().subtitle) {\n <h3 class=\"msportalfx-tooltip-overflow\">{{ tile().subtitle }}</h3>\n }\n </header>\n <section class=\"fxs-part-content css-scope-HubsExtension\"></section>\n </div>\n <div class=\"fxs-tile-overlay\"></div>\n </section>\n `,\n})\nexport class TileComponent {\n readonly tile = input.required<PositionedTile>();\n readonly tileClick = output<PositionedTile>();\n\n onClick(): void {\n this.tileClick.emit(this.tile());\n }\n}\n","import { Component, inject } from '@angular/core';\nimport { PortalService } from '../../services/portal.service';\nimport { BladeService } from '../../services/blade.service';\nimport { TileComponent } from '../tile/tile.component';\nimport { PositionedTile } from '../../models/panorama.model';\n\n/**\n * Panorama (startboard/dashboard) component.\n * Ported from the fxs-panorama-homearea section in home.html (v0.2.346).\n *\n * Displays tiles on the startboard. When a tile is clicked, it opens\n * the first blade via BladeService.setFirstBlade().\n *\n * Usage:\n * ```html\n * <apa-panorama />\n * ```\n */\n@Component({\n selector: 'apa-panorama',\n standalone: true,\n imports: [TileComponent],\n styles: [`:host { display: contents; }`],\n template: `\n @if (portal.isPanoramaVisible()) {\n <div class=\"fxs-panorama-homearea\" [class.collapsed]=\"!panorama().showTiles\">\n <div class=\"fxs-startboard-target fxs-startboard fx-rightClick\" [class.collapsed]=\"!panorama().showTiles\">\n @if (panorama().tiles.length === 0 && panorama().isTilesLoaded) {\n <div class=\"fxs-part fxs-part-clickable\" style=\"background-color:var(--apa-surface-raised); padding:25px; max-width:800px; margin-bottom:15px; height:auto;\">\n <header class=\"fxs-part-title\" style=\"color:var(--apa-text)\">\n <h3 class=\"msportalfx-tooltip-overflow\">Keine Applikationen zugeordnet</h3>\n <p class=\"msportalfx-tooltip-overflow\" style=\"margin:0;padding:0\">\n Wenden Sie sich bitte an den Administrator damit die entsprechenden Applikationen zugeordnet werden koennen.\n </p>\n </header>\n </div>\n }\n <div class=\"fxs-startboard-layout fxs-flowlayout\">\n <div class=\"fxs-flowlayout-childcontainer\">\n @for (tile of panorama().tiles; track tile.bladePath) {\n <apa-tile [tile]=\"tile\" (tileClick)=\"onTileClick($event)\" />\n }\n </div>\n </div>\n </div>\n </div>\n }\n `,\n})\nexport class PanoramaComponent {\n protected readonly portal = inject(PortalService);\n private readonly bladeService = inject(BladeService);\n\n protected panorama = this.portal.panorama;\n\n onTileClick(tile: PositionedTile): void {\n this.bladeService.setFirstBlade(tile.bladePath, tile.title);\n }\n}\n","import { Component, inject, signal, ElementRef, afterNextRender, effect, Injector } from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { PortalService } from '../../services/portal.service';\nimport { getUserDisplayName } from '../../models/user-account.model';\n\n/**\n * Root portal shell component.\n * Ported from the fxs-portal structure in home.html (v0.2.346).\n *\n * Provides the top bar (with portal title and avatar menu),\n * and the main content area. Child components (panorama, blade-host,\n * notification-panel) are projected via content projection.\n *\n * Usage:\n * ```html\n * <apa-portal-layout>\n * <apa-panorama />\n * <apa-blade-host />\n * </apa-portal-layout>\n * ```\n */\n@Component({\n selector: 'apa-portal-layout',\n standalone: true,\n template: `\n <div class=\"fxs-portal fxs-theme-blue\">\n <!-- Top bar -->\n <div class=\"fxs-topbar\">\n <div style=\"padding-left:25px;\">\n <a href=\"#\" class=\"fxs-topbar-home fxs-has-hover\" (click)=\"onHomeClick($event)\">\n {{ portal.panorama().title }}\n </a>\n </div>\n <div style=\"display:flex; align-items:center; gap:12px; padding-right:10px;\">\n <button class=\"apa-darkmode-toggle fxs-has-hover\"\n (click)=\"toggleDarkMode()\"\n [attr.aria-label]=\"isDark() ? 'Switch to light mode' : 'Switch to dark mode'\"\n [attr.title]=\"isDark() ? 'Light mode' : 'Dark mode'\">\n <i [class]=\"isDark() ? 'ti ti-sun' : 'ti ti-moon'\"></i>\n </button>\n <div class=\"fxs-avatarmenu-tenant-container\">\n <a class=\"fxs-has-hover\" (click)=\"portal.toggleAvatarMenu()\">\n <span>{{ displayName() }}</span><br />\n <span>{{ portal.avatarMenu().userAccount.userName }}</span>\n </a>\n </div>\n </div>\n </div>\n <!-- Main content area -->\n <div class=\"fxs-portal-content fxs-panorama\"\n [style.margin-right.px]=\"notificationMargin()\">\n <ng-content />\n </div>\n <!-- Footer -->\n <div class=\"fxs-portal-footer\"></div>\n </div>\n `,\n})\nexport class PortalLayoutComponent {\n protected readonly portal = inject(PortalService);\n private static readonly STORAGE_KEY = 'apa-dark-mode';\n private readonly document = inject(DOCUMENT);\n private readonly elementRef = inject(ElementRef);\n private readonly injector = inject(Injector);\n protected readonly isDark = signal(false);\n\n constructor() {\n const stored = localStorage.getItem(PortalLayoutComponent.STORAGE_KEY);\n const dark = stored === 'true';\n this.applyTheme(dark);\n\n // Scroll to the last blade whenever the blade stack changes\n const injector = this.injector;\n effect(() => {\n const blades = this.portal.blades();\n if (blades.length === 0) return;\n afterNextRender(() => {\n this.scrollToLastBlade();\n }, { injector });\n });\n }\n\n protected toggleDarkMode(): void {\n const dark = !this.isDark();\n localStorage.setItem(PortalLayoutComponent.STORAGE_KEY, String(dark));\n this.applyTheme(dark);\n }\n\n private applyTheme(dark: boolean): void {\n this.isDark.set(dark);\n this.document.documentElement.classList.toggle('apa-dark', dark);\n this.document.documentElement.classList.toggle('apa-light', !dark);\n }\n\n protected displayName(): string {\n const account = this.portal.avatarMenu().userAccount;\n return getUserDisplayName(account);\n }\n\n protected notificationMargin(): number {\n const notif = this.portal.notification();\n return notif.isVisible ? notif.width : 0;\n }\n\n protected onHomeClick(event: Event): void {\n event.preventDefault();\n // Clear all blades to show panorama\n this.portal.blades.set([]);\n }\n\n private scrollToLastBlade(): void {\n const scrollContainer = this.elementRef.nativeElement.querySelector('.fxs-portal-content');\n if (!scrollContainer) return;\n\n const bladeElements = scrollContainer.querySelectorAll('.azureportalblade');\n if (bladeElements.length === 0) return;\n\n const lastBlade = bladeElements[bladeElements.length - 1] as HTMLElement;\n const scrollRect = scrollContainer.getBoundingClientRect();\n const bladeRect = lastBlade.getBoundingClientRect();\n\n // Blade is already fully visible — no scroll needed\n if (bladeRect.left >= scrollRect.left && bladeRect.right <= scrollRect.right) {\n return;\n }\n\n const currentScroll = scrollContainer.scrollLeft;\n const viewportWidth = scrollContainer.clientWidth;\n\n let targetScroll: number;\n\n if (bladeElements.length >= 2) {\n // Use the previous blade's right edge (= where the new blade starts)\n const prevBlade = bladeElements[bladeElements.length - 2] as HTMLElement;\n const prevRect = prevBlade.getBoundingClientRect();\n // Distance from viewport's left edge to the previous blade's right edge\n const delta = prevRect.right - scrollRect.left;\n targetScroll = currentScroll + delta;\n } else {\n // First blade — scroll to show it\n targetScroll = currentScroll + (bladeRect.left - scrollRect.left);\n }\n\n // Cap scroll movement to at most one viewport width\n targetScroll = Math.min(targetScroll, currentScroll + viewportWidth);\n\n scrollContainer.scrollTo({ left: targetScroll, behavior: 'smooth' });\n }\n}\n","import { Component, input } from '@angular/core';\nimport { BladeCommand } from '../../models/blade-command.model';\n\n/**\n * Command bar for a blade.\n * Ported from the fxs-commandBar section in blade.html (v0.2.346).\n *\n * Replaces the 18 individual command buttons with a dynamic BladeCommand[] array.\n *\n * Usage:\n * ```html\n * <apa-command-bar [commands]=\"blade.commands\" />\n * ```\n */\n@Component({\n selector: 'apa-command-bar',\n standalone: true,\n styles: [`:host { display: block; }`],\n template: `\n <div class=\"fxs-commandBar\">\n <ul class=\"fxs-commandBar-itemList\">\n @for (cmd of visibleCommands(); track cmd.key) {\n <li>\n <a class=\"fxs-commandBar-item\"\n [class.apa-disable-click]=\"!cmd.enabled\"\n (click)=\"onCommand(cmd)\">\n <span class=\"fxs-commandBar-item-text\">{{ cmd.label }}</span>\n @if (cmd.icon) {\n <span class=\"fxs-commandBar-item-icon apa-commandbar-icon\">\n <span [class]=\"cmd.icon\"></span>\n </span>\n }\n </a>\n </li>\n }\n </ul>\n </div>\n `,\n})\nexport class CommandBarComponent {\n readonly commands = input<BladeCommand[]>([]);\n\n visibleCommands(): BladeCommand[] {\n return this.commands().filter((c) => c.visible);\n }\n\n onCommand(cmd: BladeCommand): void {\n if (cmd.enabled && cmd.action) {\n cmd.action();\n }\n }\n}\n","import { Component, input, output, inject } from '@angular/core';\nimport { BladeDefinition } from '../../models/blade.model';\nimport { BladeService } from '../../services/blade.service';\nimport { CommandBarComponent } from '../command-bar/command-bar.component';\n\n/**\n * Blade chrome component — the visual container for a single blade.\n * Ported from blade.html (v0.2.346).\n *\n * Renders the blade header (status bar, close/maximize buttons, title,\n * command bar) and projects blade content via <ng-content>.\n *\n * Usage:\n * ```html\n * <apa-blade [blade]=\"myBlade\">\n * <p>Blade content here</p>\n * </apa-blade>\n * ```\n */\n@Component({\n selector: 'apa-blade',\n standalone: true,\n imports: [CommandBarComponent],\n styles: [`:host { display: block; height: 100%; }`],\n template: `\n <section class=\"fxs-blade-locked fxs-blade fx-rightClick fxs-bladesize-small\"\n [style.width.px]=\"blade().width\">\n <!-- Header -->\n <header class=\"fxs-blade-header\">\n <!-- Status bar -->\n <div class=\"fxs-blade-statusbar-wrapper\">\n <div class=\"fxs-blade-statusbar\"\n [class.apa-statusbar-info]=\"blade().statusBar.style === 'info'\"\n [class.apa-statusbar-error]=\"blade().statusBar.style === 'error' || blade().statusBar.style === 'warning'\"\n [class.apa-statusbar-success]=\"blade().statusBar.style === 'success'\">\n {{ blade().statusBar.text }}\n </div>\n </div>\n\n <!-- Action buttons -->\n <div class=\"fxs-blade-actions\">\n <button (click)=\"onClose()\" title=\"Schliessen\">\n <svg viewBox=\"0 0 11 11\" role=\"presentation\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\">\n <g>\n <polygon class=\"msportal-fx-svg-placeholder\" points=\"10.4,1.4 9.6,0.6 5.5,4.7 1.4,0.6 0.6,1.4 4.7,5.5 0.6,9.6 1.4,10.4 5.5,6.3 9.6,10.4 10.4,9.6 6.3,5.5\"/>\n </g>\n </svg>\n </button>\n </div>\n\n <!-- Title -->\n <div class=\"fxs-blade-title\">\n <div class=\"fxs-blade-title-text-container\">\n <h2>{{ blade().title }}</h2>\n @if (blade().subtitle) {\n <h3>{{ blade().subtitle }}</h3>\n }\n </div>\n </div>\n\n <!-- Command bar -->\n <div class=\"fxs-blade-commandBarContainer\">\n <apa-command-bar [commands]=\"blade().commands\" />\n </div>\n </header>\n\n <!-- Content area -->\n <div class=\"fxs-blade-content fxs-pannable\">\n <div class=\"fxs-blade-stacklayout\">\n <div class=\"fxs-stacklayout-child\">\n <ng-content />\n </div>\n </div>\n </div>\n </section>\n `,\n})\nexport class BladeComponent {\n readonly blade = input.required<BladeDefinition>();\n readonly bladeClose = output<BladeDefinition>();\n\n private readonly bladeService = inject(BladeService);\n\n onClose(): void {\n const b = this.blade();\n this.bladeClose.emit(b);\n this.bladeService.closeBlade(b);\n }\n}\n","import { Component, inject } from '@angular/core';\nimport { PortalService } from '../../services/portal.service';\nimport { BladeComponent } from '../blade/blade.component';\n\n/**\n * Blade host — renders the blade stack (journey area).\n * Ported from the apa-blade-area section in home.html (v0.2.346).\n *\n * Each blade in the stack is rendered horizontally. When a new blade\n * is added, the portal layout scrolls to show it.\n *\n * Consumer apps provide blade content via the [bladeTemplate] input\n * or by routing. For now, blades are rendered with their path as content.\n *\n * Usage:\n * ```html\n * <apa-blade-host />\n * ```\n */\n@Component({\n selector: 'apa-blade-host',\n standalone: true,\n imports: [BladeComponent],\n styles: [`:host { display: block; height: 100%; }`],\n template: `\n <div id=\"apa-blade-area\" class=\"fxs-journey-target fxs-journey\">\n <div class=\"fxs-journey-layout fxs-stacklayout fxs-stacklayout-horizontal\">\n @for (blade of portal.blades(); track blade.path) {\n <div class=\"azureportalblade fxs-stacklayout-child\">\n <apa-blade [blade]=\"blade\">\n <!-- Default content: blade path (consumers override via content projection or custom templates) -->\n <p style=\"padding:25px; color:var(--apa-text-secondary);\">{{ blade.path }}</p>\n </apa-blade>\n </div>\n }\n </div>\n </div>\n `,\n})\nexport class BladeHostComponent {\n protected readonly portal = inject(PortalService);\n}\n","import { Component, input, inject } from '@angular/core';\nimport { BladeNavItem } from '../../models/blade-nav-item.model';\nimport { BladeService } from '../../services/blade.service';\n\n/**\n * Navigation blade content — renders a list of nav items.\n * Ported from nav.html (v0.2.346).\n *\n * Each nav item shows an icon and title. Clicking a row opens\n * the target blade via BladeService.\n *\n * Usage:\n * ```html\n * <apa-blade [blade]=\"navBlade\">\n * <apa-blade-nav [items]=\"navItems\" [senderPath]=\"navBlade.path\" />\n * </apa-blade>\n * ```\n */\n@Component({\n selector: 'apa-blade-nav',\n standalone: true,\n styles: [`:host { display: flex; flex-direction: column; flex: 1; }`],\n template: `\n <table class=\"azc-grid-full azc-grid-multiselectable\">\n <colgroup>\n <col class=\"col0\" style=\"width:28px;\">\n <col class=\"col1\">\n </colgroup>\n <tbody class=\"azc-grid-groupdata\" role=\"rowgroup\">\n @for (item of visibleItems(); track item.bladePath) {\n <tr role=\"row\" style=\"cursor:pointer\" (click)=\"onItemClick(item)\">\n <td class=\"msportalfx-gridcolumn-asseticon\" role=\"gridcell\">\n @if (item.cssClass) {\n <i [class]=\"item.cssClass\"></i>\n }\n </td>\n <td tabindex=\"0\" role=\"gridcell\">\n @if (item.hrefPath) {\n <a [href]=\"item.hrefPath\" target=\"_blank\">{{ item.title }}</a>\n } @else {\n <span>{{ item.title }}</span>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n `,\n})\nexport class BladeNavComponent {\n readonly items = input<BladeNavItem[]>([]);\n readonly senderPath = input<string>('');\n\n private readonly bladeService = inject(BladeService);\n\n visibleItems(): BladeNavItem[] {\n return this.items().filter((item) => item.isVisible);\n }\n\n onItemClick(item: BladeNavItem): void {\n if (item.hrefPath) {\n // External link — let the <a> handle it\n return;\n }\n if (item.bladePath) {\n this.bladeService.addBlade(item.bladePath, this.senderPath());\n }\n item.callback?.();\n }\n}\n","import { Component, input, output, inject } from '@angular/core';\nimport { BladeService } from '../../services/blade.service';\nimport { filterItems } from '../../models/filter.util';\n\n/**\n * Grid/list blade content — renders a searchable list of items.\n * Ported from grid.html + BladeGrid (v0.2.346).\n *\n * Displays items in a table with optional search filtering.\n * Each row shows a title and optional subtitle. Clicking a row\n * opens the target blade.\n *\n * Usage:\n * ```html\n * <apa-blade [blade]=\"gridBlade\">\n * <apa-blade-grid\n * [items]=\"items\"\n * [senderPath]=\"gridBlade.path\"\n * [displayField]=\"'title'\"\n * (itemClick)=\"onItemClick($event)\" />\n * </apa-blade>\n * ```\n */\n@Component({\n selector: 'apa-blade-grid',\n standalone: true,\n styles: [`:host { display: flex; flex-direction: column; flex: 1; }`],\n template: `\n @if (searchable()) {\n <div style=\"padding:0 0 10px 0;\">\n <input type=\"text\"\n class=\"form-control\"\n placeholder=\"Suchen...\"\n [value]=\"searchText\"\n (input)=\"onSearchInput($event)\" />\n </div>\n }\n <table class=\"azc-grid-full azc-grid-multiselectable\">\n <colgroup>\n <col class=\"col0\" style=\"width:41px;\">\n <col class=\"col1\">\n </colgroup>\n <tbody class=\"azc-grid-groupdata\" role=\"rowgroup\">\n @for (item of filteredItems(); track $index) {\n <tr role=\"row\" style=\"cursor:pointer\" (click)=\"onRowClick(item)\">\n <td class=\"msportalfx-gridcolumn-asseticon\" role=\"gridcell\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"msportal-fx-svg-placeholder\" viewBox=\"0 0 50 50\" focusable=\"false\" style=\"height:21px;width:21px;\">\n <rect class=\"msportalfx-svg-c04\" x=\"19.8\" y=\"39.4\" width=\"10.6\" height=\"3.4\"/>\n <polygon class=\"msportalfx-svg-c04\" points=\"23.1,50 27,50 30.3,46.5 19.8,46.5\"/>\n <path class=\"msportalfx-svg-c20\" d=\"M41.2 14.7v-.3c0-7.7-6.6-14.1-14.7-14.2-.2-.3-4.8.1-4.8.1-7.3.9-13 7-13 14.1 0 .2-.8 5.8 4.9 10.5 2.6 2.3 5.3 8.5 5.7 10.3l.3.6h10.6l.3-.6c.4-1.8 3.2-8 5.7-10.2C41.9 20.2 41.2 14.9 41.2 14.7z\"/>\n </svg>\n </td>\n <td tabindex=\"0\" role=\"gridcell\">\n <span>{{ getDisplayValue(item) }}</span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n `,\n})\nexport class BladeGridComponent {\n readonly items = input<any[]>([]);\n readonly senderPath = input<string>('');\n readonly displayField = input<string>('title');\n readonly bladePathField = input<string>('bladePath');\n readonly searchable = input<boolean>(true);\n readonly itemClick = output<any>();\n\n searchText = '';\n\n private readonly bladeService = inject(BladeService);\n\n filteredItems(): any[] {\n return filterItems(this.items(), this.searchText);\n }\n\n getDisplayValue(item: any): string {\n return item[this.displayField()] ?? '';\n }\n\n onSearchInput(event: Event): void {\n this.searchText = (event.target as HTMLInputElement).value;\n }\n\n onRowClick(item: any): void {\n this.itemClick.emit(item);\n const bladePath = item[this.bladePathField()];\n if (bladePath) {\n this.bladeService.addBlade(bladePath, this.senderPath());\n }\n }\n}\n","import { Component, input } from '@angular/core';\nimport { BladeDataDefinition } from '../../models/blade-data.model';\nimport { BladeCommand, createCommand } from '../../models/blade-command.model';\n\n/**\n * Detail/edit blade content — renders a form area for editing an item.\n * Ported from BladeDetail<T> (v0.2.346).\n *\n * Provides a content projection area for forms. The blade's commands\n * (save, delete, cancel, new) are managed via the blade definition.\n *\n * This is a thin wrapper that projects content and provides\n * convenience methods for setting up typical detail blade commands.\n *\n * Usage:\n * ```html\n * <apa-blade [blade]=\"detailBlade\">\n * <apa-blade-detail [blade]=\"detailBlade\">\n * <form>\n * <!-- form fields here -->\n * </form>\n * </apa-blade-detail>\n * </apa-blade>\n * ```\n */\n@Component({\n selector: 'apa-blade-detail',\n standalone: true,\n styles: [`:host { display: flex; flex-direction: column; flex: 1; }\n .apa-blade-detail { flex: 1; }`],\n template: `\n <div class=\"apa-blade-detail\">\n <ng-content />\n </div>\n `,\n})\nexport class BladeDetailComponent {\n readonly blade = input.required<BladeDataDefinition<any>>();\n}\n\n/**\n * Create standard detail blade commands (new, save, delete, cancel).\n * Convenience function for setting up typical detail/edit blade commands\n * matching the v0.2.346 BladeDetail default commands.\n */\nexport function createDetailCommands(handlers: {\n onNew?: () => void;\n onSave?: () => void;\n onDelete?: () => void;\n onCancel?: () => void;\n}): BladeCommand[] {\n const commands: BladeCommand[] = [];\n\n if (handlers.onNew) {\n commands.push(createCommand('new', 'neu', handlers.onNew));\n }\n if (handlers.onSave) {\n commands.push(createCommand('save', 'speichern', handlers.onSave));\n }\n if (handlers.onDelete) {\n commands.push(createCommand('delete', 'loeschen', handlers.onDelete));\n }\n if (handlers.onCancel) {\n commands.push(createCommand('cancel', 'abbrechen', handlers.onCancel));\n }\n\n return commands;\n}\n","import { Component, inject } from '@angular/core';\nimport { PortalService } from '../../services/portal.service';\n\n/**\n * Notification panel — right-side overlay panel.\n * Ported from apa-notification-area in home.html (v0.2.346).\n *\n * Usage:\n * ```html\n * <apa-notification-panel>\n * <!-- Custom notification content -->\n * </apa-notification-panel>\n * ```\n */\n@Component({\n selector: 'apa-notification-panel',\n standalone: true,\n styles: [`:host { display: contents; }`],\n template: `\n @if (portal.notification().isVisible) {\n <div class=\"apa-notification-panel\"\n [style.width.px]=\"portal.notification().width\">\n <button class=\"apa-notification-close\" (click)=\"onClose()\" title=\"Schliessen\">\n <svg viewBox=\"0 0 11 11\" role=\"presentation\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\">\n <polygon class=\"msportal-fx-svg-placeholder\" points=\"10.4,1.4 9.6,0.6 5.5,4.7 1.4,0.6 0.6,1.4 4.7,5.5 0.6,9.6 1.4,10.4 5.5,6.3 9.6,10.4 10.4,9.6 6.3,5.5\"/>\n </svg>\n </button>\n <ng-content />\n </div>\n }\n `,\n})\nexport class NotificationPanelComponent {\n protected readonly portal = inject(PortalService);\n\n onClose(): void {\n this.portal.hideNotification();\n }\n}\n","import { Component, inject } from '@angular/core';\nimport { PortalService } from '../../services/portal.service';\nimport { getUserDisplayName } from '../../models/user-account.model';\n\n/**\n * Avatar menu — user account dropdown in the portal header.\n * Ported from fxs-avatarmenu CSS structure in v0.2.346.\n *\n * Shows the user's name and email. Clicking toggles a dropdown\n * with optional actions (sign out, etc.).\n *\n * Usage:\n * ```html\n * <apa-avatar-menu>\n * <a href=\"/Account/SignOut\">Abmelden</a>\n * </apa-avatar-menu>\n * ```\n */\n@Component({\n selector: 'apa-avatar-menu',\n standalone: true,\n template: `\n <div class=\"fxs-avatarmenu\">\n <a class=\"fxs-has-hover\" (click)=\"portal.toggleAvatarMenu()\">\n <div class=\"fxs-avatarmenu-header\">\n <span class=\"fxs-avatarmenu-username\">{{ displayName() }}</span>\n <span class=\"fxs-avatarmenu-emailaddress\">{{ userAccount().emailAddress }}</span>\n </div>\n </a>\n @if (portal.avatarMenu().isOpen) {\n <div class=\"fxs-avatarmenu-dropdown\" style=\"display:block;\">\n <ul>\n <ng-content />\n </ul>\n </div>\n }\n </div>\n `,\n})\nexport class AvatarMenuComponent {\n protected readonly portal = inject(PortalService);\n\n protected userAccount() {\n return this.portal.avatarMenu().userAccount;\n }\n\n protected displayName(): string {\n return getUserDisplayName(this.userAccount());\n }\n}\n","import { Component, input, inject } from '@angular/core';\nimport { BladeNavItem } from '../../models/blade-nav-item.model';\nimport { BladeService } from '../../services/blade.service';\n\n/**\n * Sidebar navigation — optional vertical navigation panel.\n * New in v0.3.0 (no equivalent in v0.2.346).\n *\n * Provides a collapsible sidebar with navigation items that\n * open blades when clicked.\n *\n * Usage:\n * ```html\n * <apa-sidebar [items]=\"sidebarItems\" [collapsed]=\"false\" />\n * ```\n */\n@Component({\n selector: 'apa-sidebar',\n standalone: true,\n template: `\n <nav class=\"apa-sidebar\" [class.apa-sidebar-collapsed]=\"collapsed()\">\n @for (item of visibleItems(); track item.bladePath) {\n <a class=\"apa-sidebar-item\"\n (click)=\"onItemClick(item)\"\n style=\"cursor:pointer;\">\n @if (item.cssClass) {\n <i [class]=\"item.cssClass\" class=\"apa-sidebar-icon\"></i>\n }\n @if (!collapsed()) {\n <span class=\"apa-sidebar-label\">{{ item.title }}</span>\n }\n </a>\n }\n </nav>\n `,\n styles: [`\n .apa-sidebar {\n display: flex;\n flex-direction: column;\n background-color: var(--apa-chrome);\n width: 200px;\n height: 100%;\n padding-top: 10px;\n transition: width 0.2s ease;\n }\n .apa-sidebar-collapsed {\n width: 50px;\n }\n .apa-sidebar-item {\n display: flex;\n align-items: center;\n padding: 10px 15px;\n color: var(--apa-chrome-text);\n text-decoration: none;\n font-size: 13px;\n transition: background-color 0.15s ease;\n }\n .apa-sidebar-item:hover {\n background-color: var(--apa-chrome-hover);\n }\n .apa-sidebar-icon {\n margin-right: 10px;\n width: 20px;\n text-align: center;\n }\n .apa-sidebar-collapsed .apa-sidebar-icon {\n margin-right: 0;\n }\n `],\n})\nexport class SidebarComponent {\n readonly items = input<BladeNavItem[]>([]);\n readonly collapsed = input<boolean>(false);\n\n private readonly bladeService = inject(BladeService);\n\n visibleItems(): BladeNavItem[] {\n return this.items().filter((item) => item.isVisible);\n }\n\n onItemClick(item: BladeNavItem): void {\n if (item.bladePath) {\n this.bladeService.setFirstBlade(item.bladePath, item.title);\n }\n item.callback?.();\n }\n}\n","/*\r\n * Public API Surface of @ardimedia/angular-portal-azure\r\n */\r\n\r\n// Models\r\nexport * from './lib/models/blade.model';\r\nexport * from './lib/models/blade-command.model';\r\nexport * from './lib/models/blade-data.model';\r\nexport * from './lib/models/blade-nav-item.model';\r\nexport * from './lib/models/blade-parameter.model';\r\nexport * from './lib/models/status-bar.model';\r\nexport * from './lib/models/tile-definition.model';\r\nexport * from './lib/models/user-account.model';\r\nexport * from './lib/models/notification.model';\r\nexport * from './lib/models/panorama.model';\r\nexport * from './lib/models/avatar-menu.model';\r\nexport * from './lib/models/portal-config.model';\r\nexport * from './lib/models/filter.util';\r\n\r\n// Services\r\nexport * from './lib/services/portal.service';\r\nexport * from './lib/services/blade.service';\r\nexport * from './lib/services/provide-portal-azure';\r\n\r\n// Components\r\nexport * from './lib/components/tile/tile.component';\r\nexport * from './lib/components/panorama/panorama.component';\r\nexport * from './lib/components/portal-layout/portal-layout.component';\r\nexport * from './lib/components/command-bar/command-bar.component';\r\nexport * from './lib/components/blade/blade.component';\r\nexport * from './lib/components/blade-host/blade-host.component';\r\nexport * from './lib/components/blade-nav/blade-nav.component';\r\nexport * from './lib/components/blade-grid/blade-grid.component';\r\nexport * from './lib/components/blade-detail/blade-detail.component';\r\nexport * from './lib/components/notification-panel/notification-panel.component';\r\nexport * from './lib/components/avatar-menu/avatar-menu.component';\r\nexport * from './lib/components/sidebar/sidebar.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ardimedia-angular-portal-azure.mjs","sources":["../../../../projects/ardimedia/angular-portal-azure/src/lib/models/status-bar.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/blade.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/blade-command.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/blade-data.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/blade-nav-item.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/tile-definition.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/user-account.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/notification.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/panorama.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/avatar-menu.model.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/models/filter.util.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/services/portal.service.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/services/blade.service.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/services/provide-portal-azure.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/tile/tile.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/panorama/panorama.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/portal-layout/portal-layout.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/command-bar/command-bar.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/blade/blade.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/blade-host/blade-host.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/blade-nav/blade-nav.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/blade-grid/blade-grid.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/blade-detail/blade-detail.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/notification-panel/notification-panel.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/avatar-menu/avatar-menu.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/lib/components/sidebar/sidebar.component.ts","../../../../projects/ardimedia/angular-portal-azure/src/public-api.ts","../../../../projects/ardimedia/angular-portal-azure/src/ardimedia-angular-portal-azure.ts"],"sourcesContent":["/**\n * Status bar display state for a blade.\n * Ported from UserControlBase.statusBar / statusBarClass in v0.2.346.\n */\nexport interface StatusBarState {\n /** Status bar text message */\n text: string;\n /** CSS class for styling (e.g. 'info', 'error', 'success') */\n style: StatusBarStyle;\n}\n\nexport type StatusBarStyle = 'none' | 'info' | 'error' | 'success' | 'warning';\n\nexport function clearStatusBar(): StatusBarState {\n return { text: '', style: 'none' };\n}\n\nexport function statusBarInfo(text: string): StatusBarState {\n return { text, style: 'info' };\n}\n\nexport function statusBarError(text: string): StatusBarState {\n return { text, style: 'error' };\n}\n\nexport function statusBarSuccess(text: string): StatusBarState {\n return { text, style: 'success' };\n}\n","import { BladeCommand } from './blade-command.model';\nimport { StatusBarState, clearStatusBar } from './status-bar.model';\n\n/**\n * Base blade definition used by BladeService to manage the blade stack.\n * Ported from Blade class in v0.2.346 — flattened from the UserControlBase → Blade hierarchy.\n *\n * In v0.2.346 this was a class with 18 command boolean groups and deep inheritance.\n * In v0.3.0 commands are a BladeCommand[] array and blade state is managed by the service.\n */\nexport interface BladeDefinition {\n /** Unique path identifying this blade (lowercased) */\n path: string;\n /** Blade header title */\n title: string;\n /** Blade header subtitle */\n subtitle: string;\n /** Blade width in pixels */\n width: number;\n /** Whether the blade content uses inner HTML (ng-content) vs structured content */\n isInnerHtml: boolean;\n /** Command bar buttons */\n commands: BladeCommand[];\n /** Status bar state */\n statusBar: StatusBarState;\n}\n\n/** Creates a blade definition with sensible defaults */\nexport function createBlade(path: string, title: string, width: number = 315): BladeDefinition {\n return {\n path: path.toLowerCase(),\n title,\n subtitle: '',\n width,\n isInnerHtml: true,\n commands: [],\n statusBar: clearStatusBar(),\n };\n}\n\n/**\n * Event args for blade navigation.\n * Ported from IAddBladeEventArgs in v0.2.346.\n */\nexport interface AddBladeEventArgs {\n path: string;\n pathSender: string;\n}\n","/**\n * Defines a command button in a blade's command bar.\n *\n * Replaces the 18 individual command boolean groups from v0.2.346.\n * Each command has visibility, enabled state, label text, icon, and action callback.\n */\nexport interface BladeCommand {\n /** Unique key identifying the command (e.g. 'save', 'delete', 'new') */\n key: string;\n /** Display text for the command button */\n label: string;\n /** Whether the command button is visible */\n visible: boolean;\n /** Whether the command button is enabled (clickable) */\n enabled: boolean;\n /** SVG icon identifier or CSS class for the command icon */\n icon?: string;\n /** Callback executed when the command is clicked */\n action: () => void;\n}\n\n/**\n * Standard command keys matching the 18 commands from v0.2.346:\n * browse, cancel, copy, delete, document, document2, document3, document4, document5,\n * new, order, restart, save, search, start, stop, swap, excel\n */\nexport type StandardCommandKey =\n | 'browse' | 'cancel' | 'copy' | 'delete'\n | 'document' | 'document2' | 'document3' | 'document4' | 'document5'\n | 'new' | 'order' | 'restart' | 'save' | 'search'\n | 'start' | 'stop' | 'swap' | 'excel';\n\n/** Creates a command with sensible defaults (visible, enabled, no-op action) */\nexport function createCommand(key: string, label: string, action: () => void, icon?: string): BladeCommand {\n return { key, label, visible: true, enabled: true, icon, action };\n}\n","import { BladeDefinition, createBlade } from './blade.model';\nimport { StatusBarState, statusBarInfo, statusBarError, statusBarSuccess, clearStatusBar } from './status-bar.model';\n\n/**\n * Exception model for API error responses.\n * Ported from Exception / ExceptionDotNet in v0.2.346.\n */\nexport interface ApiException {\n message: string;\n status?: number;\n statusText?: string;\n data?: Array<{ key: number; value: string }>;\n validationResults?: Array<{ errorMessage: string; memberNames: string[] }>;\n}\n\n/**\n * Lifecycle hooks for CRUD operations on a blade.\n * Ported from BladeData<T> template method pattern in v0.2.346.\n *\n * Each operation follows the pattern: onBefore → execute → onSuccess | onError\n */\nexport interface BladeDataLifecycle<T> {\n // Load single item\n onLoadItem?: () => void;\n onLoadedItem?: () => void;\n onLoadItemError?: (ex: ApiException) => void;\n\n // Load multiple items\n onLoadItems?: () => void;\n onLoadedItems?: () => void;\n onLoadItemsError?: (ex: ApiException) => void;\n\n // Save item\n onSaveItem?: () => void;\n onSavedItem?: () => void;\n onSaveItemError?: (ex: ApiException) => void;\n\n // Delete item\n onDeleteItem?: () => void;\n onDeletedItem?: () => boolean; // return false to prevent blade close\n onDeleteItemError?: (ex: ApiException) => void;\n\n // New item\n onNewItem?: () => void;\n onNewedItem?: () => void;\n onNewItemError?: (ex: ApiException) => void;\n\n // Execute generic action\n onExecute?: () => void;\n onExecuted?: () => void;\n onExecuteError?: (ex: ApiException) => void;\n\n // Form validation\n isFormValid?: () => boolean;\n}\n\n/**\n * Extended blade definition for data-driven blades with CRUD operations.\n * Ported from BladeData<T> in v0.2.346.\n */\nexport interface BladeDataDefinition<T> extends BladeDefinition {\n /** Current item being edited/viewed */\n item: T;\n /** List of items (for grid/list blades) */\n items: T[];\n /** Lifecycle hooks for CRUD operations */\n lifecycle: BladeDataLifecycle<T>;\n}\n\n/** Creates a data blade definition with sensible defaults */\nexport function createDataBlade<T>(\n path: string,\n title: string,\n width: number = 315,\n): BladeDataDefinition<T> {\n return {\n ...createBlade(path, title, width),\n item: {} as T,\n items: [],\n lifecycle: {},\n };\n}\n\n/**\n * Execute a load-item operation with lifecycle hooks and status bar updates.\n * Replaces the BladeData.loadItem() template method from v0.2.346.\n */\nexport async function executeLoadItem<T>(\n blade: BladeDataDefinition<T>,\n loadFn: () => Promise<T>,\n): Promise<T | void> {\n blade.lifecycle.onLoadItem?.();\n blade.statusBar = statusBarInfo('Laden...');\n try {\n const result = await loadFn();\n blade.item = result;\n blade.statusBar = clearStatusBar();\n blade.lifecycle.onLoadedItem?.();\n return result;\n } catch (ex) {\n blade.statusBar = statusBarError((ex as ApiException).message || 'Fehler beim Laden');\n blade.lifecycle.onLoadItemError?.(ex as ApiException);\n }\n}\n\n/**\n * Execute a load-items operation with lifecycle hooks and status bar updates.\n */\nexport async function executeLoadItems<T>(\n blade: BladeDataDefinition<T>,\n loadFn: () => Promise<T[]>,\n): Promise<T[] | void> {\n blade.lifecycle.onLoadItems?.();\n blade.statusBar = statusBarInfo('Laden...');\n try {\n const result = await loadFn();\n blade.items = result;\n blade.statusBar = clearStatusBar();\n blade.lifecycle.onLoadedItems?.();\n return result;\n } catch (ex) {\n blade.statusBar = statusBarError((ex as ApiException).message || 'Fehler beim Laden');\n blade.lifecycle.onLoadItemsError?.(ex as ApiException);\n }\n}\n\n/**\n * Execute a save-item operation with lifecycle hooks and status bar updates.\n */\nexport async function executeSaveItem<T>(\n blade: BladeDataDefinition<T>,\n saveFn: () => Promise<T>,\n): Promise<T | void> {\n if (blade.lifecycle.isFormValid && !blade.lifecycle.isFormValid()) {\n return;\n }\n blade.lifecycle.onSaveItem?.();\n blade.statusBar = statusBarInfo('Speichern...');\n try {\n const result = await saveFn();\n blade.item = result;\n blade.statusBar = statusBarSuccess('Gespeichert');\n blade.lifecycle.onSavedItem?.();\n return result;\n } catch (ex) {\n blade.statusBar = statusBarError((ex as ApiException).message || 'Fehler beim Speichern');\n blade.lifecycle.onSaveItemError?.(ex as ApiException);\n }\n}\n\n/**\n * Execute a delete-item operation with lifecycle hooks and status bar updates.\n * Returns true if the blade should be closed after deletion.\n */\nexport async function executeDeleteItem<T>(\n blade: BladeDataDefinition<T>,\n deleteFn: () => Promise<void>,\n): Promise<boolean> {\n blade.lifecycle.onDeleteItem?.();\n blade.statusBar = statusBarInfo('Loeschen...');\n try {\n await deleteFn();\n blade.statusBar = statusBarSuccess('Geloescht');\n const shouldClose = blade.lifecycle.onDeletedItem?.() ?? true;\n return shouldClose;\n } catch (ex) {\n blade.statusBar = statusBarError((ex as ApiException).message || 'Fehler beim Loeschen');\n blade.lifecycle.onDeleteItemError?.(ex as ApiException);\n return false;\n }\n}\n","/**\n * Navigation item displayed in a BladeNav component.\n * Ported from BladeNavItem in v0.2.346.\n */\nexport interface BladeNavItem {\n /** Display title */\n title: string;\n /** CSS class for the icon */\n cssClass?: string;\n /** Path of the blade to open when clicked */\n bladePath: string;\n /** External href link (alternative to bladePath) */\n hrefPath?: string;\n /** Comma-separated role names for visibility control */\n roles?: string;\n /** Whether this nav item is visible */\n isVisible: boolean;\n /** Optional callback executed on click (in addition to navigation) */\n callback?: () => void;\n}\n\nexport function createNavItem(title: string, bladePath: string, cssClass?: string): BladeNavItem {\n return { title, bladePath, cssClass, isVisible: true };\n}\n","/**\n * Tile size enum matching v0.2.346 TileSizes.\n * The names are used in CSS class names (e.g. 'fxs-tilesize-normal').\n */\nexport enum TileSize {\n Small = 'small',\n Mini = 'mini',\n Normal = 'normal',\n HeroWide = 'herowide',\n}\n\n/** Pixel dimensions for each tile size */\nexport const TILE_DIMENSIONS: Record<TileSize, { width: number; height: number }> = {\n [TileSize.Small]: { width: 90, height: 90 },\n [TileSize.Mini]: { width: 180, height: 90 },\n [TileSize.Normal]: { width: 180, height: 180 },\n [TileSize.HeroWide]: { width: 540, height: 360 },\n};\n\n/**\n * Tile definition for the panorama/startboard.\n * Ported from Tile in v0.2.346.\n */\nexport interface TileDefinition {\n /** Display title on the tile */\n title: string;\n /** Optional subtitle */\n subtitle?: string;\n /** Path of the blade to open when the tile is clicked */\n bladePath: string;\n /** Tile size (determines CSS class and dimensions) */\n size: TileSize;\n /** Optional CSS class for tile icon/content */\n cssClass?: string;\n}\n\nexport function createTile(title: string, bladePath: string, size: TileSize = TileSize.Normal): TileDefinition {\n return { title, bladePath, size };\n}\n","/**\n * User account information for the avatar menu.\n * Ported from UserAccount in v0.2.346.\n */\nexport interface UserAccount {\n userName: string;\n firstName: string;\n lastName: string;\n emailAddress?: string;\n}\n\n/** Computed full name from first and last name */\nexport function getUserDisplayName(account: UserAccount): string {\n return `${account.firstName || ''} ${account.lastName || ''}`.trim();\n}\n","/**\n * Notification panel definition.\n * Ported from AreaNotification in v0.2.346.\n */\nexport interface NotificationDefinition {\n /** Path/identifier for the content shown in the notification area */\n path: string;\n /** Panel width in pixels (default 250) */\n width: number;\n /** Whether the notification panel is currently visible */\n isVisible: boolean;\n /** Background color (default '#32383f') */\n backgroundColor: string;\n}\n\n/** Lifecycle hooks for the notification panel */\nexport interface NotificationLifecycle {\n /** Called before hide; return false to prevent hiding */\n onHide?: () => boolean;\n /** Called before showing */\n onShow?: () => void;\n /** Called after the panel is shown */\n onShowed?: () => void;\n}\n\nexport function createNotificationPanel(): NotificationDefinition {\n return {\n path: '',\n width: 250,\n isVisible: false,\n backgroundColor: '#32383f',\n };\n}\n","import { TileDefinition, TileSize, TILE_DIMENSIONS } from './tile-definition.model';\n\n/**\n * Panorama (startboard) definition.\n * Ported from Panorama + Startboard + Tiles in v0.2.346.\n *\n * The panorama is the dashboard view that shows tiles and toggles\n * visibility with the blade area.\n */\nexport interface PanoramaDefinition {\n /** Portal title displayed in the panorama header */\n title: string;\n /** Whether the panorama/startboard is visible (hidden when blades are open) */\n isVisible: boolean;\n /** Whether tiles have been loaded */\n isTilesLoaded: boolean;\n /** Whether to show tiles at all */\n showTiles: boolean;\n /** Hide the tile section if only one tile exists */\n hideTileIfOnlyOne: boolean;\n /** Positioned tiles with layout coordinates */\n tiles: PositionedTile[];\n}\n\n/** A tile with computed layout position (left/top in pixels) */\nexport interface PositionedTile extends TileDefinition {\n /** Horizontal offset in pixels */\n left: number;\n /** Vertical offset in pixels */\n top: number;\n}\n\n/**\n * Lay out tiles in a flowing grid pattern matching v0.2.346's Tiles.addTile() algorithm.\n * Tiles wrap after 540px width (3 normal tiles or 1 hero-wide tile).\n */\nexport function layoutTiles(tiles: TileDefinition[]): PositionedTile[] {\n const maxWidth = 720;\n let nextLeft = 0;\n let nextTop = 0;\n let columnHeightMax = 0;\n\n return tiles.map((tile) => {\n const dim = TILE_DIMENSIONS[tile.size];\n\n // Wrap to next row if tile exceeds max width\n if (nextLeft + dim.width > maxWidth && nextLeft > 0) {\n nextLeft = 0;\n nextTop += columnHeightMax;\n columnHeightMax = 0;\n }\n\n const positioned: PositionedTile = {\n ...tile,\n left: nextLeft,\n top: nextTop,\n };\n\n nextLeft += dim.width;\n if (dim.height > columnHeightMax) {\n columnHeightMax = dim.height;\n }\n\n return positioned;\n });\n}\n\nexport function createPanorama(title: string): PanoramaDefinition {\n return {\n title,\n isVisible: true,\n isTilesLoaded: false,\n showTiles: true,\n hideTileIfOnlyOne: true,\n tiles: [],\n };\n}\n","import { UserAccount } from './user-account.model';\n\n/**\n * A single item in the avatar dropdown menu.\n */\nexport interface AvatarMenuItem {\n /** Display text */\n label: string;\n /** Navigation URL */\n href: string;\n /** Optional icon CSS class, e.g. 'ti ti-settings' */\n icon?: string;\n}\n\n/**\n * Avatar menu definition for the user menu in the portal header.\n * Ported from AvatarMenu in v0.2.346.\n */\nexport interface AvatarMenuDefinition {\n /** The logged-in user's account info */\n userAccount: UserAccount;\n /** Whether the avatar dropdown is currently open */\n isOpen: boolean;\n /** Menu items shown in the dropdown */\n items: AvatarMenuItem[];\n}\n\nexport function createAvatarMenu(): AvatarMenuDefinition {\n return {\n userAccount: { userName: '', firstName: '', lastName: '' },\n isOpen: false,\n items: [],\n };\n}\n","/**\n * Multi-word search filter for grid/list blades.\n * Ported from BladeGrid.onFilter() in v0.2.346.\n *\n * Splits the search string by spaces and checks if ALL words\n * are found in ANY string property of the item.\n */\nexport function filterItems<T>(items: T[], searchText: string): T[] {\n if (!searchText || !searchText.trim()) {\n return items;\n }\n\n const words = searchText.toLowerCase().split(/\\s+/).filter(Boolean);\n\n return items.filter((item) => {\n const allValues = getAllStringValues(item).toLowerCase();\n return words.every((word) => allValues.includes(word));\n });\n}\n\n/** Concatenate all string property values of an object into one searchable string */\nfunction getAllStringValues(obj: unknown): string {\n if (obj === null || obj === undefined) return '';\n if (typeof obj === 'string') return obj;\n if (typeof obj !== 'object') return String(obj);\n\n return Object.values(obj as Record<string, unknown>)\n .filter((v) => typeof v === 'string')\n .join(' ');\n}\n","import { Injectable, signal, computed, WritableSignal } from '@angular/core';\nimport { BladeDefinition } from '../models/blade.model';\nimport { BladeParameter } from '../models/blade-parameter.model';\nimport { PanoramaDefinition, createPanorama, PositionedTile, layoutTiles } from '../models/panorama.model';\nimport { NotificationDefinition, createNotificationPanel } from '../models/notification.model';\nimport { AvatarMenuDefinition, AvatarMenuItem, createAvatarMenu } from '../models/avatar-menu.model';\nimport { TileDefinition } from '../models/tile-definition.model';\nimport { UserAccount } from '../models/user-account.model';\nimport { PortalConfig } from '../models/portal-config.model';\n\n/**\n * Central state service for the angular-portal-azure library.\n * Replaces v0.2.346's PortalService + Panorama + AreaNotification state.\n *\n * All state is managed via Angular signals for reactive updates.\n */\n@Injectable({ providedIn: 'root' })\nexport class PortalService {\n /** The blade stack — ordered left-to-right */\n readonly blades: WritableSignal<BladeDefinition[]> = signal([]);\n\n /** Panorama (startboard/dashboard) state */\n readonly panorama: WritableSignal<PanoramaDefinition> = signal(createPanorama(''));\n\n /** Notification panel state */\n readonly notification: WritableSignal<NotificationDefinition> = signal(createNotificationPanel());\n\n /** Avatar menu state */\n readonly avatarMenu: WritableSignal<AvatarMenuDefinition> = signal(createAvatarMenu());\n\n /** Shared parameter for passing data between blades */\n readonly parameter: WritableSignal<BladeParameter> = signal({ action: 'none', itemId: 0 });\n\n /** Portal theme identifier */\n readonly theme: WritableSignal<string> = signal('azure-blue');\n\n /** Whether the panorama is visible (true when no blades are open) */\n readonly isPanoramaVisible = computed(() => this.blades().length === 0);\n\n /** Number of open blades */\n readonly bladeCount = computed(() => this.blades().length);\n\n /** Positioned tiles with layout coordinates */\n readonly positionedTiles = computed(() => {\n const pano = this.panorama();\n return pano.tiles;\n });\n\n /**\n * Initialize the portal with configuration.\n * Called by providePortalAzure() during app bootstrap.\n */\n configure(config: PortalConfig): void {\n this.panorama.update((p) => ({\n ...p,\n title: config.title,\n tiles: config.tiles ? layoutTiles(config.tiles) : [],\n isTilesLoaded: !!config.tiles,\n showTiles: true,\n }));\n\n if (config.userAccount) {\n this.avatarMenu.update((m) => ({\n ...m,\n userAccount: config.userAccount!,\n }));\n }\n\n if (config.theme) {\n this.theme.set(config.theme);\n }\n }\n\n /** Update the portal title */\n setTitle(title: string): void {\n this.panorama.update((p) => ({ ...p, title }));\n }\n\n /** Update the user account */\n setUserAccount(userAccount: UserAccount): void {\n this.avatarMenu.update((m) => ({ ...m, userAccount }));\n }\n\n /** Set tiles on the startboard */\n setTiles(tiles: TileDefinition[]): void {\n this.panorama.update((p) => ({\n ...p,\n tiles: layoutTiles(tiles),\n isTilesLoaded: true,\n }));\n }\n\n /** Set blade parameter for inter-blade communication */\n setParameter(param: Partial<BladeParameter>): void {\n this.parameter.update((p) => ({ ...p, ...param }));\n }\n\n /** Clear the blade parameter back to defaults */\n clearParameter(): void {\n this.parameter.set({ action: 'none', itemId: 0 });\n }\n\n // --- Notification panel ---\n\n /** Show the notification panel */\n showNotification(path: string, width: number = 250): void {\n this.notification.update((n) => ({\n ...n,\n path,\n width,\n isVisible: true,\n }));\n }\n\n /** Hide the notification panel */\n hideNotification(): void {\n this.notification.update((n) => ({\n ...n,\n path: '',\n isVisible: false,\n }));\n }\n\n // --- Avatar menu ---\n\n /** Toggle avatar menu open/close */\n toggleAvatarMenu(): void {\n this.avatarMenu.update((m) => ({ ...m, isOpen: !m.isOpen }));\n }\n\n /** Close avatar menu */\n closeAvatarMenu(): void {\n this.avatarMenu.update((m) => ({ ...m, isOpen: false }));\n }\n\n /** Set avatar menu items */\n setAvatarMenuItems(items: AvatarMenuItem[]): void {\n this.avatarMenu.update((m) => ({ ...m, items }));\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { PortalService } from './portal.service';\nimport { BladeDefinition, createBlade, AddBladeEventArgs } from '../models/blade.model';\n\n/**\n * Blade stack management service.\n * Replaces v0.2.346's AreaBlades class.\n *\n * Manages the blade stack: adding, removing, cascade-closing,\n * and panorama visibility toggling.\n */\n@Injectable({ providedIn: 'root' })\nexport class BladeService {\n private readonly portal = inject(PortalService);\n\n /**\n * Set the first blade (e.g., when opening a top-level item from a tile).\n * Clears all existing blades, hides panorama, and adds the new blade.\n *\n * Ported from AreaBlades.setFirstBlade() in v0.2.346.\n */\n setFirstBlade(path: string, title: string = '', width: number = 315): BladeDefinition {\n this.portal.blades.set([]);\n const blade = createBlade(path.toLowerCase(), title, width);\n this.portal.blades.set([blade]);\n return blade;\n }\n\n /**\n * Add a blade to the stack. If senderPath is provided, all blades\n * after the sender are removed first (cascade close).\n *\n * Ported from AreaBlades.addBlade() in v0.2.346.\n */\n addBlade(path: string, senderPath: string = '', title: string = '', width: number = 315): BladeDefinition | undefined {\n if (!path) return undefined;\n\n const normalizedPath = path.toLowerCase();\n const blades = this.portal.blades();\n\n // Check if blade already exists\n const existing = blades.find((b) => b.path === normalizedPath);\n if (existing) {\n return existing;\n }\n\n // Cascade close: remove blades after the sender\n if (senderPath) {\n this.clearChild(senderPath);\n }\n\n const blade = createBlade(normalizedPath, title, width);\n this.portal.blades.update((b) => [...b, blade]);\n return blade;\n }\n\n /**\n * Open a blade from a navigation event (e.g., tile click, nav item click).\n * Wraps addBlade with AddBladeEventArgs for compatibility.\n */\n openBlade(args: AddBladeEventArgs, title: string = '', width: number = 315): BladeDefinition | undefined {\n return this.addBlade(args.path, args.pathSender, title, width);\n }\n\n /**\n * Clear all blades. Shows panorama if appropriate.\n * Ported from AreaBlades.clearAll() in v0.2.346.\n */\n clearAll(): void {\n this.portal.blades.set([]);\n }\n\n /**\n * Remove a specific blade and all blades to its right.\n * This is what happens when a blade is closed.\n *\n * Ported from AreaBlades.clearPath() in v0.2.346.\n */\n clearPath(path: string): void {\n const normalizedPath = path.toLowerCase();\n const blades = this.portal.blades();\n const index = blades.findIndex((b) => b.path === normalizedPath);\n\n if (index >= 0) {\n this.portal.blades.set(blades.slice(0, index));\n } else {\n // Check notification area\n const notif = this.portal.notification();\n if (notif.path === normalizedPath) {\n this.portal.hideNotification();\n }\n }\n }\n\n /**\n * Remove all blades AFTER a given path (keeps the blade itself).\n * Used for cascade close when a blade opens a child.\n *\n * Ported from AreaBlades.clearChild() in v0.2.346.\n */\n clearChild(path: string): void {\n if (!path) return;\n\n const normalizedPath = path.toLowerCase();\n const blades = this.portal.blades();\n const index = blades.findIndex((b) => b.path === normalizedPath);\n\n if (index >= 0) {\n this.portal.blades.set(blades.slice(0, index + 1));\n }\n }\n\n /**\n * Remove blades at and beyond a specific 1-based level.\n * Ported from AreaBlades.clearLevel() in v0.2.346.\n */\n clearLevel(level: number): void {\n const adjustedLevel = level <= 0 ? 1 : level;\n const blades = this.portal.blades();\n if (adjustedLevel <= blades.length) {\n this.portal.blades.set(blades.slice(0, adjustedLevel - 1));\n }\n }\n\n /**\n * Remove only the last (rightmost) blade.\n * Ported from AreaBlades.clearLastLevel() in v0.2.346.\n */\n clearLastLevel(): void {\n const blades = this.portal.blades();\n if (blades.length > 0) {\n this.portal.blades.set(blades.slice(0, -1));\n }\n }\n\n /**\n * Close a specific blade by its definition reference.\n * Removes the blade and all blades to its right.\n */\n closeBlade(blade: BladeDefinition): void {\n this.clearPath(blade.path);\n }\n\n /**\n * Get a blade by path, if it exists in the stack.\n */\n getBlade(path: string): BladeDefinition | undefined {\n return this.portal.blades().find((b) => b.path === path.toLowerCase());\n }\n\n /**\n * Check if a blade with the given path is currently open.\n */\n isBladOpen(path: string): boolean {\n return this.portal.blades().some((b) => b.path === path.toLowerCase());\n }\n}\n","import { EnvironmentProviders, makeEnvironmentProviders, APP_INITIALIZER, inject } from '@angular/core';\nimport { PortalConfig } from '../models/portal-config.model';\nimport { PortalService } from './portal.service';\n\n/**\n * Provide the angular-portal-azure library configuration.\n *\n * Usage in app.config.ts:\n * ```typescript\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * providePortalAzure({\n * title: 'My Portal',\n * tiles: [...],\n * theme: 'azure-blue',\n * }),\n * ],\n * };\n * ```\n *\n * New in v0.3.0 — no equivalent in v0.2.346 (which used PortalShell constructor).\n */\nexport function providePortalAzure(config: PortalConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: APP_INITIALIZER,\n multi: true,\n useFactory: () => {\n const portalService = inject(PortalService);\n return () => portalService.configure(config);\n },\n },\n ]);\n}\n","import { Component, input, output } from '@angular/core';\nimport { PositionedTile } from '../../models/panorama.model';\n\n/**\n * Individual dashboard tile.\n * Ported from the tile section in home.html (v0.2.346).\n *\n * Usage:\n * ```html\n * <apa-tile [tile]=\"myTile\" (tileClick)=\"onTileClick($event)\" />\n * ```\n */\n@Component({\n selector: 'apa-tile',\n standalone: true,\n styles: [`:host { display: contents; }`],\n template: `\n <section\n class=\"fxs-tile fx-rightClick fxs-flowlayout-element\"\n [class.fxs-tilesize-normal]=\"tile().size === 'normal'\"\n [class.fxs-tilesize-mini]=\"tile().size === 'mini'\"\n [class.fxs-tilesize-herowide]=\"tile().size === 'herowide'\"\n [class.fxs-tilesize-small]=\"tile().size === 'small'\">\n <div class=\"fxs-part fxs-part-clickable\" (click)=\"onClick()\" style=\"cursor:pointer;\">\n <header class=\"fxs-part-title\">\n <h2 class=\"msportalfx-tooltip-overflow\">{{ tile().title }}</h2>\n @if (tile().subtitle) {\n <h3 class=\"msportalfx-tooltip-overflow\">{{ tile().subtitle }}</h3>\n }\n </header>\n <section class=\"fxs-part-content css-scope-HubsExtension\"></section>\n </div>\n <div class=\"fxs-tile-overlay\"></div>\n </section>\n `,\n})\nexport class TileComponent {\n readonly tile = input.required<PositionedTile>();\n readonly tileClick = output<PositionedTile>();\n\n onClick(): void {\n this.tileClick.emit(this.tile());\n }\n}\n","import { Component, inject } from '@angular/core';\nimport { PortalService } from '../../services/portal.service';\nimport { BladeService } from '../../services/blade.service';\nimport { TileComponent } from '../tile/tile.component';\nimport { PositionedTile } from '../../models/panorama.model';\n\n/**\n * Panorama (startboard/dashboard) component.\n * Ported from the fxs-panorama-homearea section in home.html (v0.2.346).\n *\n * Displays tiles on the startboard. When a tile is clicked, it opens\n * the first blade via BladeService.setFirstBlade().\n *\n * Usage:\n * ```html\n * <apa-panorama />\n * ```\n */\n@Component({\n selector: 'apa-panorama',\n standalone: true,\n imports: [TileComponent],\n styles: [`:host { display: contents; }`],\n template: `\n @if (portal.isPanoramaVisible()) {\n <div class=\"fxs-panorama-homearea\" [class.collapsed]=\"!panorama().showTiles\">\n <div class=\"fxs-startboard-target fxs-startboard fx-rightClick\" [class.collapsed]=\"!panorama().showTiles\">\n @if (panorama().tiles.length === 0 && panorama().isTilesLoaded) {\n <div class=\"fxs-part fxs-part-clickable\" style=\"background-color:var(--apa-surface-raised); padding:25px; max-width:800px; margin-bottom:15px; height:auto;\">\n <header class=\"fxs-part-title\" style=\"color:var(--apa-text)\">\n <h3 class=\"msportalfx-tooltip-overflow\">Keine Applikationen zugeordnet</h3>\n <p class=\"msportalfx-tooltip-overflow\" style=\"margin:0;padding:0\">\n Wende dich bitte an den Administrator, damit die Applikationen zugeordnet werden können.\n </p>\n </header>\n </div>\n }\n <div class=\"fxs-startboard-layout fxs-flowlayout\">\n <div class=\"fxs-flowlayout-childcontainer\">\n @for (tile of panorama().tiles; track tile.bladePath) {\n <apa-tile [tile]=\"tile\" (tileClick)=\"onTileClick($event)\" />\n }\n </div>\n </div>\n </div>\n </div>\n }\n `,\n})\nexport class PanoramaComponent {\n protected readonly portal = inject(PortalService);\n private readonly bladeService = inject(BladeService);\n\n protected panorama = this.portal.panorama;\n\n onTileClick(tile: PositionedTile): void {\n this.bladeService.setFirstBlade(tile.bladePath, tile.title);\n }\n}\n","import { Component, inject, signal, ElementRef, afterNextRender, effect, Injector } from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { PortalService } from '../../services/portal.service';\nimport { getUserDisplayName } from '../../models/user-account.model';\n\n/**\n * Root portal shell component.\n * Ported from the fxs-portal structure in home.html (v0.2.346).\n *\n * Provides the top bar (with portal title and avatar menu),\n * and the main content area. Child components (panorama, blade-host,\n * notification-panel) are projected via content projection.\n *\n * Usage:\n * ```html\n * <apa-portal-layout>\n * <apa-panorama />\n * <apa-blade-host />\n * </apa-portal-layout>\n * ```\n */\n@Component({\n selector: 'apa-portal-layout',\n standalone: true,\n template: `\n <div class=\"fxs-portal fxs-theme-blue\">\n <!-- Top bar -->\n <div class=\"fxs-topbar\">\n <div style=\"padding-left:25px;\">\n <a href=\"#\" class=\"fxs-topbar-home fxs-has-hover\" (click)=\"onHomeClick($event)\">\n {{ portal.panorama().title }}\n </a>\n </div>\n <div style=\"display:flex; align-items:center; gap:12px; padding-right:10px;\">\n <button class=\"apa-darkmode-toggle fxs-has-hover\"\n (click)=\"toggleDarkMode()\"\n [attr.aria-label]=\"isDark() ? 'Switch to light mode' : 'Switch to dark mode'\"\n [attr.title]=\"isDark() ? 'Light mode' : 'Dark mode'\">\n <i [class]=\"isDark() ? 'ti ti-sun' : 'ti ti-moon'\"></i>\n </button>\n <div class=\"fxs-avatarmenu-tenant-container\" style=\"position:relative;\">\n <a class=\"apa-avatar-trigger fxs-has-hover\" (click)=\"portal.toggleAvatarMenu()\">\n <span class=\"apa-avatar-initials\">{{ initials() }}</span>\n <span class=\"apa-avatar-info\">\n <span class=\"apa-avatar-name\">{{ displayName() }}</span>\n <span class=\"apa-avatar-email\">{{ portal.avatarMenu().userAccount.userName }}</span>\n </span>\n <i class=\"ti\" [class.ti-chevron-down]=\"!portal.avatarMenu().isOpen\"\n [class.ti-chevron-up]=\"portal.avatarMenu().isOpen\"></i>\n </a>\n @if (portal.avatarMenu().isOpen && portal.avatarMenu().items.length > 0) {\n <div class=\"apa-avatar-dropdown\">\n @for (item of portal.avatarMenu().items; track item.href) {\n <a class=\"apa-avatar-dropdown-item\" [href]=\"item.href\">\n @if (item.icon) {\n <i [class]=\"item.icon\"></i>\n }\n <span>{{ item.label }}</span>\n </a>\n }\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Main content area -->\n <div class=\"fxs-portal-content fxs-panorama\"\n [style.margin-right.px]=\"notificationMargin()\">\n <ng-content />\n </div>\n <!-- Footer -->\n <div class=\"fxs-portal-footer\"></div>\n </div>\n `,\n})\nexport class PortalLayoutComponent {\n protected readonly portal = inject(PortalService);\n private static readonly STORAGE_KEY = 'apa-dark-mode';\n private readonly document = inject(DOCUMENT);\n private readonly elementRef = inject(ElementRef);\n private readonly injector = inject(Injector);\n protected readonly isDark = signal(false);\n\n constructor() {\n const stored = localStorage.getItem(PortalLayoutComponent.STORAGE_KEY);\n const dark = stored === 'true';\n this.applyTheme(dark);\n\n // Scroll to the last blade whenever the blade stack changes\n const injector = this.injector;\n effect(() => {\n const blades = this.portal.blades();\n if (blades.length === 0) return;\n afterNextRender(() => {\n this.scrollToLastBlade();\n }, { injector });\n });\n }\n\n protected toggleDarkMode(): void {\n const dark = !this.isDark();\n localStorage.setItem(PortalLayoutComponent.STORAGE_KEY, String(dark));\n this.applyTheme(dark);\n }\n\n private applyTheme(dark: boolean): void {\n this.isDark.set(dark);\n this.document.documentElement.classList.toggle('apa-dark', dark);\n this.document.documentElement.classList.toggle('apa-light', !dark);\n }\n\n protected displayName(): string {\n const account = this.portal.avatarMenu().userAccount;\n return getUserDisplayName(account);\n }\n\n protected initials(): string {\n const a = this.portal.avatarMenu().userAccount;\n const f = (a.firstName || '')[0] || '';\n const l = (a.lastName || '')[0] || '';\n return (f + l).toUpperCase() || '?';\n }\n\n protected notificationMargin(): number {\n const notif = this.portal.notification();\n return notif.isVisible ? notif.width : 0;\n }\n\n protected onHomeClick(event: Event): void {\n event.preventDefault();\n // Clear all blades to show panorama\n this.portal.blades.set([]);\n }\n\n private scrollToLastBlade(): void {\n const scrollContainer = this.elementRef.nativeElement.querySelector('.fxs-portal-content');\n if (!scrollContainer) return;\n\n const bladeElements = scrollContainer.querySelectorAll('.azureportalblade');\n if (bladeElements.length === 0) return;\n\n const lastBlade = bladeElements[bladeElements.length - 1] as HTMLElement;\n const scrollRect = scrollContainer.getBoundingClientRect();\n const bladeRect = lastBlade.getBoundingClientRect();\n\n // Blade is already fully visible — no scroll needed\n if (bladeRect.left >= scrollRect.left && bladeRect.right <= scrollRect.right) {\n return;\n }\n\n const currentScroll = scrollContainer.scrollLeft;\n const viewportWidth = scrollContainer.clientWidth;\n\n let targetScroll: number;\n\n if (bladeElements.length >= 2) {\n // Use the previous blade's right edge (= where the new blade starts)\n const prevBlade = bladeElements[bladeElements.length - 2] as HTMLElement;\n const prevRect = prevBlade.getBoundingClientRect();\n // Distance from viewport's left edge to the previous blade's right edge\n const delta = prevRect.right - scrollRect.left;\n targetScroll = currentScroll + delta;\n } else {\n // First blade — scroll to show it\n targetScroll = currentScroll + (bladeRect.left - scrollRect.left);\n }\n\n // Cap scroll movement to at most one viewport width\n targetScroll = Math.min(targetScroll, currentScroll + viewportWidth);\n\n scrollContainer.scrollTo({ left: targetScroll, behavior: 'smooth' });\n }\n}\n","import { Component, input } from '@angular/core';\nimport { BladeCommand } from '../../models/blade-command.model';\n\n/**\n * Command bar for a blade.\n * Ported from the fxs-commandBar section in blade.html (v0.2.346).\n *\n * Replaces the 18 individual command buttons with a dynamic BladeCommand[] array.\n *\n * Usage:\n * ```html\n * <apa-command-bar [commands]=\"blade.commands\" />\n * ```\n */\n@Component({\n selector: 'apa-command-bar',\n standalone: true,\n styles: [`:host { display: block; }`],\n template: `\n <div class=\"fxs-commandBar\">\n <ul class=\"fxs-commandBar-itemList\">\n @for (cmd of visibleCommands(); track cmd.key) {\n <li>\n <a class=\"fxs-commandBar-item\"\n [class.apa-disable-click]=\"!cmd.enabled\"\n (click)=\"onCommand(cmd)\">\n <span class=\"fxs-commandBar-item-text\">{{ cmd.label }}</span>\n @if (cmd.icon) {\n <span class=\"fxs-commandBar-item-icon apa-commandbar-icon\">\n <span [class]=\"cmd.icon\"></span>\n </span>\n }\n </a>\n </li>\n }\n </ul>\n </div>\n `,\n})\nexport class CommandBarComponent {\n readonly commands = input<BladeCommand[]>([]);\n\n visibleCommands(): BladeCommand[] {\n return this.commands().filter((c) => c.visible);\n }\n\n onCommand(cmd: BladeCommand): void {\n if (cmd.enabled && cmd.action) {\n cmd.action();\n }\n }\n}\n","import { Component, input, output, inject } from '@angular/core';\nimport { BladeDefinition } from '../../models/blade.model';\nimport { BladeService } from '../../services/blade.service';\nimport { CommandBarComponent } from '../command-bar/command-bar.component';\n\n/**\n * Blade chrome component — the visual container for a single blade.\n * Ported from blade.html (v0.2.346).\n *\n * Renders the blade header (status bar, close/maximize buttons, title,\n * command bar) and projects blade content via <ng-content>.\n *\n * Usage:\n * ```html\n * <apa-blade [blade]=\"myBlade\">\n * <p>Blade content here</p>\n * </apa-blade>\n * ```\n */\n@Component({\n selector: 'apa-blade',\n standalone: true,\n imports: [CommandBarComponent],\n styles: [`:host { display: block; height: 100%; }`],\n template: `\n <section class=\"fxs-blade-locked fxs-blade fx-rightClick fxs-bladesize-small\"\n [style.width.px]=\"blade().width\">\n <!-- Header -->\n <header class=\"fxs-blade-header\">\n <!-- Status bar -->\n <div class=\"fxs-blade-statusbar-wrapper\">\n <div class=\"fxs-blade-statusbar\"\n [class.apa-statusbar-info]=\"blade().statusBar.style === 'info'\"\n [class.apa-statusbar-error]=\"blade().statusBar.style === 'error' || blade().statusBar.style === 'warning'\"\n [class.apa-statusbar-success]=\"blade().statusBar.style === 'success'\">\n {{ blade().statusBar.text }}\n </div>\n </div>\n\n <!-- Action buttons -->\n <div class=\"fxs-blade-actions\">\n <button (click)=\"onClose()\" title=\"Schliessen\">\n <svg viewBox=\"0 0 11 11\" role=\"presentation\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\">\n <g>\n <polygon class=\"msportal-fx-svg-placeholder\" points=\"10.4,1.4 9.6,0.6 5.5,4.7 1.4,0.6 0.6,1.4 4.7,5.5 0.6,9.6 1.4,10.4 5.5,6.3 9.6,10.4 10.4,9.6 6.3,5.5\"/>\n </g>\n </svg>\n </button>\n </div>\n\n <!-- Title -->\n <div class=\"fxs-blade-title\">\n <div class=\"fxs-blade-title-text-container\">\n <h2>{{ blade().title }}</h2>\n @if (blade().subtitle) {\n <h3>{{ blade().subtitle }}</h3>\n }\n </div>\n </div>\n\n <!-- Command bar -->\n <div class=\"fxs-blade-commandBarContainer\">\n <apa-command-bar [commands]=\"blade().commands\" />\n </div>\n </header>\n\n <!-- Content area -->\n <div class=\"fxs-blade-content fxs-pannable\">\n <div class=\"fxs-blade-stacklayout\">\n <div class=\"fxs-stacklayout-child\">\n <ng-content />\n </div>\n </div>\n </div>\n </section>\n `,\n})\nexport class BladeComponent {\n readonly blade = input.required<BladeDefinition>();\n readonly bladeClose = output<BladeDefinition>();\n\n private readonly bladeService = inject(BladeService);\n\n onClose(): void {\n const b = this.blade();\n this.bladeClose.emit(b);\n this.bladeService.closeBlade(b);\n }\n}\n","import { Component, inject } from '@angular/core';\nimport { PortalService } from '../../services/portal.service';\nimport { BladeComponent } from '../blade/blade.component';\n\n/**\n * Blade host — renders the blade stack (journey area).\n * Ported from the apa-blade-area section in home.html (v0.2.346).\n *\n * Each blade in the stack is rendered horizontally. When a new blade\n * is added, the portal layout scrolls to show it.\n *\n * Consumer apps provide blade content via the [bladeTemplate] input\n * or by routing. For now, blades are rendered with their path as content.\n *\n * Usage:\n * ```html\n * <apa-blade-host />\n * ```\n */\n@Component({\n selector: 'apa-blade-host',\n standalone: true,\n imports: [BladeComponent],\n styles: [`:host { display: block; height: 100%; }`],\n template: `\n <div id=\"apa-blade-area\" class=\"fxs-journey-target fxs-journey\">\n <div class=\"fxs-journey-layout fxs-stacklayout fxs-stacklayout-horizontal\">\n @for (blade of portal.blades(); track blade.path) {\n <div class=\"azureportalblade fxs-stacklayout-child\">\n <apa-blade [blade]=\"blade\">\n <!-- Default content: blade path (consumers override via content projection or custom templates) -->\n <p style=\"padding:25px; color:var(--apa-text-secondary);\">{{ blade.path }}</p>\n </apa-blade>\n </div>\n }\n </div>\n </div>\n `,\n})\nexport class BladeHostComponent {\n protected readonly portal = inject(PortalService);\n}\n","import { Component, input, inject } from '@angular/core';\nimport { BladeNavItem } from '../../models/blade-nav-item.model';\nimport { BladeService } from '../../services/blade.service';\n\n/**\n * Navigation blade content — renders a list of nav items.\n * Ported from nav.html (v0.2.346).\n *\n * Each nav item shows an icon and title. Clicking a row opens\n * the target blade via BladeService.\n *\n * Usage:\n * ```html\n * <apa-blade [blade]=\"navBlade\">\n * <apa-blade-nav [items]=\"navItems\" [senderPath]=\"navBlade.path\" />\n * </apa-blade>\n * ```\n */\n@Component({\n selector: 'apa-blade-nav',\n standalone: true,\n styles: [`:host { display: flex; flex-direction: column; flex: 1; }`],\n template: `\n <table class=\"azc-grid-full azc-grid-multiselectable\">\n <colgroup>\n <col class=\"col0\" style=\"width:28px;\">\n <col class=\"col1\">\n </colgroup>\n <tbody class=\"azc-grid-groupdata\" role=\"rowgroup\">\n @for (item of visibleItems(); track item.bladePath) {\n <tr role=\"row\" style=\"cursor:pointer\" (click)=\"onItemClick(item)\">\n <td class=\"msportalfx-gridcolumn-asseticon\" role=\"gridcell\">\n @if (item.cssClass) {\n <i [class]=\"item.cssClass\"></i>\n }\n </td>\n <td tabindex=\"0\" role=\"gridcell\">\n @if (item.hrefPath) {\n <a [href]=\"item.hrefPath\" target=\"_blank\">{{ item.title }}</a>\n } @else {\n <span>{{ item.title }}</span>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n `,\n})\nexport class BladeNavComponent {\n readonly items = input<BladeNavItem[]>([]);\n readonly senderPath = input<string>('');\n\n private readonly bladeService = inject(BladeService);\n\n visibleItems(): BladeNavItem[] {\n return this.items().filter((item) => item.isVisible);\n }\n\n onItemClick(item: BladeNavItem): void {\n if (item.hrefPath) {\n // External link — let the <a> handle it\n return;\n }\n if (item.bladePath) {\n this.bladeService.addBlade(item.bladePath, this.senderPath());\n }\n item.callback?.();\n }\n}\n","import { Component, input, output, inject } from '@angular/core';\nimport { BladeService } from '../../services/blade.service';\nimport { filterItems } from '../../models/filter.util';\n\n/**\n * Grid/list blade content — renders a searchable list of items.\n * Ported from grid.html + BladeGrid (v0.2.346).\n *\n * Displays items in a table with optional search filtering.\n * Each row shows a title and optional subtitle. Clicking a row\n * opens the target blade.\n *\n * Usage:\n * ```html\n * <apa-blade [blade]=\"gridBlade\">\n * <apa-blade-grid\n * [items]=\"items\"\n * [senderPath]=\"gridBlade.path\"\n * [displayField]=\"'title'\"\n * (itemClick)=\"onItemClick($event)\" />\n * </apa-blade>\n * ```\n */\n@Component({\n selector: 'apa-blade-grid',\n standalone: true,\n styles: [`:host { display: flex; flex-direction: column; flex: 1; }`],\n template: `\n @if (searchable()) {\n <div style=\"padding:0 0 10px 0;\">\n <input type=\"text\"\n class=\"form-control\"\n placeholder=\"Suchen...\"\n [value]=\"searchText\"\n (input)=\"onSearchInput($event)\" />\n </div>\n }\n <table class=\"azc-grid-full azc-grid-multiselectable\">\n <colgroup>\n <col class=\"col0\" style=\"width:41px;\">\n <col class=\"col1\">\n </colgroup>\n <tbody class=\"azc-grid-groupdata\" role=\"rowgroup\">\n @for (item of filteredItems(); track $index) {\n <tr role=\"row\" style=\"cursor:pointer\" (click)=\"onRowClick(item)\">\n <td class=\"msportalfx-gridcolumn-asseticon\" role=\"gridcell\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"msportal-fx-svg-placeholder\" viewBox=\"0 0 50 50\" focusable=\"false\" style=\"height:21px;width:21px;\">\n <rect class=\"msportalfx-svg-c04\" x=\"19.8\" y=\"39.4\" width=\"10.6\" height=\"3.4\"/>\n <polygon class=\"msportalfx-svg-c04\" points=\"23.1,50 27,50 30.3,46.5 19.8,46.5\"/>\n <path class=\"msportalfx-svg-c20\" d=\"M41.2 14.7v-.3c0-7.7-6.6-14.1-14.7-14.2-.2-.3-4.8.1-4.8.1-7.3.9-13 7-13 14.1 0 .2-.8 5.8 4.9 10.5 2.6 2.3 5.3 8.5 5.7 10.3l.3.6h10.6l.3-.6c.4-1.8 3.2-8 5.7-10.2C41.9 20.2 41.2 14.9 41.2 14.7z\"/>\n </svg>\n </td>\n <td tabindex=\"0\" role=\"gridcell\">\n <span>{{ getDisplayValue(item) }}</span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n `,\n})\nexport class BladeGridComponent {\n readonly items = input<any[]>([]);\n readonly senderPath = input<string>('');\n readonly displayField = input<string>('title');\n readonly bladePathField = input<string>('bladePath');\n readonly searchable = input<boolean>(true);\n readonly itemClick = output<any>();\n\n searchText = '';\n\n private readonly bladeService = inject(BladeService);\n\n filteredItems(): any[] {\n return filterItems(this.items(), this.searchText);\n }\n\n getDisplayValue(item: any): string {\n return item[this.displayField()] ?? '';\n }\n\n onSearchInput(event: Event): void {\n this.searchText = (event.target as HTMLInputElement).value;\n }\n\n onRowClick(item: any): void {\n this.itemClick.emit(item);\n const bladePath = item[this.bladePathField()];\n if (bladePath) {\n this.bladeService.addBlade(bladePath, this.senderPath());\n }\n }\n}\n","import { Component, input } from '@angular/core';\nimport { BladeDataDefinition } from '../../models/blade-data.model';\nimport { BladeCommand, createCommand } from '../../models/blade-command.model';\n\n/**\n * Detail/edit blade content — renders a form area for editing an item.\n * Ported from BladeDetail<T> (v0.2.346).\n *\n * Provides a content projection area for forms. The blade's commands\n * (save, delete, cancel, new) are managed via the blade definition.\n *\n * This is a thin wrapper that projects content and provides\n * convenience methods for setting up typical detail blade commands.\n *\n * Usage:\n * ```html\n * <apa-blade [blade]=\"detailBlade\">\n * <apa-blade-detail [blade]=\"detailBlade\">\n * <form>\n * <!-- form fields here -->\n * </form>\n * </apa-blade-detail>\n * </apa-blade>\n * ```\n */\n@Component({\n selector: 'apa-blade-detail',\n standalone: true,\n styles: [`:host { display: flex; flex-direction: column; flex: 1; }\n .apa-blade-detail { flex: 1; }`],\n template: `\n <div class=\"apa-blade-detail\">\n <ng-content />\n </div>\n `,\n})\nexport class BladeDetailComponent {\n readonly blade = input.required<BladeDataDefinition<any>>();\n}\n\n/**\n * Create standard detail blade commands (new, save, delete, cancel).\n * Convenience function for setting up typical detail/edit blade commands\n * matching the v0.2.346 BladeDetail default commands.\n */\nexport function createDetailCommands(handlers: {\n onNew?: () => void;\n onSave?: () => void;\n onDelete?: () => void;\n onCancel?: () => void;\n}): BladeCommand[] {\n const commands: BladeCommand[] = [];\n\n if (handlers.onNew) {\n commands.push(createCommand('new', 'neu', handlers.onNew));\n }\n if (handlers.onSave) {\n commands.push(createCommand('save', 'speichern', handlers.onSave));\n }\n if (handlers.onDelete) {\n commands.push(createCommand('delete', 'loeschen', handlers.onDelete));\n }\n if (handlers.onCancel) {\n commands.push(createCommand('cancel', 'abbrechen', handlers.onCancel));\n }\n\n return commands;\n}\n","import { Component, inject } from '@angular/core';\nimport { PortalService } from '../../services/portal.service';\n\n/**\n * Notification panel — right-side overlay panel.\n * Ported from apa-notification-area in home.html (v0.2.346).\n *\n * Usage:\n * ```html\n * <apa-notification-panel>\n * <!-- Custom notification content -->\n * </apa-notification-panel>\n * ```\n */\n@Component({\n selector: 'apa-notification-panel',\n standalone: true,\n styles: [`:host { display: contents; }`],\n template: `\n @if (portal.notification().isVisible) {\n <div class=\"apa-notification-panel\"\n [style.width.px]=\"portal.notification().width\">\n <button class=\"apa-notification-close\" (click)=\"onClose()\" title=\"Schliessen\">\n <svg viewBox=\"0 0 11 11\" role=\"presentation\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\">\n <polygon class=\"msportal-fx-svg-placeholder\" points=\"10.4,1.4 9.6,0.6 5.5,4.7 1.4,0.6 0.6,1.4 4.7,5.5 0.6,9.6 1.4,10.4 5.5,6.3 9.6,10.4 10.4,9.6 6.3,5.5\"/>\n </svg>\n </button>\n <ng-content />\n </div>\n }\n `,\n})\nexport class NotificationPanelComponent {\n protected readonly portal = inject(PortalService);\n\n onClose(): void {\n this.portal.hideNotification();\n }\n}\n","import { Component, inject } from '@angular/core';\nimport { PortalService } from '../../services/portal.service';\nimport { getUserDisplayName } from '../../models/user-account.model';\n\n/**\n * Avatar menu — user account dropdown in the portal header.\n * Ported from fxs-avatarmenu CSS structure in v0.2.346.\n *\n * Shows the user's name and email. Clicking toggles a dropdown\n * with optional actions (sign out, etc.).\n *\n * Usage:\n * ```html\n * <apa-avatar-menu>\n * <a href=\"/Account/SignOut\">Abmelden</a>\n * </apa-avatar-menu>\n * ```\n */\n@Component({\n selector: 'apa-avatar-menu',\n standalone: true,\n template: `\n <div class=\"fxs-avatarmenu\">\n <a class=\"fxs-has-hover\" (click)=\"portal.toggleAvatarMenu()\">\n <div class=\"fxs-avatarmenu-header\">\n <span class=\"fxs-avatarmenu-username\">{{ displayName() }}</span>\n <span class=\"fxs-avatarmenu-emailaddress\">{{ userAccount().emailAddress }}</span>\n </div>\n </a>\n @if (portal.avatarMenu().isOpen) {\n <div class=\"fxs-avatarmenu-dropdown\" style=\"display:block;\">\n <ul>\n <ng-content />\n </ul>\n </div>\n }\n </div>\n `,\n})\nexport class AvatarMenuComponent {\n protected readonly portal = inject(PortalService);\n\n protected userAccount() {\n return this.portal.avatarMenu().userAccount;\n }\n\n protected displayName(): string {\n return getUserDisplayName(this.userAccount());\n }\n}\n","import { Component, input, inject } from '@angular/core';\nimport { BladeNavItem } from '../../models/blade-nav-item.model';\nimport { BladeService } from '../../services/blade.service';\n\n/**\n * Sidebar navigation — optional vertical navigation panel.\n * New in v0.3.0 (no equivalent in v0.2.346).\n *\n * Provides a collapsible sidebar with navigation items that\n * open blades when clicked.\n *\n * Usage:\n * ```html\n * <apa-sidebar [items]=\"sidebarItems\" [collapsed]=\"false\" />\n * ```\n */\n@Component({\n selector: 'apa-sidebar',\n standalone: true,\n template: `\n <nav class=\"apa-sidebar\" [class.apa-sidebar-collapsed]=\"collapsed()\">\n @for (item of visibleItems(); track item.bladePath) {\n <a class=\"apa-sidebar-item\"\n (click)=\"onItemClick(item)\"\n style=\"cursor:pointer;\">\n @if (item.cssClass) {\n <i [class]=\"item.cssClass\" class=\"apa-sidebar-icon\"></i>\n }\n @if (!collapsed()) {\n <span class=\"apa-sidebar-label\">{{ item.title }}</span>\n }\n </a>\n }\n </nav>\n `,\n styles: [`\n .apa-sidebar {\n display: flex;\n flex-direction: column;\n background-color: var(--apa-chrome);\n width: 200px;\n height: 100%;\n padding-top: 10px;\n transition: width 0.2s ease;\n }\n .apa-sidebar-collapsed {\n width: 50px;\n }\n .apa-sidebar-item {\n display: flex;\n align-items: center;\n padding: 10px 15px;\n color: var(--apa-chrome-text);\n text-decoration: none;\n font-size: 13px;\n transition: background-color 0.15s ease;\n }\n .apa-sidebar-item:hover {\n background-color: var(--apa-chrome-hover);\n }\n .apa-sidebar-icon {\n margin-right: 10px;\n width: 20px;\n text-align: center;\n }\n .apa-sidebar-collapsed .apa-sidebar-icon {\n margin-right: 0;\n }\n `],\n})\nexport class SidebarComponent {\n readonly items = input<BladeNavItem[]>([]);\n readonly collapsed = input<boolean>(false);\n\n private readonly bladeService = inject(BladeService);\n\n visibleItems(): BladeNavItem[] {\n return this.items().filter((item) => item.isVisible);\n }\n\n onItemClick(item: BladeNavItem): void {\n if (item.bladePath) {\n this.bladeService.setFirstBlade(item.bladePath, item.title);\n }\n item.callback?.();\n }\n}\n","/*\r\n * Public API Surface of @ardimedia/angular-portal-azure\r\n */\r\n\r\n// Models\r\nexport * from './lib/models/blade.model';\r\nexport * from './lib/models/blade-command.model';\r\nexport * from './lib/models/blade-data.model';\r\nexport * from './lib/models/blade-nav-item.model';\r\nexport * from './lib/models/blade-parameter.model';\r\nexport * from './lib/models/status-bar.model';\r\nexport * from './lib/models/tile-definition.model';\r\nexport * from './lib/models/user-account.model';\r\nexport * from './lib/models/notification.model';\r\nexport * from './lib/models/panorama.model';\r\nexport * from './lib/models/avatar-menu.model';\r\nexport * from './lib/models/portal-config.model';\r\nexport * from './lib/models/filter.util';\r\n\r\n// Services\r\nexport * from './lib/services/portal.service';\r\nexport * from './lib/services/blade.service';\r\nexport * from './lib/services/provide-portal-azure';\r\n\r\n// Components\r\nexport * from './lib/components/tile/tile.component';\r\nexport * from './lib/components/panorama/panorama.component';\r\nexport * from './lib/components/portal-layout/portal-layout.component';\r\nexport * from './lib/components/command-bar/command-bar.component';\r\nexport * from './lib/components/blade/blade.component';\r\nexport * from './lib/components/blade-host/blade-host.component';\r\nexport * from './lib/components/blade-nav/blade-nav.component';\r\nexport * from './lib/components/blade-grid/blade-grid.component';\r\nexport * from './lib/components/blade-detail/blade-detail.component';\r\nexport * from './lib/components/notification-panel/notification-panel.component';\r\nexport * from './lib/components/avatar-menu/avatar-menu.component';\r\nexport * from './lib/components/sidebar/sidebar.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ardimedia/angular-portal-azure",
3
- "version": "0.3.0",
3
+ "version": "0.3.3",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^21.1.0",
6
6
  "@angular/core": "^21.1.0"
@@ -197,7 +197,7 @@
197
197
  /* Command bar */
198
198
  --apa-commandbar-color: var(--apa-chrome-text);
199
199
  --apa-commandbar-hover-bg: var(--apa-chrome-hover);
200
- --apa-commandbar-border-color: var(--apa-border-strong);
200
+ --apa-commandbar-border-color: var(--apa-slate-700);
201
201
 
202
202
  /* Tile */
203
203
  --apa-tile-bg: var(--apa-surface);
@@ -361,6 +361,53 @@ a:focus, a:hover {
361
361
  color: var(--apa-chrome-text);
362
362
  }
363
363
 
364
+ /* Avatar trigger */
365
+ .apa-avatar-trigger {
366
+ display: flex;
367
+ align-items: center;
368
+ gap: 10px;
369
+ padding: 4px 8px;
370
+ border-radius: 6px;
371
+ cursor: pointer;
372
+ text-decoration: none;
373
+ }
374
+ .apa-avatar-initials {
375
+ width: 34px;
376
+ height: 34px;
377
+ border-radius: 50%;
378
+ background: var(--apa-slate-600);
379
+ color: #fff;
380
+ font-size: 13px;
381
+ font-weight: 600;
382
+ display: flex;
383
+ align-items: center;
384
+ justify-content: center;
385
+ flex-shrink: 0;
386
+ letter-spacing: 0.5px;
387
+ }
388
+ .apa-avatar-info {
389
+ display: flex;
390
+ flex-direction: column;
391
+ line-height: 1.3;
392
+ text-align: left;
393
+ }
394
+ .apa-avatar-name {
395
+ font-size: 13px;
396
+ font-weight: 500;
397
+ color: var(--apa-chrome-text);
398
+ }
399
+ .apa-avatar-email {
400
+ font-size: 11px;
401
+ opacity: 0.7;
402
+ color: var(--apa-chrome-text);
403
+ }
404
+ .apa-avatar-trigger > i {
405
+ font-size: 14px;
406
+ opacity: 0.6;
407
+ color: var(--apa-chrome-text);
408
+ transition: transform 0.2s ease;
409
+ }
410
+
364
411
  /* ===== Panorama / Startboard ===== */
365
412
  .fxs-panorama {
366
413
  -ms-scroll-chaining: none;
@@ -671,10 +718,8 @@ a:focus, a:hover {
671
718
  transition: height 0.175s ease-in;
672
719
  }
673
720
  .fxs-commandBar > ul.fxs-commandBar-itemList > li {
674
- border-right-color: var(--apa-commandbar-border-color);
675
721
  float: left;
676
722
  margin-bottom: 5px;
677
- border-right: 1px solid transparent;
678
723
  }
679
724
  .fxs-commandBar .fxs-commandBar-item {
680
725
  font-family: var(--apa-font-family-semibold);
@@ -687,14 +732,16 @@ a:focus, a:hover {
687
732
  position: relative;
688
733
  padding: 3px 10px 0;
689
734
  width: auto;
690
- max-width: 90px;
735
+ min-width: 60px;
691
736
  height: 48px;
692
737
  box-sizing: border-box;
693
738
  transition: background-color 0.07s ease-in;
694
739
  cursor: pointer;
740
+ text-align: center;
741
+ border: 1px solid var(--apa-commandbar-border-color);
695
742
  }
696
743
  .fxs-commandBar .fxs-commandBar-item:hover {
697
- background-color: var(--apa-commandbar-hover-bg);
744
+ background-color: rgba(255, 255, 255, 0.1);
698
745
  }
699
746
  .fxs-commandBar .fxs-commandBar-item .fxs-commandBar-item-text {
700
747
  height: 22px;
@@ -703,6 +750,9 @@ a:focus, a:hover {
703
750
  .fxs-commandBar .fxs-commandBar-item .fxs-commandBar-item-icon {
704
751
  position: absolute;
705
752
  bottom: 2px;
753
+ left: 0;
754
+ right: 0;
755
+ text-align: center;
706
756
  }
707
757
  .fxs-commandBar .fxs-commandBar-item .fxs-commandBar-item-icon > svg,
708
758
  .fxs-commandBar .fxs-commandBar-item .fxs-commandBar-item-icon > img {
@@ -806,6 +856,39 @@ a:focus, a:hover {
806
856
  text-overflow: ellipsis;
807
857
  }
808
858
 
859
+ /* ===== Avatar Dropdown (portal-layout) ===== */
860
+ .apa-avatar-dropdown {
861
+ position: absolute;
862
+ top: 100%;
863
+ right: 0;
864
+ min-width: 200px;
865
+ background-color: var(--apa-chrome);
866
+ border: 1px solid var(--apa-border);
867
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
868
+ z-index: 200;
869
+ }
870
+ .apa-avatar-dropdown-item {
871
+ display: flex;
872
+ align-items: center;
873
+ gap: 10px;
874
+ padding: 10px 16px;
875
+ font-size: 13px;
876
+ color: var(--apa-chrome-text);
877
+ text-decoration: none;
878
+ white-space: nowrap;
879
+ cursor: pointer;
880
+ transition: background-color 0.1s ease;
881
+ }
882
+ .apa-avatar-dropdown-item:hover {
883
+ background-color: rgba(255, 255, 255, 0.1);
884
+ color: var(--apa-chrome-text);
885
+ text-decoration: none;
886
+ }
887
+ .apa-avatar-dropdown-item i {
888
+ font-size: 16px;
889
+ opacity: 0.8;
890
+ }
891
+
809
892
  /* ===== Notification Panel ===== */
810
893
  .apa-notification-panel {
811
894
  position: fixed;
@@ -863,15 +946,24 @@ a:focus, a:hover {
863
946
  color: inherit;
864
947
  position: relative;
865
948
  }
866
- .azc-grid table tbody tr td {
949
+ .azc-grid table tbody tr,
950
+ .azc-grid-full tbody tr {
951
+ transition: background-color 0.07s ease-in;
952
+ }
953
+ .azc-grid table tbody tr:hover,
954
+ .azc-grid-full tbody tr:hover {
955
+ background-color: var(--apa-surface-hover);
956
+ }
957
+ .azc-grid table tbody tr td,
958
+ .azc-grid-full tbody tr td {
867
959
  color: var(--apa-text);
868
- height: 33px;
960
+ height: 40px;
869
961
  border-top: 1px solid var(--apa-grid-border-color);
870
962
  border-bottom: 1px solid var(--apa-grid-border-color);
871
963
  white-space: nowrap;
872
964
  overflow: hidden;
873
965
  text-overflow: ellipsis;
874
- padding: 1px 0 1px 10px;
966
+ padding: 6px 10px;
875
967
  }
876
968
  .azc-grid-activateableRow table tbody tr[aria-selected='true'] {
877
969
  background-color: var(--apa-grid-row-selected-bg) !important;
@@ -296,6 +296,17 @@ interface PositionedTile extends TileDefinition {
296
296
  declare function layoutTiles(tiles: TileDefinition[]): PositionedTile[];
297
297
  declare function createPanorama(title: string): PanoramaDefinition;
298
298
 
299
+ /**
300
+ * A single item in the avatar dropdown menu.
301
+ */
302
+ interface AvatarMenuItem {
303
+ /** Display text */
304
+ label: string;
305
+ /** Navigation URL */
306
+ href: string;
307
+ /** Optional icon CSS class, e.g. 'ti ti-settings' */
308
+ icon?: string;
309
+ }
299
310
  /**
300
311
  * Avatar menu definition for the user menu in the portal header.
301
312
  * Ported from AvatarMenu in v0.2.346.
@@ -305,6 +316,8 @@ interface AvatarMenuDefinition {
305
316
  userAccount: UserAccount;
306
317
  /** Whether the avatar dropdown is currently open */
307
318
  isOpen: boolean;
319
+ /** Menu items shown in the dropdown */
320
+ items: AvatarMenuItem[];
308
321
  }
309
322
  declare function createAvatarMenu(): AvatarMenuDefinition;
310
323
 
@@ -383,6 +396,8 @@ declare class PortalService {
383
396
  toggleAvatarMenu(): void;
384
397
  /** Close avatar menu */
385
398
  closeAvatarMenu(): void;
399
+ /** Set avatar menu items */
400
+ setAvatarMenuItems(items: AvatarMenuItem[]): void;
386
401
  static ɵfac: i0.ɵɵFactoryDeclaration<PortalService, never>;
387
402
  static ɵprov: i0.ɵɵInjectableDeclaration<PortalService>;
388
403
  }
@@ -546,6 +561,7 @@ declare class PortalLayoutComponent {
546
561
  protected toggleDarkMode(): void;
547
562
  private applyTheme;
548
563
  protected displayName(): string;
564
+ protected initials(): string;
549
565
  protected notificationMargin(): number;
550
566
  protected onHomeClick(event: Event): void;
551
567
  private scrollToLastBlade;
@@ -777,4 +793,4 @@ declare class SidebarComponent {
777
793
  }
778
794
 
779
795
  export { AvatarMenuComponent, BladeComponent, BladeDetailComponent, BladeGridComponent, BladeHostComponent, BladeNavComponent, BladeService, CommandBarComponent, NotificationPanelComponent, PanoramaComponent, PortalLayoutComponent, PortalService, SidebarComponent, TILE_DIMENSIONS, TileComponent, TileSize, clearStatusBar, createAvatarMenu, createBlade, createCommand, createDataBlade, createDetailCommands, createNavItem, createNotificationPanel, createPanorama, createTile, executeDeleteItem, executeLoadItem, executeLoadItems, executeSaveItem, filterItems, getUserDisplayName, layoutTiles, providePortalAzure, statusBarError, statusBarInfo, statusBarSuccess };
780
- export type { AddBladeEventArgs, ApiException, AvatarMenuDefinition, BladeCommand, BladeDataDefinition, BladeDataLifecycle, BladeDefinition, BladeNavItem, BladeParameter, NotificationDefinition, NotificationLifecycle, PanoramaDefinition, PortalConfig, PositionedTile, StandardCommandKey, StatusBarState, StatusBarStyle, TileDefinition, UserAccount };
796
+ export type { AddBladeEventArgs, ApiException, AvatarMenuDefinition, AvatarMenuItem, BladeCommand, BladeDataDefinition, BladeDataLifecycle, BladeDefinition, BladeNavItem, BladeParameter, NotificationDefinition, NotificationLifecycle, PanoramaDefinition, PortalConfig, PositionedTile, StandardCommandKey, StatusBarState, StatusBarStyle, TileDefinition, UserAccount };