cloud-ide-element 1.0.116 → 1.0.119

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.
@@ -3385,6 +3385,7 @@ class CideEleFloatingContainerService {
3385
3385
  activeComponents = new Map();
3386
3386
  constructor(injector) {
3387
3387
  this.injector = injector;
3388
+ // Keyboard shortcuts are now handled by FloatingContainerShortcutsService
3388
3389
  }
3389
3390
  // Computed properties
3390
3391
  visibleContainers = computed(() => Array.from(this.containers().values()).filter(container => container.isVisible), ...(ngDevMode ? [{ debugName: "visibleContainers" }] : []));
@@ -3394,7 +3395,9 @@ class CideEleFloatingContainerService {
3394
3395
  show(config) {
3395
3396
  const containerId = config.id || this.generateId();
3396
3397
  const instanceId = this.generateInstanceId(config.componentId || 'default');
3397
- const zIndex = this.nextZIndex();
3398
+ // Get the highest z-index and add 1 to bring new container to front
3399
+ const maxZIndex = this.getMaxZIndex();
3400
+ const zIndex = maxZIndex + 1;
3398
3401
  const now = new Date();
3399
3402
  const container = {
3400
3403
  id: containerId,
@@ -3427,40 +3430,64 @@ class CideEleFloatingContainerService {
3427
3430
  return newContainers;
3428
3431
  });
3429
3432
  }
3430
- minimize(containerId) {
3433
+ /**
3434
+ * Get the maximum z-index among all visible containers
3435
+ */
3436
+ getMaxZIndex() {
3437
+ const containers = this.containers();
3438
+ let maxZIndex = 1000; // Base z-index
3439
+ for (const container of containers.values()) {
3440
+ if (container.isVisible && container.zIndex > maxZIndex) {
3441
+ maxZIndex = container.zIndex;
3442
+ }
3443
+ }
3444
+ return maxZIndex;
3445
+ }
3446
+ /**
3447
+ * Bring a container to the front (highest z-index)
3448
+ */
3449
+ bringToFront(containerId) {
3450
+ const maxZIndex = this.getMaxZIndex();
3451
+ const newZIndex = maxZIndex + 1;
3452
+ console.log(`🎯 [FloatingContainer] Bringing container '${containerId}' to front`);
3453
+ console.log(`🎯 [FloatingContainer] Current max z-index: ${maxZIndex}, new z-index: ${newZIndex}`);
3431
3454
  this.containers.update(containers => {
3432
3455
  const newContainers = new Map(containers);
3433
3456
  const container = newContainers.get(containerId);
3434
3457
  if (container) {
3435
- container.isMinimized = !container.isMinimized;
3458
+ const oldZIndex = container.zIndex;
3459
+ container.zIndex = newZIndex;
3460
+ container.lastAccessed = new Date();
3436
3461
  newContainers.set(containerId, container);
3462
+ console.log(`🎯 [FloatingContainer] Container '${containerId}' z-index updated: ${oldZIndex} → ${newZIndex}`);
3463
+ }
3464
+ else {
3465
+ console.warn(`⚠️ [FloatingContainer] Container '${containerId}' not found!`);
3437
3466
  }
3438
3467
  return newContainers;
3439
3468
  });
3440
3469
  }
3441
- maximize(containerId) {
3470
+ minimize(containerId) {
3442
3471
  this.containers.update(containers => {
3443
3472
  const newContainers = new Map(containers);
3444
3473
  const container = newContainers.get(containerId);
3445
3474
  if (container) {
3446
- container.isMaximized = !container.isMaximized;
3475
+ container.isMinimized = !container.isMinimized;
3447
3476
  newContainers.set(containerId, container);
3448
3477
  }
3449
3478
  return newContainers;
3450
3479
  });
3451
3480
  }
3452
- bringToFront(containerId) {
3453
- const zIndex = this.nextZIndex();
3481
+ maximize(containerId) {
3454
3482
  this.containers.update(containers => {
3455
3483
  const newContainers = new Map(containers);
3456
3484
  const container = newContainers.get(containerId);
3457
3485
  if (container) {
3458
- container.zIndex = zIndex;
3486
+ container.isMaximized = !container.isMaximized;
3459
3487
  newContainers.set(containerId, container);
3460
3488
  }
3461
3489
  return newContainers;
3462
3490
  });
3463
- this.nextZIndex.update(z => z + 1);
3464
3491
  }
3465
3492
  getContainer(containerId) {
3466
3493
  return this.containers().get(containerId);
@@ -3678,6 +3705,35 @@ class CideEleFloatingContainerService {
3678
3705
  return container?.isMaximized || false;
3679
3706
  });
3680
3707
  }
3708
+ getZIndexSignal(containerId) {
3709
+ return computed(() => {
3710
+ const container = this.getContainer(containerId);
3711
+ const zIndex = container?.zIndex || 1000;
3712
+ console.log(`🎯 [FloatingContainer] Z-index signal for '${containerId}': ${zIndex}`);
3713
+ return zIndex;
3714
+ });
3715
+ }
3716
+ /**
3717
+ * Set z-index for a specific container
3718
+ */
3719
+ setZIndex(containerId, zIndex) {
3720
+ console.log(`🎯 [FloatingContainer] Setting z-index for '${containerId}' to ${zIndex}`);
3721
+ this.containers.update(containers => {
3722
+ const newContainers = new Map(containers);
3723
+ const container = newContainers.get(containerId);
3724
+ if (container) {
3725
+ const oldZIndex = container.zIndex;
3726
+ container.zIndex = zIndex;
3727
+ container.lastAccessed = new Date();
3728
+ newContainers.set(containerId, container);
3729
+ console.log(`🎯 [FloatingContainer] Container '${containerId}' z-index updated: ${oldZIndex} → ${zIndex}`);
3730
+ }
3731
+ else {
3732
+ console.warn(`⚠️ [FloatingContainer] Container '${containerId}' not found for z-index update!`);
3733
+ }
3734
+ return newContainers;
3735
+ });
3736
+ }
3681
3737
  /**
3682
3738
  * Get visible signal for a container
3683
3739
  */
@@ -4932,8 +4988,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
4932
4988
  class CideEleFloatingFileUploaderComponent {
4933
4989
  destroyRef = inject(DestroyRef);
4934
4990
  fileManagerService = inject(CideEleFileManagerService);
4991
+ // Input data from floating container
4992
+ data = {};
4935
4993
  // Signals for reactive state
4936
- isVisible = signal(false, ...(ngDevMode ? [{ debugName: "isVisible" }] : []));
4994
+ isVisible = signal(true, ...(ngDevMode ? [{ debugName: "isVisible" }] : [])); // Set to true by default for floating containers
4937
4995
  isMinimized = signal(false, ...(ngDevMode ? [{ debugName: "isMinimized" }] : []));
4938
4996
  currentUserId = signal('', ...(ngDevMode ? [{ debugName: "currentUserId" }] : []));
4939
4997
  currentGroupId = signal(null, ...(ngDevMode ? [{ debugName: "currentGroupId" }] : []));
@@ -5015,6 +5073,8 @@ class CideEleFloatingFileUploaderComponent {
5015
5073
  });
5016
5074
  }
5017
5075
  ngOnInit() {
5076
+ // Initialize with input data
5077
+ this.initializeWithData();
5018
5078
  // Set up drag and drop listeners
5019
5079
  this.setupDragAndDrop();
5020
5080
  // Set up file input change listeners
@@ -5022,6 +5082,39 @@ class CideEleFloatingFileUploaderComponent {
5022
5082
  // Set up window resize listener
5023
5083
  this.setupWindowResize();
5024
5084
  }
5085
+ initializeWithData() {
5086
+ console.log('🚀 [FloatingFileUploader] Initializing with data:', this.data);
5087
+ // Set user ID if provided
5088
+ if (this.data.userId) {
5089
+ this.currentUserId.set(this.data.userId);
5090
+ console.log('👤 [FloatingFileUploader] User ID set:', this.data.userId);
5091
+ }
5092
+ // Set group ID if provided
5093
+ if (this.data.groupId) {
5094
+ this.currentGroupId.set(this.data.groupId);
5095
+ console.log('🆔 [FloatingFileUploader] Group ID set:', this.data.groupId);
5096
+ // Load existing files for this group
5097
+ this.loadExistingFiles();
5098
+ }
5099
+ // Set visibility to true when component loads
5100
+ this.isVisible.set(true);
5101
+ }
5102
+ loadExistingFiles() {
5103
+ const groupId = this.currentGroupId();
5104
+ if (!groupId)
5105
+ return;
5106
+ console.log('📁 [FloatingFileUploader] Loading existing files for group:', groupId);
5107
+ this.fileManagerService.fetchAndStoreFilesByGroupId(groupId)
5108
+ .pipe(takeUntilDestroyed(this.destroyRef))
5109
+ .subscribe({
5110
+ next: (files) => {
5111
+ console.log('📋 [FloatingFileUploader] Files loaded:', files.length);
5112
+ },
5113
+ error: (error) => {
5114
+ console.error('❌ [FloatingFileUploader] Failed to load files:', error);
5115
+ }
5116
+ });
5117
+ }
5025
5118
  ngOnDestroy() {
5026
5119
  console.log('🧹 [FloatingFileUploader] Component destroyed');
5027
5120
  this.removeDragAndDropListeners();
@@ -5468,7 +5561,7 @@ class CideEleFloatingFileUploaderComponent {
5468
5561
  }, 100);
5469
5562
  }
5470
5563
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingFileUploaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5471
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleFloatingFileUploaderComponent, isStandalone: true, selector: "cide-ele-floating-file-uploader", ngImport: i0, template: "<!-- Floating File Uploader Container -->\n@if (isVisible()) {\n<div class=\"floating-uploader\" \n [class.minimized]=\"isMinimized()\" \n [class.animating]=\"isAnimating()\"\n [style.left.px]=\"position().x\"\n [style.top.px]=\"position().y\">\n\n <!-- Header (Draggable) -->\n <div class=\"uploader-header draggable-header\"\n (mousedown)=\"startDrag($event)\"\n (touchstart)=\"startDrag($event)\">\n <div class=\"header-left\">\n <div class=\"upload-icon\">\n <cide-ele-icon size=\"sm\">cloud_upload</cide-ele-icon>\n </div>\n <div class=\"upload-info\">\n <div class=\"upload-title\">File Upload</div>\n <div class=\"upload-summary\">{{ getUploadSummary() }}</div>\n </div>\n </div>\n \n <div class=\"header-actions\">\n <button class=\"action-btn minimize-btn\" (click)=\"toggleMinimize()\" [title]=\"isMinimized() ? 'Expand' : 'Minimize'\">\n <cide-ele-icon size=\"xs\">{{ isMinimized() ? 'expand_more' : 'expand_less' }}</cide-ele-icon>\n </button>\n <button class=\"action-btn close-btn\" (click)=\"close()\" title=\"Close\">\n <cide-ele-icon size=\"xs\">close</cide-ele-icon>\n </button>\n </div>\n </div>\n\n <!-- Content (hidden when minimized) -->\n @if (!isMinimized()) {\n <div class=\"uploader-content\">\n \n <!-- Drag and Drop Zone -->\n <div class=\"upload-zone\" \n [class.drag-over]=\"isDragOver()\" \n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\" \n (drop)=\"onDrop($event)\" \n (click)=\"triggerFileInput()\">\n \n <!-- Hidden file input -->\n <input #fileInput \n type=\"file\" \n [multiple]=\"true\" \n [accept]=\"'*/*'\" \n (change)=\"onFileInputChange($event)\" \n style=\"display: none;\">\n \n <div class=\"upload-zone-content\">\n <cide-ele-icon class=\"upload-icon\" size=\"sm\">cloud_upload</cide-ele-icon>\n \n <div class=\"upload-text\">\n <div class=\"upload-title\">\n {{ isDragOver() ? 'Drop files here' : 'Drag files here or click to browse' }}\n </div>\n </div>\n </div>\n </div>\n \n <!-- Upload Queue - Show files from service state -->\n @if (allFilesForGroup().length > 0) {\n <div class=\"upload-queue\">\n <!-- Show all files from service state -->\n @for (file of allFilesForGroup(); track file.fileId) {\n <div class=\"upload-item\" [class]=\"getStatusClass(file.stage)\">\n <div class=\"file-info\">\n <cide-ele-icon class=\"status-icon\" size=\"xs\">{{ getStatusIcon(file.stage) }}</cide-ele-icon>\n <div class=\"file-details\">\n <div class=\"file-name\">{{ file.fileName }}</div>\n <div class=\"file-status\">\n @switch (file.stage) {\n @case ('pending') {\n <span class=\"text-yellow-600\">Waiting...</span>\n }\n @case ('reading') {\n <span class=\"text-yellow-600\">Reading...</span>\n }\n @case ('uploading') {\n <span class=\"text-blue-600\">Uploading...</span>\n }\n @case ('complete') {\n <span class=\"text-green-600\">Completed</span>\n }\n @case ('error') {\n <span class=\"text-red-600\">Failed</span>\n }\n }\n </div>\n </div>\n </div>\n\n <!-- Progress Bar (only for uploading files) -->\n @if (file.stage === 'uploading' && file.percentage !== undefined) {\n <div class=\"file-progress\">\n <div class=\"progress-bar\">\n <div class=\"progress-fill\" [style.width.%]=\"file.percentage\"></div>\n </div>\n <span class=\"progress-text\">{{ file.percentage }}%</span>\n </div>\n }\n\n <!-- Actions -->\n <div class=\"upload-actions\">\n @switch (file.stage) {\n @case ('pending') {\n <button class=\"action-btn cancel-btn\" (click)=\"cancelUpload(file.fileId)\" title=\"Cancel\">\n <cide-ele-icon size=\"xs\">cancel</cide-ele-icon>\n </button>\n }\n @case ('reading') {\n <button class=\"action-btn cancel-btn\" (click)=\"cancelUpload(file.fileId)\" title=\"Cancel\">\n <cide-ele-icon size=\"xs\">cancel</cide-ele-icon>\n </button>\n }\n @case ('uploading') {\n <button class=\"action-btn cancel-btn\" (click)=\"cancelUpload(file.fileId)\" title=\"Cancel\">\n <cide-ele-icon size=\"xs\">cancel</cide-ele-icon>\n </button>\n }\n @case ('complete') {\n <button class=\"action-btn success-btn\" title=\"Completed\">\n <cide-ele-icon size=\"xs\">check_circle</cide-ele-icon>\n </button>\n }\n @case ('error') {\n <button class=\"action-btn retry-btn\" title=\"Retry\">\n <cide-ele-icon size=\"xs\">refresh</cide-ele-icon>\n </button>\n }\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <!-- No uploads message when manually opened -->\n <div class=\"no-uploads-message\">\n <div class=\"message-content\">\n <cide-ele-icon size=\"md\" class=\"message-icon\">cloud_upload</cide-ele-icon>\n <div class=\"message-text\">\n <h4>No active uploads</h4>\n <p>Upload files to see their progress here</p>\n </div>\n </div>\n </div>\n }\n </div>\n }\n</div>\n}\n", styles: [".floating-uploader{position:fixed;width:320px;max-height:500px;background:#fff;border-radius:12px;box-shadow:0 8px 32px #0000001f;border:1px solid rgba(0,0,0,.08);z-index:1000;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateY(0);opacity:1}.floating-uploader.animating{transition:all .3s cubic-bezier(.4,0,.2,1)}.floating-uploader.minimized .uploader-content{display:none}.floating-uploader.minimized .uploader-footer{border-top:none}.floating-uploader.uploading{border-color:#3b82f6;box-shadow:0 8px 32px #3b82f626}.floating-uploader .uploader-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.floating-uploader .uploader-header.draggable-header{cursor:move;-webkit-user-select:none;user-select:none}.floating-uploader .uploader-header.draggable-header:hover{background:#f1f5f9}.floating-uploader .uploader-header.draggable-header:active{background:#e2e8f0;cursor:grabbing}.floating-uploader .uploader-header .header-left{display:flex;align-items:center;gap:8px}.floating-uploader .uploader-header .header-left .upload-icon{display:flex;align-items:center;justify-content:center;width:24px;height:24px;background:#3b82f6;border-radius:6px;color:#fff}.floating-uploader .uploader-header .header-left .upload-info .upload-title{font-size:14px;font-weight:600;color:#1e293b;margin:0}.floating-uploader .uploader-header .header-left .upload-info .upload-summary{font-size:12px;color:#64748b;margin:0}.floating-uploader .uploader-header .header-actions{display:flex;gap:4px}.floating-uploader .uploader-header .header-actions .action-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border:none;background:transparent;border-radius:4px;cursor:pointer;transition:background-color .2s;color:#64748b}.floating-uploader .uploader-header .header-actions .action-btn:hover{background:#e2e8f0;color:#1e293b}.floating-uploader .uploader-header .header-actions .action-btn.close-btn:hover{background:#fef2f2;color:#dc2626}.floating-uploader .uploader-content{max-height:400px;overflow-y:auto}.floating-uploader .uploader-content .upload-zone{margin:8px 16px;padding:12px;border:2px dashed #d1d5db;border-radius:6px;background:#f9fafb;cursor:pointer;transition:all .2s ease;text-align:center}.floating-uploader .uploader-content .upload-zone:hover{border-color:#3b82f6;background:#f0f9ff}.floating-uploader .uploader-content .upload-zone.drag-over{border-color:#3b82f6;background:#dbeafe;transform:scale(1.01)}.floating-uploader .uploader-content .upload-zone .upload-zone-content{display:flex;flex-direction:column;align-items:center;gap:6px}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-icon{color:#6b7280;transition:color .2s ease}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-text .upload-title{font-size:13px;font-weight:500;color:#374151;margin:0;line-height:1.2}.floating-uploader .uploader-content .upload-zone:hover .upload-zone-content .upload-icon{color:#3b82f6}.floating-uploader .uploader-content .upload-zone.drag-over .upload-zone-content .upload-icon{color:#1d4ed8}.floating-uploader .uploader-content .upload-queue .upload-item{display:flex;align-items:center;padding:8px 16px;border-bottom:1px solid #f1f5f9;transition:background-color .2s}.floating-uploader .uploader-content .upload-queue .upload-item:last-child{border-bottom:none}.floating-uploader .uploader-content .upload-queue .upload-item.status-uploading{background:#f0f9ff}.floating-uploader .uploader-content .upload-queue .upload-item.status-completed{background:#f0fdf4}.floating-uploader .uploader-content .upload-queue .upload-item.status-error{background:#fef2f2}.floating-uploader .uploader-content .upload-queue .upload-item .file-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .status-icon{flex-shrink:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details{min-width:0;flex:1}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-name{font-size:13px;font-weight:500;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-status{font-size:11px;margin:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-status span{font-weight:500}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress{display:flex;align-items:center;gap:8px;margin:0 8px;min-width:80px}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar{flex:1;height:3px;background:#e2e8f0;border-radius:2px;overflow:hidden}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar .progress-fill{height:100%;background:#3b82f6;transition:width .3s ease}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-text{font-size:10px;color:#64748b;min-width:24px;text-align:right}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions{display:flex;gap:4px}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn{display:flex;align-items:center;justify-content:center;width:20px;height:20px;border:none;background:transparent;border-radius:4px;cursor:pointer;transition:all .2s;color:#64748b}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn:hover{background:#e2e8f0}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.cancel-btn:hover{background:#fef2f2;color:#dc2626}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.retry-btn:hover{background:#f0f9ff;color:#3b82f6}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.success-btn{color:#16a34a}.floating-uploader .uploader-content .hidden-uploader{display:none}.floating-uploader .uploader-footer{padding:8px 16px;background:#f8fafc;border-top:1px solid #e2e8f0}.floating-uploader .uploader-footer .footer-stats{display:flex;gap:12px;font-size:11px}.floating-uploader .uploader-footer .footer-stats .stat{display:flex;align-items:center;gap:4px;color:#64748b}.floating-uploader .uploader-footer .footer-stats .stat.uploading{color:#3b82f6}.floating-uploader .uploader-footer .footer-stats .stat.completed{color:#16a34a}.floating-uploader .uploader-footer .footer-stats .stat.failed{color:#dc2626}@media (max-width: 640px){.floating-uploader{bottom:10px;right:10px;left:10px;width:auto;max-width:none}}@media (prefers-color-scheme: dark){.floating-uploader{background:#1e293b;border-color:#334155;box-shadow:0 8px 32px #0000004d}.floating-uploader.uploading{border-color:#3b82f6;box-shadow:0 8px 32px #3b82f633}.floating-uploader .uploader-header{background:#334155;border-bottom-color:#475569}.floating-uploader .uploader-header.draggable-header:hover{background:#475569}.floating-uploader .uploader-header.draggable-header:active{background:#64748b}.floating-uploader .uploader-header .header-left .upload-icon{background:#3b82f6}.floating-uploader .uploader-header .header-left .upload-info .upload-title{color:#f1f5f9}.floating-uploader .uploader-header .header-left .upload-info .upload-summary,.floating-uploader .uploader-header .header-actions .action-btn{color:#94a3b8}.floating-uploader .uploader-header .header-actions .action-btn:hover{background:#475569;color:#f1f5f9}.floating-uploader .uploader-header .header-actions .action-btn.close-btn:hover{background:#7f1d1d;color:#fca5a5}.floating-uploader .uploader-content .upload-zone{border-color:#475569;background:#334155}.floating-uploader .uploader-content .upload-zone:hover{border-color:#3b82f6;background:#1e3a8a}.floating-uploader .uploader-content .upload-zone.drag-over{border-color:#60a5fa;background:#1e40af}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-icon{color:#94a3b8}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-text .upload-title{color:#f1f5f9}.floating-uploader .uploader-content .upload-zone:hover .upload-zone-content .upload-icon{color:#60a5fa}.floating-uploader .uploader-content .upload-zone.drag-over .upload-zone-content .upload-icon{color:#93c5fd}.floating-uploader .uploader-content .upload-queue .upload-item{border-bottom-color:#334155}.floating-uploader .uploader-content .upload-queue .upload-item.status-uploading{background:#1e3a8a}.floating-uploader .uploader-content .upload-queue .upload-item.status-completed{background:#14532d}.floating-uploader .uploader-content .upload-queue .upload-item.status-error{background:#7f1d1d}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-name{color:#f1f5f9}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar{background:#475569}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar .progress-fill{background:#3b82f6}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-text,.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn{color:#94a3b8}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn:hover{background:#475569}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.cancel-btn:hover{background:#7f1d1d;color:#fca5a5}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.retry-btn:hover{background:#1e3a8a;color:#60a5fa}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.success-btn{color:#4ade80}.floating-uploader .uploader-footer{background:#334155;border-top-color:#475569}.floating-uploader .uploader-footer .footer-stats .stat{color:#94a3b8}.floating-uploader .uploader-footer .footer-stats .stat.uploading{color:#60a5fa}.floating-uploader .uploader-footer .footer-stats .stat.completed{color:#4ade80}.floating-uploader .uploader-footer .footer-stats .stat.failed{color:#fca5a5}}@keyframes slideInUp{0%{transform:translateY(100%);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes slideOutDown{0%{transform:translateY(0);opacity:1}to{transform:translateY(100%);opacity:0}}.floating-uploader.animating{animation:slideInUp .3s cubic-bezier(.4,0,.2,1)}.floating-uploader.animating.hiding{animation:slideOutDown .3s cubic-bezier(.4,0,.2,1)}.no-uploads-message{padding:2rem;text-align:center;color:#6b7280}.no-uploads-message .message-content{display:flex;flex-direction:column;align-items:center;gap:1rem}.no-uploads-message .message-content .message-icon{color:#9ca3af;opacity:.7}.no-uploads-message .message-content .message-text h4{margin:0 0 .5rem;font-size:1.1rem;font-weight:600;color:#374151}.no-uploads-message .message-content .message-text p{margin:0;font-size:.9rem;color:#6b7280}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }] });
5564
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleFloatingFileUploaderComponent, isStandalone: true, selector: "cide-ele-floating-file-uploader", inputs: { data: "data" }, ngImport: i0, template: "<!-- Floating File Uploader Container -->\n@if (isVisible()) {\n<div class=\"floating-uploader\" \n [class.minimized]=\"isMinimized()\" \n [class.animating]=\"isAnimating()\"\n [style.left.px]=\"position().x\"\n [style.top.px]=\"position().y\">\n\n <!-- Header (Draggable) -->\n <div class=\"uploader-header draggable-header\"\n (mousedown)=\"startDrag($event)\"\n (touchstart)=\"startDrag($event)\">\n <div class=\"header-left\">\n <div class=\"upload-icon\">\n <cide-ele-icon size=\"sm\">cloud_upload</cide-ele-icon>\n </div>\n <div class=\"upload-info\">\n <div class=\"upload-title\">File Upload</div>\n <div class=\"upload-summary\">{{ getUploadSummary() }}</div>\n </div>\n </div>\n \n <div class=\"header-actions\">\n <button class=\"action-btn minimize-btn\" (click)=\"toggleMinimize()\" [title]=\"isMinimized() ? 'Expand' : 'Minimize'\">\n <cide-ele-icon size=\"xs\">{{ isMinimized() ? 'expand_more' : 'expand_less' }}</cide-ele-icon>\n </button>\n <button class=\"action-btn close-btn\" (click)=\"close()\" title=\"Close\">\n <cide-ele-icon size=\"xs\">close</cide-ele-icon>\n </button>\n </div>\n </div>\n\n <!-- Content (hidden when minimized) -->\n @if (!isMinimized()) {\n <div class=\"uploader-content\">\n \n <!-- Drag and Drop Zone -->\n <div class=\"upload-zone\" \n [class.drag-over]=\"isDragOver()\" \n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\" \n (drop)=\"onDrop($event)\" \n (click)=\"triggerFileInput()\">\n \n <!-- Hidden file input -->\n <input #fileInput \n type=\"file\" \n [multiple]=\"true\" \n [accept]=\"'*/*'\" \n (change)=\"onFileInputChange($event)\" \n style=\"display: none;\">\n \n <div class=\"upload-zone-content\">\n <cide-ele-icon class=\"upload-icon\" size=\"sm\">cloud_upload</cide-ele-icon>\n \n <div class=\"upload-text\">\n <div class=\"upload-title\">\n {{ isDragOver() ? 'Drop files here' : 'Drag files here or click to browse' }}\n </div>\n </div>\n </div>\n </div>\n \n <!-- Upload Queue - Show files from service state -->\n @if (allFilesForGroup().length > 0) {\n <div class=\"upload-queue\">\n <!-- Show all files from service state -->\n @for (file of allFilesForGroup(); track file.fileId) {\n <div class=\"upload-item\" [class]=\"getStatusClass(file.stage)\">\n <div class=\"file-info\">\n <cide-ele-icon class=\"status-icon\" size=\"xs\">{{ getStatusIcon(file.stage) }}</cide-ele-icon>\n <div class=\"file-details\">\n <div class=\"file-name\">{{ file.fileName }}</div>\n <div class=\"file-status\">\n @switch (file.stage) {\n @case ('pending') {\n <span class=\"text-yellow-600\">Waiting...</span>\n }\n @case ('reading') {\n <span class=\"text-yellow-600\">Reading...</span>\n }\n @case ('uploading') {\n <span class=\"text-blue-600\">Uploading...</span>\n }\n @case ('complete') {\n <span class=\"text-green-600\">Completed</span>\n }\n @case ('error') {\n <span class=\"text-red-600\">Failed</span>\n }\n }\n </div>\n </div>\n </div>\n\n <!-- Progress Bar (only for uploading files) -->\n @if (file.stage === 'uploading' && file.percentage !== undefined) {\n <div class=\"file-progress\">\n <div class=\"progress-bar\">\n <div class=\"progress-fill\" [style.width.%]=\"file.percentage\"></div>\n </div>\n <span class=\"progress-text\">{{ file.percentage }}%</span>\n </div>\n }\n\n <!-- Actions -->\n <div class=\"upload-actions\">\n @switch (file.stage) {\n @case ('pending') {\n <button class=\"action-btn cancel-btn\" (click)=\"cancelUpload(file.fileId)\" title=\"Cancel\">\n <cide-ele-icon size=\"xs\">cancel</cide-ele-icon>\n </button>\n }\n @case ('reading') {\n <button class=\"action-btn cancel-btn\" (click)=\"cancelUpload(file.fileId)\" title=\"Cancel\">\n <cide-ele-icon size=\"xs\">cancel</cide-ele-icon>\n </button>\n }\n @case ('uploading') {\n <button class=\"action-btn cancel-btn\" (click)=\"cancelUpload(file.fileId)\" title=\"Cancel\">\n <cide-ele-icon size=\"xs\">cancel</cide-ele-icon>\n </button>\n }\n @case ('complete') {\n <button class=\"action-btn success-btn\" title=\"Completed\">\n <cide-ele-icon size=\"xs\">check_circle</cide-ele-icon>\n </button>\n }\n @case ('error') {\n <button class=\"action-btn retry-btn\" title=\"Retry\">\n <cide-ele-icon size=\"xs\">refresh</cide-ele-icon>\n </button>\n }\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <!-- No uploads message when manually opened -->\n <div class=\"no-uploads-message\">\n <div class=\"message-content\">\n <cide-ele-icon size=\"md\" class=\"message-icon\">cloud_upload</cide-ele-icon>\n <div class=\"message-text\">\n <h4>No active uploads</h4>\n <p>Upload files to see their progress here</p>\n </div>\n </div>\n </div>\n }\n </div>\n }\n</div>\n}\n", styles: [".floating-uploader{position:fixed;width:320px;max-height:500px;background:#fff;border-radius:12px;box-shadow:0 8px 32px #0000001f;border:1px solid rgba(0,0,0,.08);z-index:1000;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateY(0);opacity:1}.floating-uploader.animating{transition:all .3s cubic-bezier(.4,0,.2,1)}.floating-uploader.minimized .uploader-content{display:none}.floating-uploader.minimized .uploader-footer{border-top:none}.floating-uploader.uploading{border-color:#3b82f6;box-shadow:0 8px 32px #3b82f626}.floating-uploader .uploader-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.floating-uploader .uploader-header.draggable-header{cursor:move;-webkit-user-select:none;user-select:none}.floating-uploader .uploader-header.draggable-header:hover{background:#f1f5f9}.floating-uploader .uploader-header.draggable-header:active{background:#e2e8f0;cursor:grabbing}.floating-uploader .uploader-header .header-left{display:flex;align-items:center;gap:8px}.floating-uploader .uploader-header .header-left .upload-icon{display:flex;align-items:center;justify-content:center;width:24px;height:24px;background:#3b82f6;border-radius:6px;color:#fff}.floating-uploader .uploader-header .header-left .upload-info .upload-title{font-size:14px;font-weight:600;color:#1e293b;margin:0}.floating-uploader .uploader-header .header-left .upload-info .upload-summary{font-size:12px;color:#64748b;margin:0}.floating-uploader .uploader-header .header-actions{display:flex;gap:4px}.floating-uploader .uploader-header .header-actions .action-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border:none;background:transparent;border-radius:4px;cursor:pointer;transition:background-color .2s;color:#64748b}.floating-uploader .uploader-header .header-actions .action-btn:hover{background:#e2e8f0;color:#1e293b}.floating-uploader .uploader-header .header-actions .action-btn.close-btn:hover{background:#fef2f2;color:#dc2626}.floating-uploader .uploader-content{max-height:400px;overflow-y:auto}.floating-uploader .uploader-content .upload-zone{margin:8px 16px;padding:12px;border:2px dashed #d1d5db;border-radius:6px;background:#f9fafb;cursor:pointer;transition:all .2s ease;text-align:center}.floating-uploader .uploader-content .upload-zone:hover{border-color:#3b82f6;background:#f0f9ff}.floating-uploader .uploader-content .upload-zone.drag-over{border-color:#3b82f6;background:#dbeafe;transform:scale(1.01)}.floating-uploader .uploader-content .upload-zone .upload-zone-content{display:flex;flex-direction:column;align-items:center;gap:6px}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-icon{color:#6b7280;transition:color .2s ease}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-text .upload-title{font-size:13px;font-weight:500;color:#374151;margin:0;line-height:1.2}.floating-uploader .uploader-content .upload-zone:hover .upload-zone-content .upload-icon{color:#3b82f6}.floating-uploader .uploader-content .upload-zone.drag-over .upload-zone-content .upload-icon{color:#1d4ed8}.floating-uploader .uploader-content .upload-queue .upload-item{display:flex;align-items:center;padding:8px 16px;border-bottom:1px solid #f1f5f9;transition:background-color .2s}.floating-uploader .uploader-content .upload-queue .upload-item:last-child{border-bottom:none}.floating-uploader .uploader-content .upload-queue .upload-item.status-uploading{background:#f0f9ff}.floating-uploader .uploader-content .upload-queue .upload-item.status-completed{background:#f0fdf4}.floating-uploader .uploader-content .upload-queue .upload-item.status-error{background:#fef2f2}.floating-uploader .uploader-content .upload-queue .upload-item .file-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .status-icon{flex-shrink:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details{min-width:0;flex:1}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-name{font-size:13px;font-weight:500;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-status{font-size:11px;margin:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-status span{font-weight:500}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress{display:flex;align-items:center;gap:8px;margin:0 8px;min-width:80px}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar{flex:1;height:3px;background:#e2e8f0;border-radius:2px;overflow:hidden}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar .progress-fill{height:100%;background:#3b82f6;transition:width .3s ease}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-text{font-size:10px;color:#64748b;min-width:24px;text-align:right}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions{display:flex;gap:4px}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn{display:flex;align-items:center;justify-content:center;width:20px;height:20px;border:none;background:transparent;border-radius:4px;cursor:pointer;transition:all .2s;color:#64748b}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn:hover{background:#e2e8f0}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.cancel-btn:hover{background:#fef2f2;color:#dc2626}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.retry-btn:hover{background:#f0f9ff;color:#3b82f6}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.success-btn{color:#16a34a}.floating-uploader .uploader-content .hidden-uploader{display:none}.floating-uploader .uploader-footer{padding:8px 16px;background:#f8fafc;border-top:1px solid #e2e8f0}.floating-uploader .uploader-footer .footer-stats{display:flex;gap:12px;font-size:11px}.floating-uploader .uploader-footer .footer-stats .stat{display:flex;align-items:center;gap:4px;color:#64748b}.floating-uploader .uploader-footer .footer-stats .stat.uploading{color:#3b82f6}.floating-uploader .uploader-footer .footer-stats .stat.completed{color:#16a34a}.floating-uploader .uploader-footer .footer-stats .stat.failed{color:#dc2626}@media (max-width: 640px){.floating-uploader{bottom:10px;right:10px;left:10px;width:auto;max-width:none}}@media (prefers-color-scheme: dark){.floating-uploader{background:#1e293b;border-color:#334155;box-shadow:0 8px 32px #0000004d}.floating-uploader.uploading{border-color:#3b82f6;box-shadow:0 8px 32px #3b82f633}.floating-uploader .uploader-header{background:#334155;border-bottom-color:#475569}.floating-uploader .uploader-header.draggable-header:hover{background:#475569}.floating-uploader .uploader-header.draggable-header:active{background:#64748b}.floating-uploader .uploader-header .header-left .upload-icon{background:#3b82f6}.floating-uploader .uploader-header .header-left .upload-info .upload-title{color:#f1f5f9}.floating-uploader .uploader-header .header-left .upload-info .upload-summary,.floating-uploader .uploader-header .header-actions .action-btn{color:#94a3b8}.floating-uploader .uploader-header .header-actions .action-btn:hover{background:#475569;color:#f1f5f9}.floating-uploader .uploader-header .header-actions .action-btn.close-btn:hover{background:#7f1d1d;color:#fca5a5}.floating-uploader .uploader-content .upload-zone{border-color:#475569;background:#334155}.floating-uploader .uploader-content .upload-zone:hover{border-color:#3b82f6;background:#1e3a8a}.floating-uploader .uploader-content .upload-zone.drag-over{border-color:#60a5fa;background:#1e40af}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-icon{color:#94a3b8}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-text .upload-title{color:#f1f5f9}.floating-uploader .uploader-content .upload-zone:hover .upload-zone-content .upload-icon{color:#60a5fa}.floating-uploader .uploader-content .upload-zone.drag-over .upload-zone-content .upload-icon{color:#93c5fd}.floating-uploader .uploader-content .upload-queue .upload-item{border-bottom-color:#334155}.floating-uploader .uploader-content .upload-queue .upload-item.status-uploading{background:#1e3a8a}.floating-uploader .uploader-content .upload-queue .upload-item.status-completed{background:#14532d}.floating-uploader .uploader-content .upload-queue .upload-item.status-error{background:#7f1d1d}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-name{color:#f1f5f9}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar{background:#475569}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar .progress-fill{background:#3b82f6}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-text,.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn{color:#94a3b8}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn:hover{background:#475569}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.cancel-btn:hover{background:#7f1d1d;color:#fca5a5}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.retry-btn:hover{background:#1e3a8a;color:#60a5fa}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.success-btn{color:#4ade80}.floating-uploader .uploader-footer{background:#334155;border-top-color:#475569}.floating-uploader .uploader-footer .footer-stats .stat{color:#94a3b8}.floating-uploader .uploader-footer .footer-stats .stat.uploading{color:#60a5fa}.floating-uploader .uploader-footer .footer-stats .stat.completed{color:#4ade80}.floating-uploader .uploader-footer .footer-stats .stat.failed{color:#fca5a5}}@keyframes slideInUp{0%{transform:translateY(100%);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes slideOutDown{0%{transform:translateY(0);opacity:1}to{transform:translateY(100%);opacity:0}}.floating-uploader.animating{animation:slideInUp .3s cubic-bezier(.4,0,.2,1)}.floating-uploader.animating.hiding{animation:slideOutDown .3s cubic-bezier(.4,0,.2,1)}.no-uploads-message{padding:2rem;text-align:center;color:#6b7280}.no-uploads-message .message-content{display:flex;flex-direction:column;align-items:center;gap:1rem}.no-uploads-message .message-content .message-icon{color:#9ca3af;opacity:.7}.no-uploads-message .message-content .message-text h4{margin:0 0 .5rem;font-size:1.1rem;font-weight:600;color:#374151}.no-uploads-message .message-content .message-text p{margin:0;font-size:.9rem;color:#6b7280}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }] });
5472
5565
  }
5473
5566
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingFileUploaderComponent, decorators: [{
5474
5567
  type: Component,
@@ -5476,7 +5569,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
5476
5569
  CommonModule,
5477
5570
  CideIconComponent
5478
5571
  ], template: "<!-- Floating File Uploader Container -->\n@if (isVisible()) {\n<div class=\"floating-uploader\" \n [class.minimized]=\"isMinimized()\" \n [class.animating]=\"isAnimating()\"\n [style.left.px]=\"position().x\"\n [style.top.px]=\"position().y\">\n\n <!-- Header (Draggable) -->\n <div class=\"uploader-header draggable-header\"\n (mousedown)=\"startDrag($event)\"\n (touchstart)=\"startDrag($event)\">\n <div class=\"header-left\">\n <div class=\"upload-icon\">\n <cide-ele-icon size=\"sm\">cloud_upload</cide-ele-icon>\n </div>\n <div class=\"upload-info\">\n <div class=\"upload-title\">File Upload</div>\n <div class=\"upload-summary\">{{ getUploadSummary() }}</div>\n </div>\n </div>\n \n <div class=\"header-actions\">\n <button class=\"action-btn minimize-btn\" (click)=\"toggleMinimize()\" [title]=\"isMinimized() ? 'Expand' : 'Minimize'\">\n <cide-ele-icon size=\"xs\">{{ isMinimized() ? 'expand_more' : 'expand_less' }}</cide-ele-icon>\n </button>\n <button class=\"action-btn close-btn\" (click)=\"close()\" title=\"Close\">\n <cide-ele-icon size=\"xs\">close</cide-ele-icon>\n </button>\n </div>\n </div>\n\n <!-- Content (hidden when minimized) -->\n @if (!isMinimized()) {\n <div class=\"uploader-content\">\n \n <!-- Drag and Drop Zone -->\n <div class=\"upload-zone\" \n [class.drag-over]=\"isDragOver()\" \n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\" \n (drop)=\"onDrop($event)\" \n (click)=\"triggerFileInput()\">\n \n <!-- Hidden file input -->\n <input #fileInput \n type=\"file\" \n [multiple]=\"true\" \n [accept]=\"'*/*'\" \n (change)=\"onFileInputChange($event)\" \n style=\"display: none;\">\n \n <div class=\"upload-zone-content\">\n <cide-ele-icon class=\"upload-icon\" size=\"sm\">cloud_upload</cide-ele-icon>\n \n <div class=\"upload-text\">\n <div class=\"upload-title\">\n {{ isDragOver() ? 'Drop files here' : 'Drag files here or click to browse' }}\n </div>\n </div>\n </div>\n </div>\n \n <!-- Upload Queue - Show files from service state -->\n @if (allFilesForGroup().length > 0) {\n <div class=\"upload-queue\">\n <!-- Show all files from service state -->\n @for (file of allFilesForGroup(); track file.fileId) {\n <div class=\"upload-item\" [class]=\"getStatusClass(file.stage)\">\n <div class=\"file-info\">\n <cide-ele-icon class=\"status-icon\" size=\"xs\">{{ getStatusIcon(file.stage) }}</cide-ele-icon>\n <div class=\"file-details\">\n <div class=\"file-name\">{{ file.fileName }}</div>\n <div class=\"file-status\">\n @switch (file.stage) {\n @case ('pending') {\n <span class=\"text-yellow-600\">Waiting...</span>\n }\n @case ('reading') {\n <span class=\"text-yellow-600\">Reading...</span>\n }\n @case ('uploading') {\n <span class=\"text-blue-600\">Uploading...</span>\n }\n @case ('complete') {\n <span class=\"text-green-600\">Completed</span>\n }\n @case ('error') {\n <span class=\"text-red-600\">Failed</span>\n }\n }\n </div>\n </div>\n </div>\n\n <!-- Progress Bar (only for uploading files) -->\n @if (file.stage === 'uploading' && file.percentage !== undefined) {\n <div class=\"file-progress\">\n <div class=\"progress-bar\">\n <div class=\"progress-fill\" [style.width.%]=\"file.percentage\"></div>\n </div>\n <span class=\"progress-text\">{{ file.percentage }}%</span>\n </div>\n }\n\n <!-- Actions -->\n <div class=\"upload-actions\">\n @switch (file.stage) {\n @case ('pending') {\n <button class=\"action-btn cancel-btn\" (click)=\"cancelUpload(file.fileId)\" title=\"Cancel\">\n <cide-ele-icon size=\"xs\">cancel</cide-ele-icon>\n </button>\n }\n @case ('reading') {\n <button class=\"action-btn cancel-btn\" (click)=\"cancelUpload(file.fileId)\" title=\"Cancel\">\n <cide-ele-icon size=\"xs\">cancel</cide-ele-icon>\n </button>\n }\n @case ('uploading') {\n <button class=\"action-btn cancel-btn\" (click)=\"cancelUpload(file.fileId)\" title=\"Cancel\">\n <cide-ele-icon size=\"xs\">cancel</cide-ele-icon>\n </button>\n }\n @case ('complete') {\n <button class=\"action-btn success-btn\" title=\"Completed\">\n <cide-ele-icon size=\"xs\">check_circle</cide-ele-icon>\n </button>\n }\n @case ('error') {\n <button class=\"action-btn retry-btn\" title=\"Retry\">\n <cide-ele-icon size=\"xs\">refresh</cide-ele-icon>\n </button>\n }\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <!-- No uploads message when manually opened -->\n <div class=\"no-uploads-message\">\n <div class=\"message-content\">\n <cide-ele-icon size=\"md\" class=\"message-icon\">cloud_upload</cide-ele-icon>\n <div class=\"message-text\">\n <h4>No active uploads</h4>\n <p>Upload files to see their progress here</p>\n </div>\n </div>\n </div>\n }\n </div>\n }\n</div>\n}\n", styles: [".floating-uploader{position:fixed;width:320px;max-height:500px;background:#fff;border-radius:12px;box-shadow:0 8px 32px #0000001f;border:1px solid rgba(0,0,0,.08);z-index:1000;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateY(0);opacity:1}.floating-uploader.animating{transition:all .3s cubic-bezier(.4,0,.2,1)}.floating-uploader.minimized .uploader-content{display:none}.floating-uploader.minimized .uploader-footer{border-top:none}.floating-uploader.uploading{border-color:#3b82f6;box-shadow:0 8px 32px #3b82f626}.floating-uploader .uploader-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.floating-uploader .uploader-header.draggable-header{cursor:move;-webkit-user-select:none;user-select:none}.floating-uploader .uploader-header.draggable-header:hover{background:#f1f5f9}.floating-uploader .uploader-header.draggable-header:active{background:#e2e8f0;cursor:grabbing}.floating-uploader .uploader-header .header-left{display:flex;align-items:center;gap:8px}.floating-uploader .uploader-header .header-left .upload-icon{display:flex;align-items:center;justify-content:center;width:24px;height:24px;background:#3b82f6;border-radius:6px;color:#fff}.floating-uploader .uploader-header .header-left .upload-info .upload-title{font-size:14px;font-weight:600;color:#1e293b;margin:0}.floating-uploader .uploader-header .header-left .upload-info .upload-summary{font-size:12px;color:#64748b;margin:0}.floating-uploader .uploader-header .header-actions{display:flex;gap:4px}.floating-uploader .uploader-header .header-actions .action-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border:none;background:transparent;border-radius:4px;cursor:pointer;transition:background-color .2s;color:#64748b}.floating-uploader .uploader-header .header-actions .action-btn:hover{background:#e2e8f0;color:#1e293b}.floating-uploader .uploader-header .header-actions .action-btn.close-btn:hover{background:#fef2f2;color:#dc2626}.floating-uploader .uploader-content{max-height:400px;overflow-y:auto}.floating-uploader .uploader-content .upload-zone{margin:8px 16px;padding:12px;border:2px dashed #d1d5db;border-radius:6px;background:#f9fafb;cursor:pointer;transition:all .2s ease;text-align:center}.floating-uploader .uploader-content .upload-zone:hover{border-color:#3b82f6;background:#f0f9ff}.floating-uploader .uploader-content .upload-zone.drag-over{border-color:#3b82f6;background:#dbeafe;transform:scale(1.01)}.floating-uploader .uploader-content .upload-zone .upload-zone-content{display:flex;flex-direction:column;align-items:center;gap:6px}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-icon{color:#6b7280;transition:color .2s ease}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-text .upload-title{font-size:13px;font-weight:500;color:#374151;margin:0;line-height:1.2}.floating-uploader .uploader-content .upload-zone:hover .upload-zone-content .upload-icon{color:#3b82f6}.floating-uploader .uploader-content .upload-zone.drag-over .upload-zone-content .upload-icon{color:#1d4ed8}.floating-uploader .uploader-content .upload-queue .upload-item{display:flex;align-items:center;padding:8px 16px;border-bottom:1px solid #f1f5f9;transition:background-color .2s}.floating-uploader .uploader-content .upload-queue .upload-item:last-child{border-bottom:none}.floating-uploader .uploader-content .upload-queue .upload-item.status-uploading{background:#f0f9ff}.floating-uploader .uploader-content .upload-queue .upload-item.status-completed{background:#f0fdf4}.floating-uploader .uploader-content .upload-queue .upload-item.status-error{background:#fef2f2}.floating-uploader .uploader-content .upload-queue .upload-item .file-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .status-icon{flex-shrink:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details{min-width:0;flex:1}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-name{font-size:13px;font-weight:500;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-status{font-size:11px;margin:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-status span{font-weight:500}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress{display:flex;align-items:center;gap:8px;margin:0 8px;min-width:80px}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar{flex:1;height:3px;background:#e2e8f0;border-radius:2px;overflow:hidden}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar .progress-fill{height:100%;background:#3b82f6;transition:width .3s ease}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-text{font-size:10px;color:#64748b;min-width:24px;text-align:right}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions{display:flex;gap:4px}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn{display:flex;align-items:center;justify-content:center;width:20px;height:20px;border:none;background:transparent;border-radius:4px;cursor:pointer;transition:all .2s;color:#64748b}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn:hover{background:#e2e8f0}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.cancel-btn:hover{background:#fef2f2;color:#dc2626}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.retry-btn:hover{background:#f0f9ff;color:#3b82f6}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.success-btn{color:#16a34a}.floating-uploader .uploader-content .hidden-uploader{display:none}.floating-uploader .uploader-footer{padding:8px 16px;background:#f8fafc;border-top:1px solid #e2e8f0}.floating-uploader .uploader-footer .footer-stats{display:flex;gap:12px;font-size:11px}.floating-uploader .uploader-footer .footer-stats .stat{display:flex;align-items:center;gap:4px;color:#64748b}.floating-uploader .uploader-footer .footer-stats .stat.uploading{color:#3b82f6}.floating-uploader .uploader-footer .footer-stats .stat.completed{color:#16a34a}.floating-uploader .uploader-footer .footer-stats .stat.failed{color:#dc2626}@media (max-width: 640px){.floating-uploader{bottom:10px;right:10px;left:10px;width:auto;max-width:none}}@media (prefers-color-scheme: dark){.floating-uploader{background:#1e293b;border-color:#334155;box-shadow:0 8px 32px #0000004d}.floating-uploader.uploading{border-color:#3b82f6;box-shadow:0 8px 32px #3b82f633}.floating-uploader .uploader-header{background:#334155;border-bottom-color:#475569}.floating-uploader .uploader-header.draggable-header:hover{background:#475569}.floating-uploader .uploader-header.draggable-header:active{background:#64748b}.floating-uploader .uploader-header .header-left .upload-icon{background:#3b82f6}.floating-uploader .uploader-header .header-left .upload-info .upload-title{color:#f1f5f9}.floating-uploader .uploader-header .header-left .upload-info .upload-summary,.floating-uploader .uploader-header .header-actions .action-btn{color:#94a3b8}.floating-uploader .uploader-header .header-actions .action-btn:hover{background:#475569;color:#f1f5f9}.floating-uploader .uploader-header .header-actions .action-btn.close-btn:hover{background:#7f1d1d;color:#fca5a5}.floating-uploader .uploader-content .upload-zone{border-color:#475569;background:#334155}.floating-uploader .uploader-content .upload-zone:hover{border-color:#3b82f6;background:#1e3a8a}.floating-uploader .uploader-content .upload-zone.drag-over{border-color:#60a5fa;background:#1e40af}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-icon{color:#94a3b8}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-text .upload-title{color:#f1f5f9}.floating-uploader .uploader-content .upload-zone:hover .upload-zone-content .upload-icon{color:#60a5fa}.floating-uploader .uploader-content .upload-zone.drag-over .upload-zone-content .upload-icon{color:#93c5fd}.floating-uploader .uploader-content .upload-queue .upload-item{border-bottom-color:#334155}.floating-uploader .uploader-content .upload-queue .upload-item.status-uploading{background:#1e3a8a}.floating-uploader .uploader-content .upload-queue .upload-item.status-completed{background:#14532d}.floating-uploader .uploader-content .upload-queue .upload-item.status-error{background:#7f1d1d}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-name{color:#f1f5f9}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar{background:#475569}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar .progress-fill{background:#3b82f6}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-text,.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn{color:#94a3b8}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn:hover{background:#475569}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.cancel-btn:hover{background:#7f1d1d;color:#fca5a5}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.retry-btn:hover{background:#1e3a8a;color:#60a5fa}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.success-btn{color:#4ade80}.floating-uploader .uploader-footer{background:#334155;border-top-color:#475569}.floating-uploader .uploader-footer .footer-stats .stat{color:#94a3b8}.floating-uploader .uploader-footer .footer-stats .stat.uploading{color:#60a5fa}.floating-uploader .uploader-footer .footer-stats .stat.completed{color:#4ade80}.floating-uploader .uploader-footer .footer-stats .stat.failed{color:#fca5a5}}@keyframes slideInUp{0%{transform:translateY(100%);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes slideOutDown{0%{transform:translateY(0);opacity:1}to{transform:translateY(100%);opacity:0}}.floating-uploader.animating{animation:slideInUp .3s cubic-bezier(.4,0,.2,1)}.floating-uploader.animating.hiding{animation:slideOutDown .3s cubic-bezier(.4,0,.2,1)}.no-uploads-message{padding:2rem;text-align:center;color:#6b7280}.no-uploads-message .message-content{display:flex;flex-direction:column;align-items:center;gap:1rem}.no-uploads-message .message-content .message-icon{color:#9ca3af;opacity:.7}.no-uploads-message .message-content .message-text h4{margin:0 0 .5rem;font-size:1.1rem;font-weight:600;color:#374151}.no-uploads-message .message-content .message-text p{margin:0;font-size:.9rem;color:#6b7280}\n"] }]
5479
- }], ctorParameters: () => [] });
5572
+ }], ctorParameters: () => [], propDecorators: { data: [{
5573
+ type: Input
5574
+ }] } });
5480
5575
 
