cloud-ide-element 1.1.3 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import * as i1 from '@angular/common';
2
2
  import { CommonModule, NgTemplateOutlet } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { Pipe, Injectable, inject, EventEmitter, ViewContainerRef, forwardRef, ViewChild, Output, Input, Component, ContentChildren, signal, DestroyRef, computed, effect, InjectionToken, Optional, Inject, input, HostListener, Directive, ElementRef, viewChild } from '@angular/core';
4
+ import { Pipe, Injectable, inject, EventEmitter, ViewContainerRef, forwardRef, ViewChild, Output, Input, Component, ContentChildren, signal, DestroyRef, computed, effect, input, HostListener, ChangeDetectionStrategy, Directive, ElementRef, viewChild } from '@angular/core';
5
5
  import * as i2 from '@angular/forms';
6
6
  import { FormsModule, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
7
7
  import { BehaviorSubject, Subject, debounceTime, distinctUntilChanged, takeUntil, Observable, retry, catchError, finalize, throwError, map, of } from 'rxjs';
@@ -946,6 +946,7 @@ class CideInputComponent {
946
946
  }
947
947
  async getControlData() {
948
948
  const cide_element_data = await this.elementService?.getElementData({ sype_key: this.id });
949
+ console.log(cide_element_data, "cide_element_data");
949
950
  if (cide_element_data) {
950
951
  this.label = cide_element_data?.sype_label;
951
952
  this.labelPlacement = (cide_element_data?.sype_label_placement || 'floating');
@@ -5342,241 +5343,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
5342
5343
  type: Output
5343
5344
  }] } });
5344
5345
 