5481
5576
  var floatingFileUploader_component = /*#__PURE__*/Object.freeze({
5482
5577
  __proto__: null,
@@ -5632,6 +5727,510 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
5632
5727
  type: Output
5633
5728
  }] } });
5634
5729
 
5730
+ class KeyboardShortcutService {
5731
+ shortcuts = new Map();
5732
+ overrides = new Map();
5733
+ keydownListener;
5734
+ constructor() {
5735
+ this.setupGlobalListener();
5736
+ }
5737
+ ngOnDestroy() {
5738
+ this.removeGlobalListener();
5739
+ }
5740
+ /**
5741
+ * Register a new keyboard shortcut
5742
+ */
5743
+ register(shortcut) {
5744
+ this.shortcuts.set(shortcut.id, shortcut);
5745
+ console.log(`⌨️ [KeyboardShortcut] Registered shortcut: ${shortcut.id} (${this.getKeyDescription(shortcut)})`);
5746
+ }
5747
+ /**
5748
+ * Override an existing shortcut with new key combination
5749
+ */
5750
+ override(shortcutId, newKey, options) {
5751
+ const originalShortcut = this.shortcuts.get(shortcutId);
5752
+ if (!originalShortcut) {
5753
+ console.warn(`⚠️ [KeyboardShortcut] Cannot override shortcut '${shortcutId}' - not found`);
5754
+ return;
5755
+ }
5756
+ const override = {
5757
+ shortcutId,
5758
+ newKey,
5759
+ newCtrlKey: options?.ctrlKey,
5760
+ newAltKey: options?.altKey,
5761
+ newShiftKey: options?.shiftKey,
5762
+ newMetaKey: options?.metaKey
5763
+ };
5764
+ this.overrides.set(shortcutId, override);
5765
+ console.log(`🔄 [KeyboardShortcut] Override registered for '${shortcutId}': ${this.getKeyDescription({ ...originalShortcut, ...options, key: newKey })}`);
5766
+ }
5767
+ /**
5768
+ * Remove a shortcut
5769
+ */
5770
+ unregister(shortcutId) {
5771
+ this.shortcuts.delete(shortcutId);
5772
+ this.overrides.delete(shortcutId);
5773
+ console.log(`🗑️ [KeyboardShortcut] Removed shortcut: ${shortcutId}`);
5774
+ }
5775
+ /**
5776
+ * Remove override for a shortcut (restore original key combination)
5777
+ */
5778
+ removeOverride(shortcutId) {
5779
+ this.overrides.delete(shortcutId);
5780
+ console.log(`🔄 [KeyboardShortcut] Override removed for: ${shortcutId}`);
5781
+ }
5782
+ /**
5783
+ * Get all registered shortcuts
5784
+ */
5785
+ getAllShortcuts() {
5786
+ return Array.from(this.shortcuts.values());
5787
+ }
5788
+ /**
5789
+ * Get shortcuts by category or filter
5790
+ */
5791
+ getShortcuts(filter) {
5792
+ const shortcuts = this.getAllShortcuts();
5793
+ return filter ? shortcuts.filter(filter) : shortcuts;
5794
+ }
5795
+ /**
5796
+ * Check if a shortcut is registered
5797
+ */
5798
+ hasShortcut(shortcutId) {
5799
+ return this.shortcuts.has(shortcutId);
5800
+ }
5801
+ /**
5802
+ * Get shortcut information
5803
+ */
5804
+ getShortcut(shortcutId) {
5805
+ return this.shortcuts.get(shortcutId);
5806
+ }
5807
+ /**
5808
+ * Clear all shortcuts
5809
+ */
5810
+ clearAll() {
5811
+ this.shortcuts.clear();
5812
+ this.overrides.clear();
5813
+ console.log(`🧹 [KeyboardShortcut] All shortcuts cleared`);
5814
+ }
5815
+ /**
5816
+ * Set up global keyboard listener
5817
+ */
5818
+ setupGlobalListener() {
5819
+ this.keydownListener = (event) => {
5820
+ this.handleKeydown(event);
5821
+ };
5822
+ document.addEventListener('keydown', this.keydownListener);
5823
+ console.log(`🎧 [KeyboardShortcut] Global keyboard listener attached`);
5824
+ }
5825
+ /**
5826
+ * Remove global keyboard listener
5827
+ */
5828
+ removeGlobalListener() {
5829
+ if (this.keydownListener) {
5830
+ document.removeEventListener('keydown', this.keydownListener);
5831
+ this.keydownListener = undefined;
5832
+ console.log(`🎧 [KeyboardShortcut] Global keyboard listener removed`);
5833
+ }
5834
+ }
5835
+ /**
5836
+ * Handle keydown events
5837
+ */
5838
+ handleKeydown(event) {
5839
+ for (const [shortcutId, shortcut] of this.shortcuts) {
5840
+ if (this.matchesShortcut(event, shortcut)) {
5841
+ // Check for override
5842
+ const override = this.overrides.get(shortcutId);
5843
+ if (override && !this.matchesOverride(event, override)) {
5844
+ continue; // Skip if override doesn't match
5845
+ }
5846
+ if (shortcut.preventDefault !== false) {
5847
+ event.preventDefault();
5848
+ }
5849
+ if (shortcut.stopPropagation) {
5850
+ event.stopPropagation();
5851
+ }
5852
+ console.log(`⌨️ [KeyboardShortcut] Executing shortcut: ${shortcutId}`);
5853
+ shortcut.action();
5854
+ break; // Only execute one shortcut per keydown
5855
+ }
5856
+ }
5857
+ }
5858
+ /**
5859
+ * Check if event matches shortcut
5860
+ */
5861
+ matchesShortcut(event, shortcut) {
5862
+ return event.key === shortcut.key &&
5863
+ (shortcut.ctrlKey === undefined || event.ctrlKey === shortcut.ctrlKey) &&
5864
+ (shortcut.altKey === undefined || event.altKey === shortcut.altKey) &&
5865
+ (shortcut.shiftKey === undefined || event.shiftKey === shortcut.shiftKey) &&
5866
+ (shortcut.metaKey === undefined || event.metaKey === shortcut.metaKey);
5867
+ }
5868
+ /**
5869
+ * Check if event matches override
5870
+ */
5871
+ matchesOverride(event, override) {
5872
+ return event.key === override.newKey &&
5873
+ (override.newCtrlKey === undefined || event.ctrlKey === override.newCtrlKey) &&
5874
+ (override.newAltKey === undefined || event.altKey === override.newAltKey) &&
5875
+ (override.newShiftKey === undefined || event.shiftKey === override.newShiftKey) &&
5876
+ (override.newMetaKey === undefined || event.metaKey === override.newMetaKey);
5877
+ }
5878
+ /**
5879
+ * Get human-readable key description
5880
+ */
5881
+ getKeyDescription(shortcut) {
5882
+ const modifiers = [];
5883
+ if (shortcut.ctrlKey)
5884
+ modifiers.push('Ctrl');
5885
+ if (shortcut.altKey)
5886
+ modifiers.push('Alt');
5887
+ if (shortcut.shiftKey)
5888
+ modifiers.push('Shift');
5889
+ if (shortcut.metaKey)
5890
+ modifiers.push('Meta');
5891
+ return [...modifiers, shortcut.key].join(' + ');
5892
+ }
5893
+ /**
5894
+ * Get key description for a shortcut ID
5895
+ */
5896
+ getKeyDescriptionForShortcut(shortcutId) {
5897
+ const shortcut = this.shortcuts.get(shortcutId);
5898
+ if (!shortcut)
5899
+ return 'Not found';
5900
+ const override = this.overrides.get(shortcutId);
5901
+ if (override) {
5902
+ return this.getKeyDescription({
5903
+ key: override.newKey,
5904
+ ctrlKey: override.newCtrlKey,
5905
+ altKey: override.newAltKey,
5906
+ shiftKey: override.newShiftKey,
5907
+ metaKey: override.newMetaKey
5908
+ });
5909
+ }
5910
+ return this.getKeyDescription(shortcut);
5911
+ }
5912
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: KeyboardShortcutService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5913
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: KeyboardShortcutService, providedIn: 'root' });
5914
+ }
5915
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: KeyboardShortcutService, decorators: [{
5916
+ type: Injectable,
5917
+ args: [{
5918
+ providedIn: 'root'
5919
+ }]
5920
+ }], ctorParameters: () => [] });
5921
+
5922
+ class FloatingContainerShortcutsService {
5923
+ keyboardShortcutService = inject(KeyboardShortcutService);
5924
+ containerService = inject(CideEleFloatingContainerService);
5925
+ // Z-index layers for different container states
5926
+ Z_INDEX_LAYERS = {
5927
+ HIDDEN: 100, // Hidden containers (behind everything)
5928
+ BACKGROUND: 1000, // Background containers
5929
+ NORMAL: 2000, // Normal visible containers
5930
+ FOCUSED: 3000, // Focused containers
5931
+ MODAL: 4000, // Modal containers
5932
+ TOOLTIP: 5000 // Tooltips and overlays
5933
+ };
5934
+ constructor() {
5935
+ this.registerDefaultShortcuts();
5936
+ }
5937
+ /**
5938
+ * Register default floating container shortcuts using custom key combinations
5939
+ */
5940
+ registerDefaultShortcuts() {
5941
+ // C + 1: Focus on first container
5942
+ this.keyboardShortcutService.register({
5943
+ id: 'floating-container-focus-first',
5944
+ key: '1',
5945
+ ctrlKey: true,
5946
+ description: 'Focus on first floating container (C+1)',
5947
+ action: () => this.focusFirstContainer(),
5948
+ preventDefault: true
5949
+ });
5950
+ // C + 2: Focus on second container
5951
+ this.keyboardShortcutService.register({
5952
+ id: 'floating-container-focus-second',
5953
+ key: '2',
5954
+ ctrlKey: true,
5955
+ description: 'Focus on second floating container (C+2)',
5956
+ action: () => this.focusContainerByIndex(1),
5957
+ preventDefault: true
5958
+ });
5959
+ // C + 3: Focus on third container
5960
+ this.keyboardShortcutService.register({
5961
+ id: 'floating-container-focus-third',
5962
+ key: '3',
5963
+ ctrlKey: true,
5964
+ description: 'Focus on third floating container (C+3)',
5965
+ action: () => this.focusContainerByIndex(2),
5966
+ preventDefault: true
5967
+ });
5968
+ // C + 4: Focus on fourth container
5969
+ this.keyboardShortcutService.register({
5970
+ id: 'floating-container-focus-fourth',
5971
+ key: '4',
5972
+ ctrlKey: true,
5973
+ description: 'Focus on fourth floating container (C+4)',
5974
+ action: () => this.focusContainerByIndex(3),
5975
+ preventDefault: true
5976
+ });
5977
+ // C + 5: Focus on fifth container
5978
+ this.keyboardShortcutService.register({
5979
+ id: 'floating-container-focus-fifth',
5980
+ key: '5',
5981
+ ctrlKey: true,
5982
+ description: 'Focus on fifth floating container (C+5)',
5983
+ action: () => this.focusContainerByIndex(4),
5984
+ preventDefault: true
5985
+ });
5986
+ // C + N: Cycle to next container
5987
+ this.keyboardShortcutService.register({
5988
+ id: 'floating-container-cycle-forward',
5989
+ key: 'n',
5990
+ ctrlKey: true,
5991
+ description: 'Cycle forward through floating containers (C+N)',
5992
+ action: () => this.cycleToNextContainer(),
5993
+ preventDefault: true
5994
+ });
5995
+ // C + P: Cycle to previous container
5996
+ this.keyboardShortcutService.register({
5997
+ id: 'floating-container-cycle-backward',
5998
+ key: 'p',
5999
+ ctrlKey: true,
6000
+ description: 'Cycle backward through floating containers (C+P)',
6001
+ action: () => this.cycleToPreviousContainer(),
6002
+ preventDefault: true
6003
+ });
6004
+ // C + H: Hide all containers
6005
+ this.keyboardShortcutService.register({
6006
+ id: 'floating-container-hide-all',
6007
+ key: 'h',
6008
+ ctrlKey: true,
6009
+ description: 'Hide all floating containers (C+H)',
6010
+ action: () => this.hideAllContainers(),
6011
+ preventDefault: true
6012
+ });
6013
+ // C + M: Minimize all containers
6014
+ this.keyboardShortcutService.register({
6015
+ id: 'floating-container-minimize-all',
6016
+ key: 'm',
6017
+ ctrlKey: true,
6018
+ description: 'Minimize all floating containers (C+M)',
6019
+ action: () => this.minimizeAllContainers(),
6020
+ preventDefault: true
6021
+ });
6022
+ // C + O: Open file uploader
6023
+ this.keyboardShortcutService.register({
6024
+ id: 'floating-container-open-file-uploader',
6025
+ key: 'o',
6026
+ ctrlKey: true,
6027
+ description: 'Open file uploader (C+O)',
6028
+ action: () => this.openFileUploader(),
6029
+ preventDefault: true
6030
+ });
6031
+ // C + R: Open entity rights sharing
6032
+ this.keyboardShortcutService.register({
6033
+ id: 'floating-container-open-entity-rights',
6034
+ key: 'r',
6035
+ ctrlKey: true,
6036
+ description: 'Open entity rights sharing (C+R)',
6037
+ action: () => this.openEntityRightsSharing(),
6038
+ preventDefault: true
6039
+ });
6040
+ // C + S: Show all containers
6041
+ this.keyboardShortcutService.register({
6042
+ id: 'floating-container-show-all',
6043
+ key: 's',
6044
+ ctrlKey: true,
6045
+ description: 'Show all floating containers (C+S)',
6046
+ action: () => this.showAllContainers(),
6047
+ preventDefault: true
6048
+ });
6049
+ // C + D: Duplicate current container
6050
+ this.keyboardShortcutService.register({
6051
+ id: 'floating-container-duplicate',
6052
+ key: 'd',
6053
+ ctrlKey: true,
6054
+ description: 'Duplicate current container (C+D)',
6055
+ action: () => this.duplicateCurrentContainer(),
6056
+ preventDefault: true
6057
+ });
6058
+ // C + W: Close current container
6059
+ this.keyboardShortcutService.register({
6060
+ id: 'floating-container-close-current',
6061
+ key: 'w',
6062
+ ctrlKey: true,
6063
+ description: 'Close current container (C+W)',
6064
+ action: () => this.closeCurrentContainer(),
6065
+ preventDefault: true
6066
+ });
6067
+ // C + T: Toggle container visibility
6068
+ this.keyboardShortcutService.register({
6069
+ id: 'floating-container-toggle-visibility',
6070
+ key: 't',
6071
+ ctrlKey: true,
6072
+ description: 'Toggle container visibility (C+T)',
6073
+ action: () => this.toggleContainerVisibility(),
6074
+ preventDefault: true
6075
+ });
6076
+ console.log('🎯 [FloatingContainerShortcuts] Custom shortcuts registered (C+1, C+2, C+O, etc.)');
6077
+ }
6078
+ /**
6079
+ * Override a floating container shortcut
6080
+ */
6081
+ overrideShortcut(shortcutId, newKey, options) {
6082
+ this.keyboardShortcutService.override(shortcutId, newKey, options);
6083
+ }
6084
+ /**
6085
+ * Add a custom floating container shortcut
6086
+ */
6087
+ addCustomShortcut(shortcut) {
6088
+ this.keyboardShortcutService.register({
6089
+ ...shortcut,
6090
+ preventDefault: true
6091
+ });
6092
+ }
6093
+ /**
6094
+ * Remove a floating container shortcut
6095
+ */
6096
+ removeShortcut(shortcutId) {
6097
+ this.keyboardShortcutService.unregister(shortcutId);
6098
+ }
6099
+ /**
6100
+ * Get all floating container shortcuts
6101
+ */
6102
+ getShortcuts() {
6103
+ return this.keyboardShortcutService.getShortcuts(shortcut => shortcut.id.startsWith('floating-container-'));
6104
+ }
6105
+ // Action methods
6106
+ cycleToNextContainer() {
6107
+ const visibleContainers = this.containerService.visibleContainers();
6108
+ if (visibleContainers.length === 0)
6109
+ return;
6110
+ // Sort by last accessed time (most recent first)
6111
+ const sortedContainers = visibleContainers.sort((a, b) => b.lastAccessed.getTime() - a.lastAccessed.getTime());
6112
+ // Find current front container
6113
+ const currentFront = sortedContainers[0];
6114
+ const currentIndex = sortedContainers.findIndex(c => c.id === currentFront.id);
6115
+ // Get next container (wrap around)
6116
+ const nextIndex = (currentIndex + 1) % sortedContainers.length;
6117
+ const nextContainer = sortedContainers[nextIndex];
6118
+ this.containerService.bringToFront(nextContainer.id);
6119
+ console.log(`🔄 [FloatingContainerShortcuts] Cycled to container: ${nextContainer.config.title}`);
6120
+ }
6121
+ cycleToPreviousContainer() {
6122
+ const visibleContainers = this.containerService.visibleContainers();
6123
+ if (visibleContainers.length === 0)
6124
+ return;
6125
+ // Sort by last accessed time (most recent first)
6126
+ const sortedContainers = visibleContainers.sort((a, b) => b.lastAccessed.getTime() - a.lastAccessed.getTime());
6127
+ // Find current front container
6128
+ const currentFront = sortedContainers[0];
6129
+ const currentIndex = sortedContainers.findIndex(c => c.id === currentFront.id);
6130
+ // Get previous container (wrap around)
6131
+ const prevIndex = currentIndex === 0 ? sortedContainers.length - 1 : currentIndex - 1;
6132
+ const prevContainer = sortedContainers[prevIndex];
6133
+ this.containerService.bringToFront(prevContainer.id);
6134
+ console.log(`🔄 [FloatingContainerShortcuts] Cycled backwards to container: ${prevContainer.config.title}`);
6135
+ }
6136
+ hideAllContainers() {
6137
+ const visibleContainers = this.containerService.visibleContainers();
6138
+ visibleContainers.forEach(container => {
6139
+ this.containerService.setZIndex(container.id, this.Z_INDEX_LAYERS.HIDDEN);
6140
+ });
6141
+ console.log(`👁️ [FloatingContainerShortcuts] All containers moved to hidden layer (z-index: ${this.Z_INDEX_LAYERS.HIDDEN})`);
6142
+ }
6143
+ focusFirstContainer() {
6144
+ const visibleContainers = this.containerService.visibleContainers();
6145
+ if (visibleContainers.length === 0)
6146
+ return;
6147
+ const firstContainer = visibleContainers[0];
6148
+ this.containerService.bringToFront(firstContainer.id);
6149
+ console.log(`🎯 [FloatingContainerShortcuts] Focused on first container: ${firstContainer.config.title}`);
6150
+ }
6151
+ minimizeAllContainers() {
6152
+ this.containerService.minimizeAll();
6153
+ console.log(`📦 [FloatingContainerShortcuts] All containers minimized`);
6154
+ }
6155
+ focusContainerByIndex(index) {
6156
+ const visibleContainers = this.containerService.visibleContainers();
6157
+ if (visibleContainers.length === 0 || index >= visibleContainers.length) {
6158
+ console.log(`⚠️ [FloatingContainerShortcuts] No container at index ${index}`);
6159
+ return;
6160
+ }
6161
+ const container = visibleContainers[index];
6162
+ this.containerService.bringToFront(container.id);
6163
+ console.log(`🎯 [FloatingContainerShortcuts] Focused on container ${index + 1}: ${container.config.title}`);
6164
+ }
6165
+ openFileUploader() {
6166
+ console.log(`📁 [FloatingContainerShortcuts] Opening file uploader...`);
6167
+ // This would need to be implemented based on your file uploader service
6168
+ // Example: this.fileUploaderService.show();
6169
+ }
6170
+ openEntityRightsSharing() {
6171
+ console.log(`🔐 [FloatingContainerShortcuts] Opening entity rights sharing...`);
6172
+ // This would need to be implemented based on your entity rights service
6173
+ // Example: this.entityRightsService.show();
6174
+ }
6175
+ showAllContainers() {
6176
+ const visibleContainers = this.containerService.visibleContainers();
6177
+ visibleContainers.forEach((container, index) => {
6178
+ // Give each container a slightly different z-index to maintain order
6179
+ const zIndex = this.Z_INDEX_LAYERS.NORMAL + index;
6180
+ this.containerService.setZIndex(container.id, zIndex);
6181
+ });
6182
+ console.log(`👁️ [FloatingContainerShortcuts] All containers moved to normal layer (z-index: ${this.Z_INDEX_LAYERS.NORMAL}+)`);
6183
+ }
6184
+ duplicateCurrentContainer() {
6185
+ const visibleContainers = this.containerService.visibleContainers();
6186
+ if (visibleContainers.length === 0) {
6187
+ console.log(`⚠️ [FloatingContainerShortcuts] No containers to duplicate`);
6188
+ return;
6189
+ }
6190
+ const currentContainer = visibleContainers[0]; // Most recent container
6191
+ console.log(`📋 [FloatingContainerShortcuts] Duplicating container: ${currentContainer.config.title}`);
6192
+ // This would need to be implemented based on your container duplication logic
6193
+ }
6194
+ closeCurrentContainer() {
6195
+ const visibleContainers = this.containerService.visibleContainers();
6196
+ if (visibleContainers.length === 0) {
6197
+ console.log(`⚠️ [FloatingContainerShortcuts] No containers to close`);
6198
+ return;
6199
+ }
6200
+ const currentContainer = visibleContainers[0]; // Most recent container
6201
+ this.containerService.hide(currentContainer.id);
6202
+ console.log(`❌ [FloatingContainerShortcuts] Closed container: ${currentContainer.config.title}`);
6203
+ }
6204
+ toggleContainerVisibility() {
6205
+ const visibleContainers = this.containerService.visibleContainers();
6206
+ if (visibleContainers.length === 0) {
6207
+ console.log(`⚠️ [FloatingContainerShortcuts] No containers to toggle`);
6208
+ return;
6209
+ }
6210
+ // Toggle visibility of the most recent container using z-index
6211
+ const currentContainer = visibleContainers[0];
6212
+ const currentZIndex = currentContainer.zIndex;
6213
+ if (currentZIndex >= this.Z_INDEX_LAYERS.NORMAL) {
6214
+ // Container is visible, move to hidden layer
6215
+ this.containerService.setZIndex(currentContainer.id, this.Z_INDEX_LAYERS.HIDDEN);
6216
+ console.log(`👁️ [FloatingContainerShortcuts] Hidden container (z-index: ${this.Z_INDEX_LAYERS.HIDDEN}): ${currentContainer.config.title}`);
6217
+ }
6218
+ else {
6219
+ // Container is hidden, move to normal layer
6220
+ this.containerService.setZIndex(currentContainer.id, this.Z_INDEX_LAYERS.NORMAL);
6221
+ console.log(`👁️ [FloatingContainerShortcuts] Shown container (z-index: ${this.Z_INDEX_LAYERS.NORMAL}): ${currentContainer.config.title}`);
6222
+ }
6223
+ }
6224
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6225
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, providedIn: 'root' });
6226
+ }
6227
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, decorators: [{
6228
+ type: Injectable,
6229
+ args: [{
6230
+ providedIn: 'root'
6231
+ }]
6232
+ }], ctorParameters: () => [] });
6233
+
5635
6234
  /**
5636
6235
  <!-- Basic horizontal (left-right) layout -->
5637
6236
  <div class="panel-container">
@@ -9736,6 +10335,7 @@ class CideEleFloatingContainerComponent {
9736
10335
  closeEvent = new EventEmitter();
9737
10336
  minimizeEvent = new EventEmitter();
9738
10337
  maximizeEvent = new EventEmitter();
10338
+ clickEvent = new EventEmitter();
9739
10339
  containerRef;
9740
10340
  // State signals
9741
10341
  position = signal({ x: 100, y: 100 }, ...(ngDevMode ? [{ debugName: "position" }] : []));
@@ -9750,8 +10350,12 @@ class CideEleFloatingContainerComponent {
9750
10350
  savedPosition = { x: 100, y: 100 }; // Store position before maximizing
9751
10351
  savedHeight = ''; // Store height before maximizing
9752
10352
  ngAfterViewInit() {
9753
- // Center the container on screen
9754
- this.centerContainer();
10353
+ // Only center the container if it's at the default position (100, 100)
10354
+ // This prevents position jumping when containers are focused
10355
+ const currentPos = this.position();
10356
+ if (currentPos.x === 100 && currentPos.y === 100) {
10357
+ this.centerContainer();
10358
+ }
9755
10359
  }
9756
10360
  constructor() {
9757
10361
  // Watch for maximize state changes
@@ -9854,6 +10458,8 @@ class CideEleFloatingContainerComponent {
9854
10458
  }
9855
10459
  // Action methods
9856
10460
  onHeaderClick(event) {
10461
+ // Emit click event to bring container to front
10462
+ this.clickEvent.emit(this.computedConfig().id);
9857
10463
  // Only minimize if clicking on the header itself, not on buttons
9858
10464
  if (this.isMinimized() && !event.target.closest('button')) {
9859
10465
  this.minimize();
@@ -9862,6 +10468,14 @@ class CideEleFloatingContainerComponent {
9862
10468
  minimize() {
9863
10469
  this.minimizeEvent.emit(this.computedConfig().id);
9864
10470
  }
10471
+ bringToFront() {
10472
+ // This will be handled by the container service through the manager component
10473
+ // The manager component will call the service's bringToFront method
10474
+ console.log(`🎯 [FloatingContainer] Container '${this.computedConfig().id}' clicked - bringing to front`);
10475
+ // Preserve current position to prevent jumping
10476
+ const currentPos = this.position();
10477
+ console.log(`🎯 [FloatingContainer] Preserving position: x=${currentPos.x}, y=${currentPos.y}`);
10478
+ }
9865
10479
  toggleMaximize() {
9866
10480
  this.maximizeEvent.emit(this.computedConfig().id);
9867
10481
  }
@@ -9872,7 +10486,7 @@ class CideEleFloatingContainerComponent {
9872
10486
  return 'linear-gradient(135deg, var(--cide-theme-primary-color) 0%, var(--tw-blue-400) 100%)';
9873
10487
  }
9874
10488
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9875
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleFloatingContainerComponent, isStandalone: true, selector: "cide-ele-floating-container", inputs: { config: "config", isMinimized: "isMinimized", isMaximized: "isMaximized", isVisible: "isVisible" }, outputs: { closeEvent: "closeEvent", minimizeEvent: "minimizeEvent", maximizeEvent: "maximizeEvent" }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: `
10489
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleFloatingContainerComponent, isStandalone: true, selector: "cide-ele-floating-container", inputs: { config: "config", isMinimized: "isMinimized", isMaximized: "isMaximized", isVisible: "isVisible" }, outputs: { closeEvent: "closeEvent", minimizeEvent: "minimizeEvent", maximizeEvent: "maximizeEvent", clickEvent: "clickEvent" }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: `
9876
10490
  <div
9877
10491
  #container
9878
10492
  class="tw-fixed tw-z-50 tw-bg-gray-50 tw-bg-opacity-90 tw-backdrop-blur-sm tw-border tw-border-gray-200 tw-border-opacity-50 tw-rounded-xl tw-shadow-lg tw-transition-all tw-duration-200 tw-flex tw-flex-col"
@@ -10101,6 +10715,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
10101
10715
  type: Output
10102
10716
  }], maximizeEvent: [{
10103
10717
  type: Output
10718
+ }], clickEvent: [{
10719
+ type: Output
10104
10720
  }], containerRef: [{
10105
10721
  type: ViewChild,
10106
10722
  args: ['container']
@@ -10111,94 +10727,96 @@ class CideEleFloatingContainerManagerComponent {
10111
10727
  // Computed properties
10112
10728
  visibleContainers = computed(() => this.containerService.visibleContainers(), ...(ngDevMode ? [{ debugName: "visibleContainers" }] : []));
10113
10729
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerManagerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10114
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleFloatingContainerManagerComponent, isStandalone: true, selector: "cide-ele-floating-container-manager", ngImport: i0, template: `
10115
- @for (container of visibleContainers(); track container.id) {
10116
- <cide-ele-floating-container
10117
- [config]="containerService.getConfigSignal(container.config)"
10118
- [isMinimized]="containerService.getMinimizedSignal(container.id)"
10119
- [isMaximized]="containerService.getMaximizedSignal(container.id)"
10120
- [isVisible]="containerService.getVisibleSignal(container.id)"
10121
- [style.z-index]="container.zIndex"
10122
- (closeEvent)="containerService.onClose($event)"
10123
- (minimizeEvent)="containerService.onMinimize($event)"
10124
- (maximizeEvent)="containerService.onMaximize($event)">
10125
-
10126
- <!-- Dynamic content loading with @defer for performance -->
10127
- @defer (when container.isVisible) {
10128
- <div
10129
- cideEleFloatingDynamic
10130
- [componentId]="container.config.componentId || container.config.id"
10131
- [componentConfig]="containerService.getComponentConfig(container.config)"
10132
- [isVisible]="container.isVisible">
10133
- </div>
10134
- } @placeholder {
10135
- <div class="tw-flex tw-items-center tw-justify-center tw-p-4">
10136
- <cide-ele-spinner size="sm"></cide-ele-spinner>
10137
- <span class="tw-ml-2 tw-text-sm tw-text-gray-600">Loading component...</span>
10138
- </div>
10139
- } @error {
10140
- <div class="tw-flex tw-flex-col tw-items-center tw-justify-center tw-p-4 tw-text-center">
10141
- <cide-ele-icon class="tw-w-8 tw-h-8 tw-text-red-500 tw-mb-2">error</cide-ele-icon>
10142
- <p class="tw-text-red-600 tw-font-medium">Failed to load component</p>
10143
- <p class="tw-text-gray-500 tw-text-sm">Component "{{ container.config.componentId || container.config.id }}" is not available</p>
10144
- <button
10145
- cideEleButton
10146
- variant="outline"
10147
- size="xs"
10148
- (click)="containerService.onClose(container.id)"
10149
- class="tw-mt-2">
10150
- Close
10151
- </button>
10152
- </div>
10153
- }
10154
- </cide-ele-floating-container>
10155
- }
10156
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideEleFloatingContainerComponent, selector: "cide-ele-floating-container", inputs: ["config", "isMinimized", "isMaximized", "isVisible"], outputs: ["closeEvent", "minimizeEvent", "maximizeEvent"] }, { kind: "component", type: CideSpinnerComponent, selector: "cide-ele-spinner", inputs: ["size", "type"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton]", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }], deferBlockDependencies: [() => [Promise.resolve().then(function () { return floatingContainerDynamic_directive; }).then(m => m.CideEleFloatingContainerDynamicDirective)]] });
10730
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleFloatingContainerManagerComponent, isStandalone: true, selector: "cide-ele-floating-container-manager", ngImport: i0, template: `
10731
+ @for (container of visibleContainers(); track container.id) {
10732
+ <cide-ele-floating-container
10733
+ [config]="containerService.getConfigSignal(container.config)"
10734
+ [isMinimized]="containerService.getMinimizedSignal(container.id)"
10735
+ [isMaximized]="containerService.getMaximizedSignal(container.id)"
10736
+ [isVisible]="containerService.getVisibleSignal(container.id)"
10737
+ [style.z-index]="containerService.getZIndexSignal(container.id)()"
10738
+ (closeEvent)="containerService.onClose($event)"
10739
+ (minimizeEvent)="containerService.onMinimize($event)"
10740
+ (maximizeEvent)="containerService.onMaximize($event)"
10741
+ (clickEvent)="containerService.bringToFront($event)">
10742
+
10743
+ <!-- Dynamic content loading with @defer for performance -->
10744
+ @defer (when container.isVisible) {
10745
+ <div
10746
+ cideEleFloatingDynamic
10747
+ [componentId]="container.config.componentId || container.config.id"
10748
+ [componentConfig]="containerService.getComponentConfig(container.config)"
10749
+ [isVisible]="container.isVisible">
10750
+ </div>
10751
+ } @placeholder {
10752
+ <div class="tw-flex tw-items-center tw-justify-center tw-p-4">
10753
+ <cide-ele-spinner size="sm"></cide-ele-spinner>
10754
+ <span class="tw-ml-2 tw-text-sm tw-text-gray-600">Loading component...</span>
10755
+ </div>
10756
+ } @error {
10757
+ <div class="tw-flex tw-flex-col tw-items-center tw-justify-center tw-p-4 tw-text-center">
10758
+ <cide-ele-icon class="tw-w-8 tw-h-8 tw-text-red-500 tw-mb-2">error</cide-ele-icon>
10759
+ <p class="tw-text-red-600 tw-font-medium">Failed to load component</p>
10760
+ <p class="tw-text-gray-500 tw-text-sm">Component "{{ container.config.componentId || container.config.id }}" is not available</p>
10761
+ <button
10762
+ cideEleButton
10763
+ variant="outline"
10764
+ size="xs"
10765
+ (click)="containerService.onClose(container.id)"
10766
+ class="tw-mt-2">
10767
+ Close
10768
+ </button>
10769
+ </div>
10770
+ }
10771
+ </cide-ele-floating-container>
10772
+ }
10773
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideEleFloatingContainerComponent, selector: "cide-ele-floating-container", inputs: ["config", "isMinimized", "isMaximized", "isVisible"], outputs: ["closeEvent", "minimizeEvent", "maximizeEvent", "clickEvent"] }, { kind: "component", type: CideSpinnerComponent, selector: "cide-ele-spinner", inputs: ["size", "type"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton]", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }], deferBlockDependencies: [() => [Promise.resolve().then(function () { return floatingContainerDynamic_directive; }).then(m => m.CideEleFloatingContainerDynamicDirective)]] });
10157
10774
  }
10158
10775
  i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerManagerComponent, resolveDeferredDeps: () => [Promise.resolve().then(function () { return floatingContainerDynamic_directive; }).then(m => m.CideEleFloatingContainerDynamicDirective)], resolveMetadata: CideEleFloatingContainerDynamicDirective => ({ decorators: [{
10159
10776
  type: Component,
10160
- args: [{ selector: 'cide-ele-floating-container-manager', standalone: true, imports: [CommonModule, CideEleFloatingContainerComponent, CideEleFloatingContainerDynamicDirective, CideSpinnerComponent, CideEleButtonComponent, CideIconComponent], template: `
10161
- @for (container of visibleContainers(); track container.id) {
10162
- <cide-ele-floating-container
10163
- [config]="containerService.getConfigSignal(container.config)"
10164
- [isMinimized]="containerService.getMinimizedSignal(container.id)"
10165
- [isMaximized]="containerService.getMaximizedSignal(container.id)"
10166
- [isVisible]="containerService.getVisibleSignal(container.id)"
10167
- [style.z-index]="container.zIndex"
10168
- (closeEvent)="containerService.onClose($event)"
10169
- (minimizeEvent)="containerService.onMinimize($event)"
10170
- (maximizeEvent)="containerService.onMaximize($event)">
10171
-
10172
- <!-- Dynamic content loading with @defer for performance -->
10173
- @defer (when container.isVisible) {
10174
- <div
10175
- cideEleFloatingDynamic
10176
- [componentId]="container.config.componentId || container.config.id"
10177
- [componentConfig]="containerService.getComponentConfig(container.config)"
10178
- [isVisible]="container.isVisible">
10179
- </div>
10180
- } @placeholder {
10181
- <div class="tw-flex tw-items-center tw-justify-center tw-p-4">
10182
- <cide-ele-spinner size="sm"></cide-ele-spinner>
10183
- <span class="tw-ml-2 tw-text-sm tw-text-gray-600">Loading component...</span>
10184
- </div>
10185
- } @error {
10186
- <div class="tw-flex tw-flex-col tw-items-center tw-justify-center tw-p-4 tw-text-center">
10187
- <cide-ele-icon class="tw-w-8 tw-h-8 tw-text-red-500 tw-mb-2">error</cide-ele-icon>
10188
- <p class="tw-text-red-600 tw-font-medium">Failed to load component</p>
10189
- <p class="tw-text-gray-500 tw-text-sm">Component "{{ container.config.componentId || container.config.id }}" is not available</p>
10190
- <button
10191
- cideEleButton
10192
- variant="outline"
10193
- size="xs"
10194
- (click)="containerService.onClose(container.id)"
10195
- class="tw-mt-2">
10196
- Close
10197
- </button>
10198
- </div>
10199
- }
10200
- </cide-ele-floating-container>
10201
- }
10777
+ args: [{ selector: 'cide-ele-floating-container-manager', standalone: true, imports: [CommonModule, CideEleFloatingContainerComponent, CideEleFloatingContainerDynamicDirective, CideSpinnerComponent, CideEleButtonComponent, CideIconComponent], template: `
10778
+ @for (container of visibleContainers(); track container.id) {
10779
+ <cide-ele-floating-container
10780
+ [config]="containerService.getConfigSignal(container.config)"
10781
+ [isMinimized]="containerService.getMinimizedSignal(container.id)"
10782
+ [isMaximized]="containerService.getMaximizedSignal(container.id)"
10783
+ [isVisible]="containerService.getVisibleSignal(container.id)"
10784
+ [style.z-index]="containerService.getZIndexSignal(container.id)()"
10785
+ (closeEvent)="containerService.onClose($event)"
10786
+ (minimizeEvent)="containerService.onMinimize($event)"
10787
+ (maximizeEvent)="containerService.onMaximize($event)"
10788
+ (clickEvent)="containerService.bringToFront($event)">
10789
+
10790
+ <!-- Dynamic content loading with @defer for performance -->
10791
+ @defer (when container.isVisible) {
10792
+ <div
10793
+ cideEleFloatingDynamic
10794
+ [componentId]="container.config.componentId || container.config.id"
10795
+ [componentConfig]="containerService.getComponentConfig(container.config)"
10796
+ [isVisible]="container.isVisible">
10797
+ </div>
10798
+ } @placeholder {
10799
+ <div class="tw-flex tw-items-center tw-justify-center tw-p-4">
10800
+ <cide-ele-spinner size="sm"></cide-ele-spinner>
10801
+ <span class="tw-ml-2 tw-text-sm tw-text-gray-600">Loading component...</span>
10802
+ </div>
10803
+ } @error {
10804
+ <div class="tw-flex tw-flex-col tw-items-center tw-justify-center tw-p-4 tw-text-center">
10805
+ <cide-ele-icon class="tw-w-8 tw-h-8 tw-text-red-500 tw-mb-2">error</cide-ele-icon>
10806
+ <p class="tw-text-red-600 tw-font-medium">Failed to load component</p>
10807
+ <p class="tw-text-gray-500 tw-text-sm">Component "{{ container.config.componentId || container.config.id }}" is not available</p>
10808
+ <button
10809
+ cideEleButton
10810
+ variant="outline"
10811
+ size="xs"
10812
+ (click)="containerService.onClose(container.id)"
10813
+ class="tw-mt-2">
10814
+ Close
10815
+ </button>
10816
+ </div>
10817
+ }
10818
+ </cide-ele-floating-container>
10819
+ }
10202
10820
  ` }]
10203
10821
  }], ctorParameters: null, propDecorators: null }) });
10204
10822
 
@@ -10458,5 +11076,5 @@ var floatingContainerDynamic_directive = /*#__PURE__*/Object.freeze({
10458
11076
  * Generated bundle index. Do not edit.
10459
11077
  */
10460
11078
 
10461
- export { CideCoreFileManagerService, CideEleButtonComponent, CideEleConfirmationModalComponent, CideEleDataGridComponent, CideEleDropdownComponent, CideEleFileImageDirective, CideEleFileInputComponent, CideEleFileManagerService, CideEleFloatingContainerComponent, CideEleFloatingContainerDynamicDirective, CideEleFloatingContainerManagerComponent, CideEleFloatingContainerService, CideEleFloatingFeaturesService, CideEleFloatingFileUploaderComponent, CideEleFloatingFileUploaderService, CideEleGlobalNotificationsComponent, CideEleJsonEditorComponent, CideEleResizerDirective, CideEleSkeletonLoaderComponent, CideEleTabComponent, CideEleToastNotificationComponent, CideElementsService, CideIconComponent, CideInputComponent, CideSelectComponent, CideSelectOptionComponent, CideSpinnerComponent, CideTextareaComponent, ConfirmationService, CoreFileManagerInsertUpdatePayload, DEFAULT_GRID_CONFIG, DropdownManagerService, ICoreCyfmSave, MFileManager, NotificationService, TooltipDirective };
11079
+ export { CideCoreFileManagerService, CideEleButtonComponent, CideEleConfirmationModalComponent, CideEleDataGridComponent, CideEleDropdownComponent, CideEleFileImageDirective, CideEleFileInputComponent, CideEleFileManagerService, CideEleFloatingContainerComponent, CideEleFloatingContainerDynamicDirective, CideEleFloatingContainerManagerComponent, CideEleFloatingContainerService, CideEleFloatingFeaturesService, CideEleFloatingFileUploaderComponent, CideEleFloatingFileUploaderService, CideEleGlobalNotificationsComponent, CideEleJsonEditorComponent, CideEleResizerDirective, CideEleSkeletonLoaderComponent, CideEleTabComponent, CideEleToastNotificationComponent, CideElementsService, CideIconComponent, CideInputComponent, CideSelectComponent, CideSelectOptionComponent, CideSpinnerComponent, CideTextareaComponent, ConfirmationService, CoreFileManagerInsertUpdatePayload, DEFAULT_GRID_CONFIG, DropdownManagerService, FloatingContainerShortcutsService, ICoreCyfmSave, KeyboardShortcutService, MFileManager, NotificationService, TooltipDirective };
10462
11080
  //# sourceMappingURL=cloud-ide-element.mjs.map