5345
- // Optional app-level provider to supply a resolver without calling into the service
5346
- const PAGE_PATH_RESOLVER = new InjectionToken('PAGE_PATH_RESOLVER');
5347
- class BreadcrumbNavigationService {
5348
- // Default context id (used by shell routes)
5349
- activeContextId = signal('default', ...(ngDevMode ? [{ debugName: "activeContextId" }] : []));
5350
- // Map of contextId -> breadcrumb items
5351
- contextIdToItems = new Map();
5352
- // Signal to store current breadcrumb items for active context
5353
- currentBreadcrumbItems = computed(() => {
5354
- const ctx = this.activeContextId();
5355
- return this.getContextSignal(ctx)();
5356
- }, ...(ngDevMode ? [{ debugName: "currentBreadcrumbItems" }] : []));
5357
- // Signal to store loading state
5358
- isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
5359
- // Registry removed; breadcrumb is resolved via API or direct inputs
5360
- // Optional external resolver to fetch breadcrumb path by page code from API/menu tables
5361
- pagePathResolver = null;
5362
- constructor(resolver) {
5363
- // Initialize with default breadcrumb
5364
- this.ensureContext('default');
5365
- this.setDefaultBreadcrumb('default');
5366
- // Accept resolver from DI if provided
5367
- if (resolver) {
5368
- this.pagePathResolver = resolver;
5369
- }
5370
- else {
5371
- // Try to resolve via token if available
5372
- try {
5373
- const tokenResolver = inject(PAGE_PATH_RESOLVER, { optional: true });
5374
- if (tokenResolver)
5375
- this.pagePathResolver = tokenResolver;
5376
- }
5377
- catch { }
5378
- }
5379
- }
5380
- // Removed default registry: breadcrumb is driven by API resolver or explicit items
5381
- /**
5382
- * Generate breadcrumb items for a given page ID
5383
- * @param pageId - The page identifier
5384
- * @param additionalItems - Optional additional breadcrumb items to append
5385
- * @returns Promise<BreadcrumbNavigationItem[]> - Generated breadcrumb items
5386
- */
5387
- async generateBreadcrumb(pageId, additionalItems = [], contextId = this.activeContextId()) {
5388
- this.isLoading.set(true);
5389
- try {
5390
- const breadcrumbItems = [
5391
- // Root item
5392
- { id: 'root', label: 'Projects', icon: 'home', type: 'root', path: '/' },
5393
- // Current page item (fallback when only pageId is available)
5394
- { id: pageId, label: this.formatPageLabel(pageId), type: 'page' },
5395
- // Additional items
5396
- ...additionalItems
5397
- ];
5398
- this.setContextItems(contextId, breadcrumbItems);
5399
- return breadcrumbItems;
5400
- }
5401
- catch (error) {
5402
- console.error('Error generating breadcrumb:', error);
5403
- return this.getDefaultBreadcrumb();
5404
- }
5405
- finally {
5406
- this.isLoading.set(false);
5407
- }
5408
- }
5409
- /**
5410
- * Generate breadcrumb with parent entity information
5411
- * @param pageId - The page identifier
5412
- * @param parentEntityInfo - Parent entity information
5413
- * @returns Promise<BreadcrumbNavigationItem[]> - Generated breadcrumb items
5414
- */
5415
- async generateBreadcrumbWithParent(pageId, parentEntityInfo, contextId = this.activeContextId()) {
5416
- const additionalItems = [
5417
- {
5418
- id: parentEntityInfo.id,
5419
- label: parentEntityInfo.name,
5420
- icon: parentEntityInfo.type === 'entity' ? 'account_tree' : 'folder',
5421
- type: 'page'
5422
- }
5423
- ];
5424
- return this.generateBreadcrumb(pageId, additionalItems, contextId);
5425
- }
5426
- /**
5427
- * Set or switch the active breadcrumb context (e.g., when focusing a tab/popup)
5428
- */
5429
- setActiveContext(contextId) {
5430
- this.ensureContext(contextId);
5431
- this.activeContextId.set(contextId);
5432
- }
5433
- /**
5434
- * Provide an external resolver that can translate a pageCode to full breadcrumb path
5435
- */
5436
- registerPagePathResolver(resolver) {
5437
- this.pagePathResolver = resolver;
5438
- }
5439
- /**
5440
- * Resolve and set breadcrumb by page code using external API/menu resolver
5441
- */
5442
- async resolveAndSetByPageCode(pageCode, contextId = this.activeContextId()) {
5443
- if (!this.pagePathResolver) {
5444
- console.warn('BreadcrumbNavigationService: No pagePathResolver registered');
5445
- return this.getDefaultBreadcrumb();
5446
- }
5447
- this.isLoading.set(true);
5448
- try {
5449
- const resolved = await this.pagePathResolver(pageCode);
5450
- const items = [
5451
- { id: 'root', label: 'Projects', icon: 'home', type: 'root', path: '/' },
5452
- ...resolved.map(r => ({ id: r.id, label: r.label, icon: r.icon, type: 'page', path: r.path }))
5453
- ];
5454
- this.setContextItems(contextId, items);
5455
- return items;
5456
- }
5457
- catch (e) {
5458
- console.error('Failed to resolve breadcrumb by pageCode', e);
5459
- return this.getDefaultBreadcrumb();
5460
- }
5461
- finally {
5462
- this.isLoading.set(false);
5463
- }
5464
- }
5465
- /**
5466
- * Register a new page in the registry
5467
- * @param pageInfo - Page information to register
5468
- */
5469
- registerPage(pageInfo) { }
5470
- /**
5471
- * Register multiple pages at once
5472
- * @param pages - Array of page information to register
5473
- */
5474
- registerPages(pages) { }
5475
- /**
5476
- * Get current breadcrumb items
5477
- * @returns BreadcrumbNavigationItem[] - Current breadcrumb items
5478
- */
5479
- getCurrentBreadcrumb() {
5480
- return this.currentBreadcrumbItems();
5481
- }
5482
- /**
5483
- * Returns a signal of the current breadcrumb items for binding in UI
5484
- */
5485
- getCurrentBreadcrumbSignal() {
5486
- return this.currentBreadcrumbItems;
5487
- }
5488
- /**
5489
- * Get loading state
5490
- * @returns boolean - Loading state
5491
- */
5492
- isLoadingBreadcrumb() {
5493
- return this.isLoading();
5494
- }
5495
- /**
5496
- * Clear current breadcrumb
5497
- */
5498
- clearBreadcrumb(contextId = this.activeContextId()) {
5499
- this.setContextItems(contextId, []);
5500
- }
5501
- /**
5502
- * Set default breadcrumb
5503
- */
5504
- setDefaultBreadcrumb(contextId) {
5505
- this.setContextItems(contextId, [
5506
- { id: 'root', label: 'Projects', icon: 'home', type: 'root', path: '/' },
5507
- { id: 'ui-kit', label: 'Universal UI Kit (Web)', icon: 'web', type: 'module' },
5508
- { id: 'shape', label: 'Shape', icon: 'shape', type: 'page' }
5509
- ]);
5510
- }
5511
- /**
5512
- * Get default breadcrumb
5513
- * @returns BreadcrumbNavigationItem[] - Default breadcrumb items
5514
- */
5515
- getDefaultBreadcrumb() {
5516
- return [
5517
- { id: 'root', label: 'Projects', icon: 'home', type: 'root', path: '/' },
5518
- { id: 'ui-kit', label: 'Universal UI Kit (Web)', icon: 'web', type: 'module' },
5519
- { id: 'unknown', label: 'Unknown Page', icon: 'help', type: 'page' }
5520
- ];
5521
- }
5522
- /**
5523
- * Format page label from page ID
5524
- * @param pageId - Page identifier
5525
- * @returns string - Formatted page label
5526
- */
5527
- formatPageLabel(pageId) {
5528
- return pageId
5529
- .split('-')
5530
- .map(word => word.charAt(0).toUpperCase() + word.slice(1))
5531
- .join(' ');
5532
- }
5533
- /**
5534
- * Get all registered pages
5535
- * @returns BreadcrumbPageInfo[] - All registered pages
5536
- */
5537
- getAllRegisteredPages() { return []; }
5538
- /**
5539
- * Get pages by module
5540
- * @param moduleName - Module name to filter by
5541
- * @returns BreadcrumbPageInfo[] - Pages in the specified module
5542
- */
5543
- getPagesByModule(moduleName) { return []; }
5544
- /**
5545
- * Get pages by menu
5546
- * @param menuName - Menu name to filter by
5547
- * @returns BreadcrumbPageInfo[] - Pages in the specified menu
5548
- */
5549
- getPagesByMenu(menuName) { return []; }
5550
- // ---------- internal helpers ----------
5551
- ensureContext(contextId) {
5552
- if (!this.contextIdToItems.has(contextId)) {
5553
- this.contextIdToItems.set(contextId, signal([]));
5554
- }
5555
- }
5556
- getContextSignal(contextId) {
5557
- this.ensureContext(contextId);
5558
- // non-null since ensured
5559
- return this.contextIdToItems.get(contextId);
5560
- }
5561
- setContextItems(contextId, items) {
5562
- this.ensureContext(contextId);
5563
- this.contextIdToItems.get(contextId).set(items);
5564
- }
5565
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: BreadcrumbNavigationService, deps: [{ token: PAGE_PATH_RESOLVER, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
5566
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: BreadcrumbNavigationService, providedIn: 'root' });
5567
- }
5568
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: BreadcrumbNavigationService, decorators: [{
5569
- type: Injectable,
5570
- args: [{
5571
- providedIn: 'root'
5572
- }]
5573
- }], ctorParameters: () => [{ type: undefined, decorators: [{
5574
- type: Optional
5575
- }, {
5576
- type: Inject,
5577
- args: [PAGE_PATH_RESOLVER]
5578
- }] }] });
5579
-
5580
5346
  class CideEleBreadcrumbComponent {
5581
5347
  // Input signals
5582
5348
  items = input([], ...(ngDevMode ? [{ debugName: "items" }] : []));
@@ -5618,52 +5384,25 @@ class CideEleBreadcrumbComponent {
5618
5384
  config = computed(() => this.getConfigForStyle(this.style()), ...(ngDevMode ? [{ debugName: "config" }] : []));
5619
5385
  effectiveLoading = computed(() => this.loadingInput() || this.localLoading(), ...(ngDevMode ? [{ debugName: "effectiveLoading" }] : []));
5620
5386
  // Service for auto-binding when inputs are not provided
5621
- breadcrumbService = inject(BreadcrumbNavigationService, { optional: true });
5622
- pagePathResolver = inject(PAGE_PATH_RESOLVER, { optional: true });
5387
+ // No service injection
5623
5388
  cleanupEffect;
5624
- ngOnInit() {
5625
- // If no items provided and service is available, auto-bind to service signal
5626
- const pc = this.pageCode();
5627
- if (pc && this.pagePathResolver && this.breadcrumbService) {
5628
- // Resolve by page code into the active or provided context
5629
- const ctx = this.contextId();
5630
- if (ctx)
5631
- this.breadcrumbService.setActiveContext(ctx);
5632
- this.breadcrumbService.registerPagePathResolver(this.pagePathResolver);
5633
- void this.breadcrumbService.resolveAndSetByPageCode(pc, ctx);
5634
- }
5635
- // Mirror external input items into local state
5636
- const stopInputs = effect(() => {
5389
+ constructor() {
5390
+ // Mirror external input items into local state within injection context
5391
+ const ref = effect(() => {
5637
5392
  const inItems = this.items();
5638
5393
  if (inItems && inItems.length > 0) {
5639
5394
  this.localItems.set([...inItems]);
5640
5395
  this.processItems();
5641
5396
  }
5642
- }, ...(ngDevMode ? [{ debugName: "stopInputs" }] : []));
5643
- this.cleanupEffect = stopInputs;
5644
- if ((this.items().length === 0) && this.breadcrumbService) {
5645
- // When a contextId is provided, switch service active context
5646
- const ctx = this.contextId();
5647
- if (ctx) {
5648
- this.breadcrumbService.setActiveContext(ctx);
5649
- }
5650
- const destroy = effect(() => {
5651
- const svcItems = this.breadcrumbService.getCurrentBreadcrumbSignal()();
5652
- const isLoading = this.breadcrumbService.isLoadingBreadcrumb();
5653
- this.localItems.set(svcItems.map(i => ({ id: i.id, label: i.label, icon: i.icon, url: i.path })));
5654
- this.localLoading.set(isLoading);
5655
- this.processItems();
5656
- }, ...(ngDevMode ? [{ debugName: "destroy" }] : []));
5657
- this.cleanupEffect = destroy;
5658
- }
5659
- else {
5660
- this.processItems();
5661
- }
5397
+ }, ...(ngDevMode ? [{ debugName: "ref" }] : []));
5398
+ this.cleanupEffect = { destroy: () => ref.destroy() };
5399
+ }
5400
+ ngOnInit() {
5401
+ // Initial calculation
5402
+ this.processItems();
5662
5403
  }
5663
5404
  ngOnDestroy() {
5664
- if (this.cleanupEffect) {
5665
- this.cleanupEffect();
5666
- }
5405
+ this.cleanupEffect?.destroy();
5667
5406
  }
5668
5407
  onDocumentClick(event) {
5669
5408
  const target = event.target;
@@ -5846,12 +5585,12 @@ class CideEleBreadcrumbComponent {
5846
5585
  this.localLoading.set(value);
5847
5586
  }
5848
5587
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5849
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleBreadcrumbComponent, isStandalone: true, selector: "cide-ele-breadcrumb", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null }, showHomeIcon: { classPropertyName: "showHomeIcon", publicName: "showHomeIcon", isSignal: true, isRequired: false, transformFunction: null }, homeIcon: { classPropertyName: "homeIcon", publicName: "homeIcon", isSignal: true, isRequired: false, transformFunction: null }, maxItems: { classPropertyName: "maxItems", publicName: "maxItems", isSignal: true, isRequired: false, transformFunction: null }, showDropdownOnOverflow: { classPropertyName: "showDropdownOnOverflow", publicName: "showDropdownOnOverflow", isSignal: true, isRequired: false, transformFunction: null }, dropdownOptions: { classPropertyName: "dropdownOptions", publicName: "dropdownOptions", isSignal: true, isRequired: false, transformFunction: null }, clickableItems: { classPropertyName: "clickableItems", publicName: "clickableItems", isSignal: true, isRequired: false, transformFunction: null }, showTooltips: { classPropertyName: "showTooltips", publicName: "showTooltips", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, animated: { classPropertyName: "animated", publicName: "animated", isSignal: true, isRequired: false, transformFunction: null }, loadingInput: { classPropertyName: "loadingInput", publicName: "loadingInput", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, contextId: { classPropertyName: "contextId", publicName: "contextId", isSignal: true, isRequired: false, transformFunction: null }, pageCode: { classPropertyName: "pageCode", publicName: "pageCode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick", dropdownOptionClick: "dropdownOptionClick", homeClick: "homeClick" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<!-- Breadcrumb Component Template -->\n<div [class]=\"getContainerClasses()\" class=\"tw-flex tw-items-center tw-text-xs tw-text-gray-700 tw-py-0\">\n \n <!-- Loading State -->\n @if (effectiveLoading()) {\n <div class=\"breadcrumb-loading\">\n <cide-ele-icon class=\"animate-spin\">refresh</cide-ele-icon>\n <span>Loading...</span>\n </div>\n }\n\n <!-- Main Breadcrumb Content -->\n @if (!effectiveLoading()) {\n <nav class=\"tw-flex tw-items-center tw-min-w-0 tw-flex-1\" role=\"navigation\" aria-label=\"Breadcrumb\">\n <ol class=\"tw-flex tw-items-center tw-list-none tw-m-0 tw-p-0 tw-gap-1 tw-flex-wrap\">\n \n <!-- Home Icon (if enabled) -->\n @if (config().showHomeIcon) {\n <li class=\"tw-flex tw-items-center tw-gap-1 tw-px-1 tw-whitespace-nowrap tw-relative\" \n [class.tw-cursor-pointer]=\"clickableItems() && !disabled()\"\n (click)=\"onHomeClick()\"\n [title]=\"showTooltips() ? 'Go to Home' : ''\">\n <cide-ele-icon class=\"tw-text-gray-500 tw-text-xs\">\n {{ config().homeIcon }}\n </cide-ele-icon>\n </li>\n \n <!-- Separator after home -->\n @if (visibleItemsSignal().length > 0) {\n <li class=\"tw-flex tw-items-center tw-text-gray-300 tw-mx-0.5\">\n @if (separator().type === 'custom' && separator().text) {\n <span class=\"tw-font-normal tw-text-gray-400\">{{ separator().text }}</span>\n } @else {\n <cide-ele-icon class=\"tw-text-xs\">\n {{ getSeparatorIcon() }}\n </cide-ele-icon>\n }\n </li>\n }\n }\n\n <!-- Visible Items -->\n @for (item of visibleItemsSignal(); track item.id; let i = $index; let isLast = $last) {\n <li class=\"tw-flex tw-items-center tw-gap-1 tw-px-1 tw-whitespace-nowrap tw-relative\"\n [class.tw-cursor-pointer]=\"clickableItems() && !disabled()\"\n [class.tw-text-gray-400]=\"isLast\"\n (click)=\"onItemClick(item)\"\n [title]=\"getTooltipText(item)\"\n [attr.aria-current]=\"isLast ? 'page' : null\">\n \n <!-- Item Icon (if provided) -->\n @if (item.icon) {\n <cide-ele-icon class=\"tw-text-gray-500 tw-text-xs tw-flex-shrink-0\">\n {{ item.icon }}\n </cide-ele-icon>\n }\n \n <!-- Item Label -->\n <span class=\"tw-font-medium tw-text-xs\">\n {{ item.label }}\n </span>\n \n <!-- Item Type Badge (for hierarchical style) -->\n @if (style() === 'hierarchical' && item.type && item.type !== 'root') {\n <span class=\"item-type-badge\" [class]=\"'type-' + item.type\">\n {{ item.type }}\n </span>\n }\n </li>\n\n <!-- Separator (except for last item) -->\n @if (!isLast || isOverflowingSignal()) {\n <li class=\"tw-flex tw-items-center tw-text-gray-300 tw-mx-0.5\">\n @if (separator().type === 'custom' && separator().text) {\n <span class=\"tw-font-normal tw-text-gray-400\">{{ separator().text }}</span>\n } @else {\n <cide-ele-icon class=\"tw-text-xs\">\n {{ getSeparatorIcon() }}\n </cide-ele-icon>\n }\n </li>\n }\n }\n\n <!-- Overflow Dropdown -->\n @if (isOverflowingSignal() && showDropdownOnOverflow()) {\n <li class=\"breadcrumb-item overflow-item\">\n <div class=\"breadcrumb-dropdown-container\">\n <button type=\"button\" \n class=\"overflow-button\"\n (click)=\"onDropdownToggle()\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"showDropdownSignal()\"\n aria-haspopup=\"true\"\n [title]=\"showTooltips() ? 'More items' : ''\">\n <cide-ele-icon class=\"overflow-icon\">more_horiz</cide-ele-icon>\n <span class=\"overflow-text\" [class.compact]=\"config().compact\">\n {{ hiddenItemsSignal().length }}+ more\n </span>\n </button>\n \n <!-- Dropdown Menu -->\n @if (showDropdownSignal()) {\n <div class=\"breadcrumb-dropdown\" role=\"menu\">\n <div class=\"dropdown-header\">\n <span>Hidden Items</span>\n </div>\n \n <!-- Hidden Items -->\n @for (item of hiddenItemsSignal(); track item.id) {\n <button type=\"button\" \n class=\"dropdown-item\"\n (click)=\"onItemClick(item)\"\n [disabled]=\"item.disabled || disabled()\"\n role=\"menuitem\">\n @if (item.icon) {\n <cide-ele-icon class=\"dropdown-item-icon\">{{ item.icon }}</cide-ele-icon>\n }\n <span class=\"dropdown-item-label\">{{ item.label }}</span>\n </button>\n }\n \n <!-- Custom Dropdown Options -->\n @if (dropdownOptions().length > 0) {\n <div class=\"dropdown-divider\"></div>\n @for (option of dropdownOptions(); track option.id) {\n <button type=\"button\" \n class=\"dropdown-option\"\n (click)=\"onDropdownOptionClick(option)\"\n [disabled]=\"option.disabled || disabled()\"\n role=\"menuitem\">\n @if (option.icon) {\n <cide-ele-icon class=\"dropdown-option-icon\">{{ option.icon }}</cide-ele-icon>\n }\n <span class=\"dropdown-option-label\">{{ option.label }}</span>\n </button>\n }\n }\n </div>\n }\n </div>\n </li>\n }\n </ol>\n </nav>\n }\n\n</div>\n", styles: [".breadcrumb-container{display:flex;align-items:center;width:100%;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:12px;line-height:1.3;color:#374151;background:transparent;padding:2px 0}.breadcrumb-container.loading{opacity:.6;pointer-events:none}.breadcrumb-container.disabled{opacity:.5;pointer-events:none}@media (max-width: 768px){.breadcrumb-container.responsive{font-size:10px;padding:3px 0}}.breadcrumb-container.compact{font-size:10px;padding:1px 0}.breadcrumb-container.animated .breadcrumb-item{transition:color .15s ease}.breadcrumb-loading{display:flex;align-items:center;gap:8px;padding:12px 16px;color:#6b7280;font-size:14px}.breadcrumb-loading cide-ele-icon{animation:spin 1s linear infinite}.breadcrumb-nav{flex:1;min-width:0}.breadcrumb-list{display:flex;align-items:center;list-style:none;margin:0;padding:0;gap:4px;flex-wrap:wrap}.breadcrumb-item{display:flex;align-items:center;gap:2px;padding:0 2px;position:relative;white-space:nowrap}.breadcrumb-item.clickable{cursor:pointer}.breadcrumb-item.clickable:hover{color:#1f2937}.breadcrumb-item.disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.breadcrumb-item.last{color:#9ca3af}.breadcrumb-item.home-item{padding:0 1px}.breadcrumb-item.home-item .home-icon{color:#6b7280;font-size:13px}.breadcrumb-item.overflow-item{position:relative}.item-label{font-weight:500;color:inherit}.item-label.compact{font-weight:600}.item-icon{color:#6b7280;flex-shrink:0}.item-type-badge{padding:2px 6px;border-radius:4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.item-type-badge.type-category{background-color:#dbeafe;color:#1e40af}.item-type-badge.type-entity{background-color:#dcfce7;color:#166534}.item-type-badge.type-custom{background-color:#f3e8ff;color:#7c3aed}.breadcrumb-separator{display:flex;align-items:center;color:#d1d5db;margin:0 .5px}.breadcrumb-separator .separator-icon{font-size:11px}.breadcrumb-separator .custom-separator{font-weight:400;color:#9ca3af}.breadcrumb-dropdown-container{position:relative}.overflow-button{display:flex;align-items:center;gap:2px;padding:2px 4px;border:none;background:transparent;cursor:pointer;transition:color .15s ease;color:#6b7280}.overflow-button:hover{color:#374151}.overflow-button:disabled{opacity:.5;cursor:not-allowed}.overflow-icon{font-size:14px}.overflow-text{font-size:11px;font-weight:400}.breadcrumb-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e5e7eb;border-radius:8px;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d;z-index:1000;min-width:200px;max-width:300px;overflow:hidden;animation:dropdownSlideIn .2s ease-out}.dropdown-header{padding:8px 12px;background:#f9fafb;border-bottom:1px solid #e5e7eb;font-size:12px;font-weight:600;color:#6b7280;text-transform:uppercase;letter-spacing:.5px}.dropdown-item,.dropdown-option{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;border:none;background:transparent;text-align:left;cursor:pointer;transition:background-color .15s ease;color:#374151}.dropdown-item:hover,.dropdown-option:hover{background:#f3f4f6}.dropdown-item:disabled,.dropdown-option:disabled{opacity:.5;cursor:not-allowed}.dropdown-item-icon,.dropdown-option-icon{font-size:14px;color:#6b7280;flex-shrink:0}.dropdown-item-label,.dropdown-option-label{font-size:14px;font-weight:500}.dropdown-divider{height:1px;background:#e5e7eb;margin:4px 0}.style-modern .breadcrumb-item.clickable:hover{color:#1f2937}.style-modern .separator-icon{color:#d1d5db}.style-classic .breadcrumb-item{padding:2px 4px}.style-classic .breadcrumb-item.clickable:hover{color:#1f2937}.style-classic .separator-icon{color:#9ca3af;font-size:12px}.style-minimal .breadcrumb-item{padding:1px 2px}.style-minimal .breadcrumb-item.clickable:hover{color:#1f2937}.style-minimal .separator-icon{color:#d1d5db;font-size:10px}.style-hierarchical{background:transparent;border:none;padding:2px 0}.style-hierarchical .breadcrumb-item{padding:0 2px}.style-hierarchical .breadcrumb-item.clickable:hover{color:#1f2937}.style-hierarchical .separator-icon{color:#d1d5db}.style-hierarchical .breadcrumb-actions{display:none}@keyframes dropdownSlideIn{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media (prefers-reduced-motion: reduce){.breadcrumb-container.animated .breadcrumb-item{transition:none}.breadcrumb-container.animated .breadcrumb-item:hover{transform:none}.breadcrumb-dropdown{animation:none}}@media (prefers-contrast: high){.breadcrumb-container .breadcrumb-item{border:1px solid transparent}.breadcrumb-container .breadcrumb-item.clickable:hover{border-color:#000}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }] });
5588
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleBreadcrumbComponent, isStandalone: true, selector: "cide-ele-breadcrumb", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null }, showHomeIcon: { classPropertyName: "showHomeIcon", publicName: "showHomeIcon", isSignal: true, isRequired: false, transformFunction: null }, homeIcon: { classPropertyName: "homeIcon", publicName: "homeIcon", isSignal: true, isRequired: false, transformFunction: null }, maxItems: { classPropertyName: "maxItems", publicName: "maxItems", isSignal: true, isRequired: false, transformFunction: null }, showDropdownOnOverflow: { classPropertyName: "showDropdownOnOverflow", publicName: "showDropdownOnOverflow", isSignal: true, isRequired: false, transformFunction: null }, dropdownOptions: { classPropertyName: "dropdownOptions", publicName: "dropdownOptions", isSignal: true, isRequired: false, transformFunction: null }, clickableItems: { classPropertyName: "clickableItems", publicName: "clickableItems", isSignal: true, isRequired: false, transformFunction: null }, showTooltips: { classPropertyName: "showTooltips", publicName: "showTooltips", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, animated: { classPropertyName: "animated", publicName: "animated", isSignal: true, isRequired: false, transformFunction: null }, loadingInput: { classPropertyName: "loadingInput", publicName: "loadingInput", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, contextId: { classPropertyName: "contextId", publicName: "contextId", isSignal: true, isRequired: false, transformFunction: null }, pageCode: { classPropertyName: "pageCode", publicName: "pageCode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick", dropdownOptionClick: "dropdownOptionClick", homeClick: "homeClick" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<!-- Breadcrumb Component Template -->\n<div [class]=\"getContainerClasses()\" class=\"tw-flex tw-items-center tw-text-xs tw-text-gray-700 tw-py-0\">\n \n <!-- Loading State -->\n @if (effectiveLoading()) {\n <div class=\"breadcrumb-loading\">\n <cide-ele-icon class=\"animate-spin\">refresh</cide-ele-icon>\n <span>Loading...</span>\n </div>\n }\n\n <!-- Main Breadcrumb Content -->\n @if (!effectiveLoading()) {\n <nav class=\"tw-flex tw-items-center tw-min-w-0 tw-flex-1\" role=\"navigation\" aria-label=\"Breadcrumb\">\n <ol class=\"tw-flex tw-items-center tw-list-none tw-m-0 tw-p-0 tw-gap-1 tw-flex-wrap\">\n \n <!-- Home Icon (if enabled) -->\n @if (config().showHomeIcon) {\n <li class=\"tw-flex tw-items-center tw-gap-1 tw-px-1 tw-whitespace-nowrap tw-relative\" \n [class.tw-cursor-pointer]=\"clickableItems() && !disabled()\"\n (click)=\"onHomeClick()\"\n [title]=\"showTooltips() ? 'Go to Home' : ''\">\n <cide-ele-icon class=\"tw-text-gray-500 tw-text-xs\">\n {{ config().homeIcon }}\n </cide-ele-icon>\n </li>\n \n <!-- Separator after home -->\n @if (visibleItemsSignal().length > 0) {\n <li class=\"tw-flex tw-items-center tw-text-gray-300 tw-mx-0.5\">\n @if (separator().type === 'custom' && separator().text) {\n <span class=\"tw-font-normal tw-text-gray-400\">{{ separator().text }}</span>\n } @else {\n <cide-ele-icon class=\"tw-text-xs\">\n {{ getSeparatorIcon() }}\n </cide-ele-icon>\n }\n </li>\n }\n }\n\n <!-- Visible Items -->\n @for (item of visibleItemsSignal(); track item.id; let i = $index; let isLast = $last) {\n <li class=\"tw-flex tw-items-center tw-gap-1 tw-px-1 tw-whitespace-nowrap tw-relative\"\n [class.tw-cursor-pointer]=\"clickableItems() && !disabled()\"\n [class.tw-text-gray-400]=\"isLast\"\n (click)=\"onItemClick(item)\"\n [title]=\"getTooltipText(item)\"\n [attr.aria-current]=\"isLast ? 'page' : null\">\n \n <!-- Item Icon (if provided) -->\n @if (item.icon) {\n <cide-ele-icon class=\"tw-text-gray-500 tw-text-xs tw-flex-shrink-0\">\n {{ item.icon }}\n </cide-ele-icon>\n }\n \n <!-- Item Label -->\n <span class=\"tw-font-medium tw-text-xs\">\n {{ item.label }}\n </span>\n \n <!-- Item Type Badge (for hierarchical style) -->\n @if (style() === 'hierarchical' && item.type && item.type !== 'root') {\n <span class=\"item-type-badge\" [class]=\"'type-' + item.type\">\n {{ item.type }}\n </span>\n }\n </li>\n\n <!-- Separator (except for last item) -->\n @if (!isLast || isOverflowingSignal()) {\n <li class=\"tw-flex tw-items-center tw-text-gray-300 tw-mx-0.5\">\n @if (separator().type === 'custom' && separator().text) {\n <span class=\"tw-font-normal tw-text-gray-400\">{{ separator().text }}</span>\n } @else {\n <cide-ele-icon class=\"tw-text-xs\">\n {{ getSeparatorIcon() }}\n </cide-ele-icon>\n }\n </li>\n }\n }\n\n <!-- Overflow Dropdown -->\n @if (isOverflowingSignal() && showDropdownOnOverflow()) {\n <li class=\"breadcrumb-item overflow-item\">\n <div class=\"breadcrumb-dropdown-container\">\n <button type=\"button\" \n class=\"overflow-button\"\n (click)=\"onDropdownToggle()\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"showDropdownSignal()\"\n aria-haspopup=\"true\"\n [title]=\"showTooltips() ? 'More items' : ''\">\n <cide-ele-icon class=\"overflow-icon\">more_horiz</cide-ele-icon>\n <span class=\"overflow-text\" [class.compact]=\"config().compact\">\n {{ hiddenItemsSignal().length }}+ more\n </span>\n </button>\n \n <!-- Dropdown Menu -->\n @if (showDropdownSignal()) {\n <div class=\"breadcrumb-dropdown\" role=\"menu\">\n <div class=\"dropdown-header\">\n <span>Hidden Items</span>\n </div>\n \n <!-- Hidden Items -->\n @for (item of hiddenItemsSignal(); track item.id) {\n <button type=\"button\" \n class=\"dropdown-item\"\n (click)=\"onItemClick(item)\"\n [disabled]=\"item.disabled || disabled()\"\n role=\"menuitem\">\n @if (item.icon) {\n <cide-ele-icon class=\"dropdown-item-icon\">{{ item.icon }}</cide-ele-icon>\n }\n <span class=\"dropdown-item-label\">{{ item.label }}</span>\n </button>\n }\n \n <!-- Custom Dropdown Options -->\n @if (dropdownOptions().length > 0) {\n <div class=\"dropdown-divider\"></div>\n @for (option of dropdownOptions(); track option.id) {\n <button type=\"button\" \n class=\"dropdown-option\"\n (click)=\"onDropdownOptionClick(option)\"\n [disabled]=\"option.disabled || disabled()\"\n role=\"menuitem\">\n @if (option.icon) {\n <cide-ele-icon class=\"dropdown-option-icon\">{{ option.icon }}</cide-ele-icon>\n }\n <span class=\"dropdown-option-label\">{{ option.label }}</span>\n </button>\n }\n }\n </div>\n }\n </div>\n </li>\n }\n </ol>\n </nav>\n }\n\n</div>\n", styles: [".breadcrumb-container{display:flex;align-items:center;width:100%;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:12px;line-height:1.3;color:#374151;background:transparent;padding:2px 0}.breadcrumb-container.loading{opacity:.6;pointer-events:none}.breadcrumb-container.disabled{opacity:.5;pointer-events:none}@media (max-width: 768px){.breadcrumb-container.responsive{font-size:10px;padding:3px 0}}.breadcrumb-container.compact{font-size:10px;padding:1px 0}.breadcrumb-container.animated .breadcrumb-item{transition:color .15s ease}.breadcrumb-loading{display:flex;align-items:center;gap:8px;padding:12px 16px;color:#6b7280;font-size:14px}.breadcrumb-loading cide-ele-icon{animation:spin 1s linear infinite}.breadcrumb-nav{flex:1;min-width:0}.breadcrumb-list{display:flex;align-items:center;list-style:none;margin:0;padding:0;gap:4px;flex-wrap:wrap}.breadcrumb-item{display:flex;align-items:center;gap:2px;padding:0 2px;position:relative;white-space:nowrap}.breadcrumb-item.clickable{cursor:pointer}.breadcrumb-item.clickable:hover{color:#1f2937}.breadcrumb-item.disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.breadcrumb-item.last{color:#9ca3af}.breadcrumb-item.home-item{padding:0 1px}.breadcrumb-item.home-item .home-icon{color:#6b7280;font-size:13px}.breadcrumb-item.overflow-item{position:relative}.item-label{font-weight:500;color:inherit}.item-label.compact{font-weight:600}.item-icon{color:#6b7280;flex-shrink:0}.item-type-badge{padding:2px 6px;border-radius:4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.item-type-badge.type-category{background-color:#dbeafe;color:#1e40af}.item-type-badge.type-entity{background-color:#dcfce7;color:#166534}.item-type-badge.type-custom{background-color:#f3e8ff;color:#7c3aed}.breadcrumb-separator{display:flex;align-items:center;color:#d1d5db;margin:0 .5px}.breadcrumb-separator .separator-icon{font-size:11px}.breadcrumb-separator .custom-separator{font-weight:400;color:#9ca3af}.breadcrumb-dropdown-container{position:relative}.overflow-button{display:flex;align-items:center;gap:2px;padding:2px 4px;border:none;background:transparent;cursor:pointer;transition:color .15s ease;color:#6b7280}.overflow-button:hover{color:#374151}.overflow-button:disabled{opacity:.5;cursor:not-allowed}.overflow-icon{font-size:14px}.overflow-text{font-size:11px;font-weight:400}.breadcrumb-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e5e7eb;border-radius:8px;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d;z-index:1000;min-width:200px;max-width:300px;overflow:hidden;animation:dropdownSlideIn .2s ease-out}.dropdown-header{padding:8px 12px;background:#f9fafb;border-bottom:1px solid #e5e7eb;font-size:12px;font-weight:600;color:#6b7280;text-transform:uppercase;letter-spacing:.5px}.dropdown-item,.dropdown-option{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;border:none;background:transparent;text-align:left;cursor:pointer;transition:background-color .15s ease;color:#374151}.dropdown-item:hover,.dropdown-option:hover{background:#f3f4f6}.dropdown-item:disabled,.dropdown-option:disabled{opacity:.5;cursor:not-allowed}.dropdown-item-icon,.dropdown-option-icon{font-size:14px;color:#6b7280;flex-shrink:0}.dropdown-item-label,.dropdown-option-label{font-size:14px;font-weight:500}.dropdown-divider{height:1px;background:#e5e7eb;margin:4px 0}.style-modern .breadcrumb-item.clickable:hover{color:#1f2937}.style-modern .separator-icon{color:#d1d5db}.style-classic .breadcrumb-item{padding:2px 4px}.style-classic .breadcrumb-item.clickable:hover{color:#1f2937}.style-classic .separator-icon{color:#9ca3af;font-size:12px}.style-minimal .breadcrumb-item{padding:1px 2px}.style-minimal .breadcrumb-item.clickable:hover{color:#1f2937}.style-minimal .separator-icon{color:#d1d5db;font-size:10px}.style-hierarchical{background:transparent;border:none;padding:2px 0}.style-hierarchical .breadcrumb-item{padding:0 2px}.style-hierarchical .breadcrumb-item.clickable:hover{color:#1f2937}.style-hierarchical .separator-icon{color:#d1d5db}.style-hierarchical .breadcrumb-actions{display:none}@keyframes dropdownSlideIn{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media (prefers-reduced-motion: reduce){.breadcrumb-container.animated .breadcrumb-item{transition:none}.breadcrumb-container.animated .breadcrumb-item:hover{transform:none}.breadcrumb-dropdown{animation:none}}@media (prefers-contrast: high){.breadcrumb-container .breadcrumb-item{border:1px solid transparent}.breadcrumb-container .breadcrumb-item.clickable:hover{border-color:#000}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5850
5589
  }
5851
5590
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleBreadcrumbComponent, decorators: [{
5852
5591
  type: Component,
5853
- args: [{ selector: 'cide-ele-breadcrumb', standalone: true, imports: [CommonModule, CideIconComponent], template: "<!-- Breadcrumb Component Template -->\n<div [class]=\"getContainerClasses()\" class=\"tw-flex tw-items-center tw-text-xs tw-text-gray-700 tw-py-0\">\n \n <!-- Loading State -->\n @if (effectiveLoading()) {\n <div class=\"breadcrumb-loading\">\n <cide-ele-icon class=\"animate-spin\">refresh</cide-ele-icon>\n <span>Loading...</span>\n </div>\n }\n\n <!-- Main Breadcrumb Content -->\n @if (!effectiveLoading()) {\n <nav class=\"tw-flex tw-items-center tw-min-w-0 tw-flex-1\" role=\"navigation\" aria-label=\"Breadcrumb\">\n <ol class=\"tw-flex tw-items-center tw-list-none tw-m-0 tw-p-0 tw-gap-1 tw-flex-wrap\">\n \n <!-- Home Icon (if enabled) -->\n @if (config().showHomeIcon) {\n <li class=\"tw-flex tw-items-center tw-gap-1 tw-px-1 tw-whitespace-nowrap tw-relative\" \n [class.tw-cursor-pointer]=\"clickableItems() && !disabled()\"\n (click)=\"onHomeClick()\"\n [title]=\"showTooltips() ? 'Go to Home' : ''\">\n <cide-ele-icon class=\"tw-text-gray-500 tw-text-xs\">\n {{ config().homeIcon }}\n </cide-ele-icon>\n </li>\n \n <!-- Separator after home -->\n @if (visibleItemsSignal().length > 0) {\n <li class=\"tw-flex tw-items-center tw-text-gray-300 tw-mx-0.5\">\n @if (separator().type === 'custom' && separator().text) {\n <span class=\"tw-font-normal tw-text-gray-400\">{{ separator().text }}</span>\n } @else {\n <cide-ele-icon class=\"tw-text-xs\">\n {{ getSeparatorIcon() }}\n </cide-ele-icon>\n }\n </li>\n }\n }\n\n <!-- Visible Items -->\n @for (item of visibleItemsSignal(); track item.id; let i = $index; let isLast = $last) {\n <li class=\"tw-flex tw-items-center tw-gap-1 tw-px-1 tw-whitespace-nowrap tw-relative\"\n [class.tw-cursor-pointer]=\"clickableItems() && !disabled()\"\n [class.tw-text-gray-400]=\"isLast\"\n (click)=\"onItemClick(item)\"\n [title]=\"getTooltipText(item)\"\n [attr.aria-current]=\"isLast ? 'page' : null\">\n \n <!-- Item Icon (if provided) -->\n @if (item.icon) {\n <cide-ele-icon class=\"tw-text-gray-500 tw-text-xs tw-flex-shrink-0\">\n {{ item.icon }}\n </cide-ele-icon>\n }\n \n <!-- Item Label -->\n <span class=\"tw-font-medium tw-text-xs\">\n {{ item.label }}\n </span>\n \n <!-- Item Type Badge (for hierarchical style) -->\n @if (style() === 'hierarchical' && item.type && item.type !== 'root') {\n <span class=\"item-type-badge\" [class]=\"'type-' + item.type\">\n {{ item.type }}\n </span>\n }\n </li>\n\n <!-- Separator (except for last item) -->\n @if (!isLast || isOverflowingSignal()) {\n <li class=\"tw-flex tw-items-center tw-text-gray-300 tw-mx-0.5\">\n @if (separator().type === 'custom' && separator().text) {\n <span class=\"tw-font-normal tw-text-gray-400\">{{ separator().text }}</span>\n } @else {\n <cide-ele-icon class=\"tw-text-xs\">\n {{ getSeparatorIcon() }}\n </cide-ele-icon>\n }\n </li>\n }\n }\n\n <!-- Overflow Dropdown -->\n @if (isOverflowingSignal() && showDropdownOnOverflow()) {\n <li class=\"breadcrumb-item overflow-item\">\n <div class=\"breadcrumb-dropdown-container\">\n <button type=\"button\" \n class=\"overflow-button\"\n (click)=\"onDropdownToggle()\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"showDropdownSignal()\"\n aria-haspopup=\"true\"\n [title]=\"showTooltips() ? 'More items' : ''\">\n <cide-ele-icon class=\"overflow-icon\">more_horiz</cide-ele-icon>\n <span class=\"overflow-text\" [class.compact]=\"config().compact\">\n {{ hiddenItemsSignal().length }}+ more\n </span>\n </button>\n \n <!-- Dropdown Menu -->\n @if (showDropdownSignal()) {\n <div class=\"breadcrumb-dropdown\" role=\"menu\">\n <div class=\"dropdown-header\">\n <span>Hidden Items</span>\n </div>\n \n <!-- Hidden Items -->\n @for (item of hiddenItemsSignal(); track item.id) {\n <button type=\"button\" \n class=\"dropdown-item\"\n (click)=\"onItemClick(item)\"\n [disabled]=\"item.disabled || disabled()\"\n role=\"menuitem\">\n @if (item.icon) {\n <cide-ele-icon class=\"dropdown-item-icon\">{{ item.icon }}</cide-ele-icon>\n }\n <span class=\"dropdown-item-label\">{{ item.label }}</span>\n </button>\n }\n \n <!-- Custom Dropdown Options -->\n @if (dropdownOptions().length > 0) {\n <div class=\"dropdown-divider\"></div>\n @for (option of dropdownOptions(); track option.id) {\n <button type=\"button\" \n class=\"dropdown-option\"\n (click)=\"onDropdownOptionClick(option)\"\n [disabled]=\"option.disabled || disabled()\"\n role=\"menuitem\">\n @if (option.icon) {\n <cide-ele-icon class=\"dropdown-option-icon\">{{ option.icon }}</cide-ele-icon>\n }\n <span class=\"dropdown-option-label\">{{ option.label }}</span>\n </button>\n }\n }\n </div>\n }\n </div>\n </li>\n }\n </ol>\n </nav>\n }\n\n</div>\n", styles: [".breadcrumb-container{display:flex;align-items:center;width:100%;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:12px;line-height:1.3;color:#374151;background:transparent;padding:2px 0}.breadcrumb-container.loading{opacity:.6;pointer-events:none}.breadcrumb-container.disabled{opacity:.5;pointer-events:none}@media (max-width: 768px){.breadcrumb-container.responsive{font-size:10px;padding:3px 0}}.breadcrumb-container.compact{font-size:10px;padding:1px 0}.breadcrumb-container.animated .breadcrumb-item{transition:color .15s ease}.breadcrumb-loading{display:flex;align-items:center;gap:8px;padding:12px 16px;color:#6b7280;font-size:14px}.breadcrumb-loading cide-ele-icon{animation:spin 1s linear infinite}.breadcrumb-nav{flex:1;min-width:0}.breadcrumb-list{display:flex;align-items:center;list-style:none;margin:0;padding:0;gap:4px;flex-wrap:wrap}.breadcrumb-item{display:flex;align-items:center;gap:2px;padding:0 2px;position:relative;white-space:nowrap}.breadcrumb-item.clickable{cursor:pointer}.breadcrumb-item.clickable:hover{color:#1f2937}.breadcrumb-item.disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.breadcrumb-item.last{color:#9ca3af}.breadcrumb-item.home-item{padding:0 1px}.breadcrumb-item.home-item .home-icon{color:#6b7280;font-size:13px}.breadcrumb-item.overflow-item{position:relative}.item-label{font-weight:500;color:inherit}.item-label.compact{font-weight:600}.item-icon{color:#6b7280;flex-shrink:0}.item-type-badge{padding:2px 6px;border-radius:4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.item-type-badge.type-category{background-color:#dbeafe;color:#1e40af}.item-type-badge.type-entity{background-color:#dcfce7;color:#166534}.item-type-badge.type-custom{background-color:#f3e8ff;color:#7c3aed}.breadcrumb-separator{display:flex;align-items:center;color:#d1d5db;margin:0 .5px}.breadcrumb-separator .separator-icon{font-size:11px}.breadcrumb-separator .custom-separator{font-weight:400;color:#9ca3af}.breadcrumb-dropdown-container{position:relative}.overflow-button{display:flex;align-items:center;gap:2px;padding:2px 4px;border:none;background:transparent;cursor:pointer;transition:color .15s ease;color:#6b7280}.overflow-button:hover{color:#374151}.overflow-button:disabled{opacity:.5;cursor:not-allowed}.overflow-icon{font-size:14px}.overflow-text{font-size:11px;font-weight:400}.breadcrumb-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e5e7eb;border-radius:8px;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d;z-index:1000;min-width:200px;max-width:300px;overflow:hidden;animation:dropdownSlideIn .2s ease-out}.dropdown-header{padding:8px 12px;background:#f9fafb;border-bottom:1px solid #e5e7eb;font-size:12px;font-weight:600;color:#6b7280;text-transform:uppercase;letter-spacing:.5px}.dropdown-item,.dropdown-option{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;border:none;background:transparent;text-align:left;cursor:pointer;transition:background-color .15s ease;color:#374151}.dropdown-item:hover,.dropdown-option:hover{background:#f3f4f6}.dropdown-item:disabled,.dropdown-option:disabled{opacity:.5;cursor:not-allowed}.dropdown-item-icon,.dropdown-option-icon{font-size:14px;color:#6b7280;flex-shrink:0}.dropdown-item-label,.dropdown-option-label{font-size:14px;font-weight:500}.dropdown-divider{height:1px;background:#e5e7eb;margin:4px 0}.style-modern .breadcrumb-item.clickable:hover{color:#1f2937}.style-modern .separator-icon{color:#d1d5db}.style-classic .breadcrumb-item{padding:2px 4px}.style-classic .breadcrumb-item.clickable:hover{color:#1f2937}.style-classic .separator-icon{color:#9ca3af;font-size:12px}.style-minimal .breadcrumb-item{padding:1px 2px}.style-minimal .breadcrumb-item.clickable:hover{color:#1f2937}.style-minimal .separator-icon{color:#d1d5db;font-size:10px}.style-hierarchical{background:transparent;border:none;padding:2px 0}.style-hierarchical .breadcrumb-item{padding:0 2px}.style-hierarchical .breadcrumb-item.clickable:hover{color:#1f2937}.style-hierarchical .separator-icon{color:#d1d5db}.style-hierarchical .breadcrumb-actions{display:none}@keyframes dropdownSlideIn{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media (prefers-reduced-motion: reduce){.breadcrumb-container.animated .breadcrumb-item{transition:none}.breadcrumb-container.animated .breadcrumb-item:hover{transform:none}.breadcrumb-dropdown{animation:none}}@media (prefers-contrast: high){.breadcrumb-container .breadcrumb-item{border:1px solid transparent}.breadcrumb-container .breadcrumb-item.clickable:hover{border-color:#000}}\n"] }]
5854
- }], propDecorators: { itemClick: [{
5592
+ args: [{ selector: 'cide-ele-breadcrumb', standalone: true, imports: [CommonModule, CideIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Breadcrumb Component Template -->\n<div [class]=\"getContainerClasses()\" class=\"tw-flex tw-items-center tw-text-xs tw-text-gray-700 tw-py-0\">\n \n <!-- Loading State -->\n @if (effectiveLoading()) {\n <div class=\"breadcrumb-loading\">\n <cide-ele-icon class=\"animate-spin\">refresh</cide-ele-icon>\n <span>Loading...</span>\n </div>\n }\n\n <!-- Main Breadcrumb Content -->\n @if (!effectiveLoading()) {\n <nav class=\"tw-flex tw-items-center tw-min-w-0 tw-flex-1\" role=\"navigation\" aria-label=\"Breadcrumb\">\n <ol class=\"tw-flex tw-items-center tw-list-none tw-m-0 tw-p-0 tw-gap-1 tw-flex-wrap\">\n \n <!-- Home Icon (if enabled) -->\n @if (config().showHomeIcon) {\n <li class=\"tw-flex tw-items-center tw-gap-1 tw-px-1 tw-whitespace-nowrap tw-relative\" \n [class.tw-cursor-pointer]=\"clickableItems() && !disabled()\"\n (click)=\"onHomeClick()\"\n [title]=\"showTooltips() ? 'Go to Home' : ''\">\n <cide-ele-icon class=\"tw-text-gray-500 tw-text-xs\">\n {{ config().homeIcon }}\n </cide-ele-icon>\n </li>\n \n <!-- Separator after home -->\n @if (visibleItemsSignal().length > 0) {\n <li class=\"tw-flex tw-items-center tw-text-gray-300 tw-mx-0.5\">\n @if (separator().type === 'custom' && separator().text) {\n <span class=\"tw-font-normal tw-text-gray-400\">{{ separator().text }}</span>\n } @else {\n <cide-ele-icon class=\"tw-text-xs\">\n {{ getSeparatorIcon() }}\n </cide-ele-icon>\n }\n </li>\n }\n }\n\n <!-- Visible Items -->\n @for (item of visibleItemsSignal(); track item.id; let i = $index; let isLast = $last) {\n <li class=\"tw-flex tw-items-center tw-gap-1 tw-px-1 tw-whitespace-nowrap tw-relative\"\n [class.tw-cursor-pointer]=\"clickableItems() && !disabled()\"\n [class.tw-text-gray-400]=\"isLast\"\n (click)=\"onItemClick(item)\"\n [title]=\"getTooltipText(item)\"\n [attr.aria-current]=\"isLast ? 'page' : null\">\n \n <!-- Item Icon (if provided) -->\n @if (item.icon) {\n <cide-ele-icon class=\"tw-text-gray-500 tw-text-xs tw-flex-shrink-0\">\n {{ item.icon }}\n </cide-ele-icon>\n }\n \n <!-- Item Label -->\n <span class=\"tw-font-medium tw-text-xs\">\n {{ item.label }}\n </span>\n \n <!-- Item Type Badge (for hierarchical style) -->\n @if (style() === 'hierarchical' && item.type && item.type !== 'root') {\n <span class=\"item-type-badge\" [class]=\"'type-' + item.type\">\n {{ item.type }}\n </span>\n }\n </li>\n\n <!-- Separator (except for last item) -->\n @if (!isLast || isOverflowingSignal()) {\n <li class=\"tw-flex tw-items-center tw-text-gray-300 tw-mx-0.5\">\n @if (separator().type === 'custom' && separator().text) {\n <span class=\"tw-font-normal tw-text-gray-400\">{{ separator().text }}</span>\n } @else {\n <cide-ele-icon class=\"tw-text-xs\">\n {{ getSeparatorIcon() }}\n </cide-ele-icon>\n }\n </li>\n }\n }\n\n <!-- Overflow Dropdown -->\n @if (isOverflowingSignal() && showDropdownOnOverflow()) {\n <li class=\"breadcrumb-item overflow-item\">\n <div class=\"breadcrumb-dropdown-container\">\n <button type=\"button\" \n class=\"overflow-button\"\n (click)=\"onDropdownToggle()\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"showDropdownSignal()\"\n aria-haspopup=\"true\"\n [title]=\"showTooltips() ? 'More items' : ''\">\n <cide-ele-icon class=\"overflow-icon\">more_horiz</cide-ele-icon>\n <span class=\"overflow-text\" [class.compact]=\"config().compact\">\n {{ hiddenItemsSignal().length }}+ more\n </span>\n </button>\n \n <!-- Dropdown Menu -->\n @if (showDropdownSignal()) {\n <div class=\"breadcrumb-dropdown\" role=\"menu\">\n <div class=\"dropdown-header\">\n <span>Hidden Items</span>\n </div>\n \n <!-- Hidden Items -->\n @for (item of hiddenItemsSignal(); track item.id) {\n <button type=\"button\" \n class=\"dropdown-item\"\n (click)=\"onItemClick(item)\"\n [disabled]=\"item.disabled || disabled()\"\n role=\"menuitem\">\n @if (item.icon) {\n <cide-ele-icon class=\"dropdown-item-icon\">{{ item.icon }}</cide-ele-icon>\n }\n <span class=\"dropdown-item-label\">{{ item.label }}</span>\n </button>\n }\n \n <!-- Custom Dropdown Options -->\n @if (dropdownOptions().length > 0) {\n <div class=\"dropdown-divider\"></div>\n @for (option of dropdownOptions(); track option.id) {\n <button type=\"button\" \n class=\"dropdown-option\"\n (click)=\"onDropdownOptionClick(option)\"\n [disabled]=\"option.disabled || disabled()\"\n role=\"menuitem\">\n @if (option.icon) {\n <cide-ele-icon class=\"dropdown-option-icon\">{{ option.icon }}</cide-ele-icon>\n }\n <span class=\"dropdown-option-label\">{{ option.label }}</span>\n </button>\n }\n }\n </div>\n }\n </div>\n </li>\n }\n </ol>\n </nav>\n }\n\n</div>\n", styles: [".breadcrumb-container{display:flex;align-items:center;width:100%;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:12px;line-height:1.3;color:#374151;background:transparent;padding:2px 0}.breadcrumb-container.loading{opacity:.6;pointer-events:none}.breadcrumb-container.disabled{opacity:.5;pointer-events:none}@media (max-width: 768px){.breadcrumb-container.responsive{font-size:10px;padding:3px 0}}.breadcrumb-container.compact{font-size:10px;padding:1px 0}.breadcrumb-container.animated .breadcrumb-item{transition:color .15s ease}.breadcrumb-loading{display:flex;align-items:center;gap:8px;padding:12px 16px;color:#6b7280;font-size:14px}.breadcrumb-loading cide-ele-icon{animation:spin 1s linear infinite}.breadcrumb-nav{flex:1;min-width:0}.breadcrumb-list{display:flex;align-items:center;list-style:none;margin:0;padding:0;gap:4px;flex-wrap:wrap}.breadcrumb-item{display:flex;align-items:center;gap:2px;padding:0 2px;position:relative;white-space:nowrap}.breadcrumb-item.clickable{cursor:pointer}.breadcrumb-item.clickable:hover{color:#1f2937}.breadcrumb-item.disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.breadcrumb-item.last{color:#9ca3af}.breadcrumb-item.home-item{padding:0 1px}.breadcrumb-item.home-item .home-icon{color:#6b7280;font-size:13px}.breadcrumb-item.overflow-item{position:relative}.item-label{font-weight:500;color:inherit}.item-label.compact{font-weight:600}.item-icon{color:#6b7280;flex-shrink:0}.item-type-badge{padding:2px 6px;border-radius:4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.item-type-badge.type-category{background-color:#dbeafe;color:#1e40af}.item-type-badge.type-entity{background-color:#dcfce7;color:#166534}.item-type-badge.type-custom{background-color:#f3e8ff;color:#7c3aed}.breadcrumb-separator{display:flex;align-items:center;color:#d1d5db;margin:0 .5px}.breadcrumb-separator .separator-icon{font-size:11px}.breadcrumb-separator .custom-separator{font-weight:400;color:#9ca3af}.breadcrumb-dropdown-container{position:relative}.overflow-button{display:flex;align-items:center;gap:2px;padding:2px 4px;border:none;background:transparent;cursor:pointer;transition:color .15s ease;color:#6b7280}.overflow-button:hover{color:#374151}.overflow-button:disabled{opacity:.5;cursor:not-allowed}.overflow-icon{font-size:14px}.overflow-text{font-size:11px;font-weight:400}.breadcrumb-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e5e7eb;border-radius:8px;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d;z-index:1000;min-width:200px;max-width:300px;overflow:hidden;animation:dropdownSlideIn .2s ease-out}.dropdown-header{padding:8px 12px;background:#f9fafb;border-bottom:1px solid #e5e7eb;font-size:12px;font-weight:600;color:#6b7280;text-transform:uppercase;letter-spacing:.5px}.dropdown-item,.dropdown-option{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;border:none;background:transparent;text-align:left;cursor:pointer;transition:background-color .15s ease;color:#374151}.dropdown-item:hover,.dropdown-option:hover{background:#f3f4f6}.dropdown-item:disabled,.dropdown-option:disabled{opacity:.5;cursor:not-allowed}.dropdown-item-icon,.dropdown-option-icon{font-size:14px;color:#6b7280;flex-shrink:0}.dropdown-item-label,.dropdown-option-label{font-size:14px;font-weight:500}.dropdown-divider{height:1px;background:#e5e7eb;margin:4px 0}.style-modern .breadcrumb-item.clickable:hover{color:#1f2937}.style-modern .separator-icon{color:#d1d5db}.style-classic .breadcrumb-item{padding:2px 4px}.style-classic .breadcrumb-item.clickable:hover{color:#1f2937}.style-classic .separator-icon{color:#9ca3af;font-size:12px}.style-minimal .breadcrumb-item{padding:1px 2px}.style-minimal .breadcrumb-item.clickable:hover{color:#1f2937}.style-minimal .separator-icon{color:#d1d5db;font-size:10px}.style-hierarchical{background:transparent;border:none;padding:2px 0}.style-hierarchical .breadcrumb-item{padding:0 2px}.style-hierarchical .breadcrumb-item.clickable:hover{color:#1f2937}.style-hierarchical .separator-icon{color:#d1d5db}.style-hierarchical .breadcrumb-actions{display:none}@keyframes dropdownSlideIn{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media (prefers-reduced-motion: reduce){.breadcrumb-container.animated .breadcrumb-item{transition:none}.breadcrumb-container.animated .breadcrumb-item:hover{transform:none}.breadcrumb-dropdown{animation:none}}@media (prefers-contrast: high){.breadcrumb-container .breadcrumb-item{border:1px solid transparent}.breadcrumb-container .breadcrumb-item.clickable:hover{border-color:#000}}\n"] }]
5593
+ }], ctorParameters: () => [], propDecorators: { itemClick: [{
5855
5594
  type: Output
5856
5595
  }], dropdownOptionClick: [{
5857
5596
  type: Output
@@ -7160,6 +6899,170 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
7160
6899
  }]
7161
6900
  }], ctorParameters: () => [] });
7162
6901
 
6902
+ class ConfirmationService {
6903
+ // Modern signal-based state management
6904
+ confirmationQueue = signal([], ...(ngDevMode ? [{ debugName: "confirmationQueue" }] : []));
6905
+ currentRequest = signal(null, ...(ngDevMode ? [{ debugName: "currentRequest" }] : []));
6906
+ // Modern computed signals with proper typing
6907
+ hasActiveConfirmation = computed(() => this.currentRequest() !== null, ...(ngDevMode ? [{ debugName: "hasActiveConfirmation" }] : []));
6908
+ queueLength = computed(() => this.confirmationQueue().length, ...(ngDevMode ? [{ debugName: "queueLength" }] : []));
6909
+ constructor() {
6910
+ // Modern service initialization
6911
+ }
6912
+ ngOnDestroy() {
6913
+ // Cleanup if needed
6914
+ }
6915
+ /**
6916
+ * Ask for confirmation with a simple yes/no dialog
6917
+ */
6918
+ ask(options) {
6919
+ console.log('🔔 ConfirmationService.ask called with options:', options);
6920
+ return new Promise((resolve, reject) => {
6921
+ const request = {
6922
+ id: this.generateId(),
6923
+ title: options.title,
6924
+ message: options.message,
6925
+ type: options.type || 'warning',
6926
+ icon: options.icon || this.getDefaultIcon(options.type || 'warning'),
6927
+ confirmText: options.confirmText || 'Confirm',
6928
+ cancelText: options.cancelText || 'Cancel',
6929
+ resolve: (value) => resolve(value),
6930
+ reject
6931
+ };
6932
+ console.log('🔽 Ask for confirmation with a simple yes/no dialog', request);
6933
+ this.addToQueue(request);
6934
+ });
6935
+ }
6936
+ /**
6937
+ * Ask for confirmation with custom template and return custom data
6938
+ */
6939
+ askWithTemplate(options) {
6940
+ return new Promise((resolve, reject) => {
6941
+ const request = {
6942
+ id: this.generateId(),
6943
+ title: options.title,
6944
+ message: options.message,
6945
+ type: options.type || 'info',
6946
+ icon: options.icon || this.getDefaultIcon(options.type || 'info'),
6947
+ confirmText: options.confirmText || 'Confirm',
6948
+ cancelText: options.cancelText || 'Cancel',
6949
+ customTemplate: options.customTemplate,
6950
+ customData: options.customData,
6951
+ resolve: (value) => resolve(value),
6952
+ reject
6953
+ };
6954
+ // Cast to unknown for queue compatibility
6955
+ this.addToQueue(request);
6956
+ });
6957
+ }
6958
+ /**
6959
+ * Quick confirmation for dangerous actions
6960
+ */
6961
+ confirmDelete(itemName) {
6962
+ return this.ask({
6963
+ title: 'Confirm Delete',
6964
+ message: itemName ? `Are you sure you want to delete "${itemName}"? This action cannot be undone.` : 'Are you sure you want to delete this item? This action cannot be undone.',
6965
+ type: 'danger',
6966
+ icon: 'delete_forever',
6967
+ confirmText: 'Delete',
6968
+ cancelText: 'Cancel'
6969
+ });
6970
+ }
6971
+ /**
6972
+ * Quick confirmation for permanent actions
6973
+ */
6974
+ confirmPermanentAction(action, itemName) {
6975
+ return this.ask({
6976
+ title: `Confirm ${action}`,
6977
+ message: itemName ? `Are you sure you want to ${action.toLowerCase()} "${itemName}"? This action cannot be undone.` : `Are you sure you want to ${action.toLowerCase()}? This action cannot be undone.`,
6978
+ type: 'danger',
6979
+ icon: 'warning',
6980
+ confirmText: action,
6981
+ cancelText: 'Cancel'
6982
+ });
6983
+ }
6984
+ /**
6985
+ * Quick confirmation for safe actions
6986
+ */
6987
+ confirmSafeAction(action, itemName) {
6988
+ return this.ask({
6989
+ title: `Confirm ${action}`,
6990
+ message: itemName ? `Are you sure you want to ${action.toLowerCase()} "${itemName}"?` : `Are you sure you want to ${action.toLowerCase()}?`,
6991
+ type: 'info',
6992
+ icon: 'info',
6993
+ confirmText: action,
6994
+ cancelText: 'Cancel'
6995
+ });
6996
+ }
6997
+ // Modern private methods with proper typing
6998
+ addToQueue(request) {
6999
+ this.confirmationQueue.update(queue => [...queue, request]);
7000
+ console.log('🔔 Added request to queue:', request);
7001
+ this.processQueue();
7002
+ }
7003
+ processQueue() {
7004
+ console.log('🔔 Processing queue. Current request:', this.currentRequest(), 'Queue length:', this.confirmationQueue().length);
7005
+ if (this.currentRequest() || this.confirmationQueue().length === 0) {
7006
+ return;
7007
+ }
7008
+ const nextRequest = this.confirmationQueue()[0];
7009
+ console.log('🔔 Setting current request:', nextRequest);
7010
+ this.currentRequest.set(nextRequest);
7011
+ }
7012
+ // Modern public methods with proper typing
7013
+ confirmCurrentRequest(data) {
7014
+ const request = this.currentRequest();
7015
+ if (!request)
7016
+ return;
7017
+ // Always resolve with true for confirmation, unless custom data is explicitly provided
7018
+ const resolvedValue = data !== undefined ? data : true;
7019
+ console.log('🔔 Confirming request with value:', resolvedValue);
7020
+ request.resolve(resolvedValue);
7021
+ this.removeCurrentRequest();
7022
+ }
7023
+ cancelCurrentRequest() {
7024
+ const request = this.currentRequest();
7025
+ if (!request)
7026
+ return;
7027
+ request.reject(new Error('User cancelled'));
7028
+ this.removeCurrentRequest();
7029
+ }
7030
+ removeCurrentRequest() {
7031
+ this.confirmationQueue.update(queue => queue.slice(1));
7032
+ this.currentRequest.set(null);
7033
+ // Process next request if any
7034
+ setTimeout(() => this.processQueue(), 100);
7035
+ }
7036
+ generateId() {
7037
+ return `confirmation-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
7038
+ }
7039
+ // Modern private utility method with proper typing
7040
+ getDefaultIcon(type) {
7041
+ const iconMap = {
7042
+ danger: 'error',
7043
+ warning: 'warning',
7044
+ info: 'info',
7045
+ success: 'check_circle'
7046
+ };
7047
+ return iconMap[type];
7048
+ }
7049
+ // Modern public getters with proper typing
7050
+ getCurrentRequest() {
7051
+ return this.currentRequest;
7052
+ }
7053
+ getHasActiveConfirmation() {
7054
+ return this.hasActiveConfirmation;
7055
+ }
7056
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: ConfirmationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7057
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: ConfirmationService, providedIn: 'root' });
7058
+ }
7059
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: ConfirmationService, decorators: [{
7060
+ type: Injectable,
7061
+ args: [{
7062
+ providedIn: 'root'
7063
+ }]
7064
+ }], ctorParameters: () => [] });
7065
+
7163
7066
  /**
7164
7067
  * Directive to display images from file manager by ID
7165
7068
  * Usage: <img cideEleFileImage [fileId]="yourFileId" [altText]="'Image'" class="your-css-classes" />
@@ -7460,170 +7363,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
7460
7363
  type: Input
7461
7364
  }] } });
7462
7365
 
7463
- class ConfirmationService {
7464
- // Modern signal-based state management
7465
- confirmationQueue = signal([], ...(ngDevMode ? [{ debugName: "confirmationQueue" }] : []));
7466
- currentRequest = signal(null, ...(ngDevMode ? [{ debugName: "currentRequest" }] : []));
7467
- // Modern computed signals with proper typing
7468
- hasActiveConfirmation = computed(() => this.currentRequest() !== null, ...(ngDevMode ? [{ debugName: "hasActiveConfirmation" }] : []));
7469
- queueLength = computed(() => this.confirmationQueue().length, ...(ngDevMode ? [{ debugName: "queueLength" }] : []));
7470
- constructor() {
7471
- // Modern service initialization
7472
- }
7473
- ngOnDestroy() {
7474
- // Cleanup if needed
7475
- }
7476
- /**
7477
- * Ask for confirmation with a simple yes/no dialog
7478
- */
7479
- ask(options) {
7480
- console.log('🔔 ConfirmationService.ask called with options:', options);
7481
- return new Promise((resolve, reject) => {
7482
- const request = {
7483
- id: this.generateId(),
7484
- title: options.title,
7485
- message: options.message,
7486
- type: options.type || 'warning',
7487
- icon: options.icon || this.getDefaultIcon(options.type || 'warning'),
7488
- confirmText: options.confirmText || 'Confirm',
7489
- cancelText: options.cancelText || 'Cancel',
7490
- resolve: (value) => resolve(value),
7491
- reject
7492
- };
7493
- console.log('🔽 Ask for confirmation with a simple yes/no dialog', request);
7494
- this.addToQueue(request);
7495
- });
7496
- }
7497
- /**
7498
- * Ask for confirmation with custom template and return custom data
7499
- */
7500
- askWithTemplate(options) {
7501
- return new Promise((resolve, reject) => {
7502
- const request = {
7503
- id: this.generateId(),
7504
- title: options.title,
7505
- message: options.message,
7506
- type: options.type || 'info',
7507
- icon: options.icon || this.getDefaultIcon(options.type || 'info'),
7508
- confirmText: options.confirmText || 'Confirm',
7509
- cancelText: options.cancelText || 'Cancel',
7510
- customTemplate: options.customTemplate,
7511
- customData: options.customData,
7512
- resolve: (value) => resolve(value),
7513
- reject
7514
- };
7515
- // Cast to unknown for queue compatibility
7516
- this.addToQueue(request);
7517
- });
7518
- }
7519
- /**
7520
- * Quick confirmation for dangerous actions
7521
- */
7522
- confirmDelete(itemName) {
7523
- return this.ask({
7524
- title: 'Confirm Delete',
7525
- message: itemName ? `Are you sure you want to delete "${itemName}"? This action cannot be undone.` : 'Are you sure you want to delete this item? This action cannot be undone.',
7526
- type: 'danger',
7527
- icon: 'delete_forever',
7528
- confirmText: 'Delete',
7529
- cancelText: 'Cancel'
7530
- });
7531
- }
7532
- /**
7533
- * Quick confirmation for permanent actions
7534
- */
7535
- confirmPermanentAction(action, itemName) {
7536
- return this.ask({
7537
- title: `Confirm ${action}`,
7538
- message: itemName ? `Are you sure you want to ${action.toLowerCase()} "${itemName}"? This action cannot be undone.` : `Are you sure you want to ${action.toLowerCase()}? This action cannot be undone.`,
7539
- type: 'danger',
7540
- icon: 'warning',
7541
- confirmText: action,
7542
- cancelText: 'Cancel'
7543
- });
7544
- }
7545
- /**
7546
- * Quick confirmation for safe actions
7547
- */
7548
- confirmSafeAction(action, itemName) {
7549
- return this.ask({
7550
- title: `Confirm ${action}`,
7551
- message: itemName ? `Are you sure you want to ${action.toLowerCase()} "${itemName}"?` : `Are you sure you want to ${action.toLowerCase()}?`,
7552
- type: 'info',
7553
- icon: 'info',
7554
- confirmText: action,
7555
- cancelText: 'Cancel'
7556
- });
7557
- }
7558
- // Modern private methods with proper typing
7559
- addToQueue(request) {
7560
- this.confirmationQueue.update(queue => [...queue, request]);
7561
- console.log('🔔 Added request to queue:', request);
7562
- this.processQueue();
7563
- }
7564
- processQueue() {
7565
- console.log('🔔 Processing queue. Current request:', this.currentRequest(), 'Queue length:', this.confirmationQueue().length);
7566
- if (this.currentRequest() || this.confirmationQueue().length === 0) {
7567
- return;
7568
- }
7569
- const nextRequest = this.confirmationQueue()[0];
7570
- console.log('🔔 Setting current request:', nextRequest);
7571
- this.currentRequest.set(nextRequest);
7572
- }
7573
- // Modern public methods with proper typing
7574
- confirmCurrentRequest(data) {
7575
- const request = this.currentRequest();
7576
- if (!request)
7577
- return;
7578
- // Always resolve with true for confirmation, unless custom data is explicitly provided
7579
- const resolvedValue = data !== undefined ? data : true;
7580
- console.log('🔔 Confirming request with value:', resolvedValue);
7581
- request.resolve(resolvedValue);
7582
- this.removeCurrentRequest();
7583
- }
7584
- cancelCurrentRequest() {
7585
- const request = this.currentRequest();
7586
- if (!request)
7587
- return;
7588
- request.reject(new Error('User cancelled'));
7589
- this.removeCurrentRequest();
7590
- }
7591
- removeCurrentRequest() {
7592
- this.confirmationQueue.update(queue => queue.slice(1));
7593
- this.currentRequest.set(null);
7594
- // Process next request if any
7595
- setTimeout(() => this.processQueue(), 100);
7596
- }
7597
- generateId() {
7598
- return `confirmation-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
7599
- }
7600
- // Modern private utility method with proper typing
7601
- getDefaultIcon(type) {
7602
- const iconMap = {
7603
- danger: 'error',
7604
- warning: 'warning',
7605
- info: 'info',
7606
- success: 'check_circle'
7607
- };
7608
- return iconMap[type];
7609
- }
7610
- // Modern public getters with proper typing
7611
- getCurrentRequest() {
7612
- return this.currentRequest;
7613
- }
7614
- getHasActiveConfirmation() {
7615
- return this.hasActiveConfirmation;
7616
- }
7617
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: ConfirmationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7618
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: ConfirmationService, providedIn: 'root' });
7619
- }
7620
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: ConfirmationService, decorators: [{
7621
- type: Injectable,
7622
- args: [{
7623
- providedIn: 'root'
7624
- }]
7625
- }], ctorParameters: () => [] });
7626
-
7627
7366
  class CideEleConfirmationModalComponent {
7628
7367
  // Modern Angular 20+ dependency injection
7629
7368
  confirmationService = inject(ConfirmationService);
@@ -11687,5 +11426,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
11687
11426
  * Generated bundle index. Do not edit.
11688
11427
  */
11689
11428
 
11690
- export { BreadcrumbNavigationService, CapitalizePipe, CideCoreFileManagerService, CideEleBreadcrumbComponent, CideEleButtonComponent, CideEleConfirmationModalComponent, CideEleDataGridComponent, CideEleDropdownComponent, CideEleFileImageDirective, CideEleFileInputComponent, CideEleFileManagerService, CideEleFloatingContainerComponent, CideEleFloatingContainerDynamicDirective, CideEleFloatingContainerManagerComponent, CideEleFloatingContainerService, CideEleFloatingFeaturesService, CideEleFloatingFileUploaderComponent, CideEleFloatingFileUploaderService, CideEleGlobalNotificationsComponent, CideEleJsonEditorComponent, CideEleResizerDirective, CideEleSkeletonLoaderComponent, CideEleTabComponent, CideEleToastNotificationComponent, CideElementsService, CideFormFieldErrorComponent, CideIconComponent, CideInputComponent, CideSelectComponent, CideSelectOptionComponent, CideTextareaComponent, CoreFileManagerInsertUpdatePayload, DEFAULT_GRID_CONFIG, DropdownManagerService, ICoreCyfmSave, KeyboardShortcutService, MFileManager, NotificationService, PAGE_PATH_RESOLVER, TooltipDirective };
11429
+ export { CapitalizePipe, CideCoreFileManagerService, CideEleBreadcrumbComponent, CideEleButtonComponent, CideEleConfirmationModalComponent, CideEleDataGridComponent, CideEleDropdownComponent, CideEleFileImageDirective, CideEleFileInputComponent, CideEleFileManagerService, CideEleFloatingContainerComponent, CideEleFloatingContainerDynamicDirective, CideEleFloatingContainerManagerComponent, CideEleFloatingContainerService, CideEleFloatingFeaturesService, CideEleFloatingFileUploaderComponent, CideEleFloatingFileUploaderService, CideEleGlobalNotificationsComponent, CideEleJsonEditorComponent, CideEleResizerDirective, CideEleSkeletonLoaderComponent, CideEleTabComponent, CideEleToastNotificationComponent, CideElementsService, CideFormFieldErrorComponent, CideIconComponent, CideInputComponent, CideSelectComponent, CideSelectOptionComponent, CideSpinnerComponent, CideTextareaComponent, ConfirmationService, CoreFileManagerInsertUpdatePayload, DEFAULT_GRID_CONFIG, DropdownManagerService, ICoreCyfmSave, KeyboardShortcutService, MFileManager, NotificationService, PortalService, TooltipDirective };
11691
11430
  //# sourceMappingURL=cloud-ide-element.mjs.map