cloud-ide-element 1.0.113 → 1.0.115

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.
@@ -2654,16 +2654,18 @@ class CideEleFileManagerService {
2654
2654
  // Optimized computed properties for file counting by group
2655
2655
  getFileCountByGroup = computed(() => {
2656
2656
  const countMap = new Map();
2657
- // Count active uploads by group
2657
+ // Count files for each group using the same deduplication logic as getAllFilesForGroup
2658
+ this._fetchedFiles().forEach((fetchedFiles, groupId) => {
2659
+ const fileCount = this.getAllFilesForGroup(groupId).length;
2660
+ countMap.set(groupId, fileCount);
2661
+ });
2662
+ // Also count groups that have active uploads but no fetched files yet
2658
2663
  this._activeUploads().forEach((upload, fileId) => {
2659
- if (upload.groupId) {
2660
- countMap.set(upload.groupId, (countMap.get(upload.groupId) || 0) + 1);
2664
+ if (upload.groupId && !countMap.has(upload.groupId)) {
2665
+ const fileCount = this.getAllFilesForGroup(upload.groupId).length;
2666
+ countMap.set(upload.groupId, fileCount);
2661
2667
  }
2662
2668
  });
2663
- // Add fetched files by group
2664
- this._fetchedFiles().forEach((files, groupId) => {
2665
- countMap.set(groupId, (countMap.get(groupId) || 0) + files.length);
2666
- });
2667
2669
  return countMap;
2668
2670
  }, ...(ngDevMode ? [{ debugName: "getFileCountByGroup" }] : []));
2669
2671
  serviceState = computed(() => ({
@@ -3378,6 +3380,7 @@ class CideEleFileInputComponent {
3378
3380
  notificationService = inject(NotificationService);
3379
3381
  elementService = inject(CideElementsService);
3380
3382
  destroyRef = inject(DestroyRef);
3383
+ // Removed direct injection to avoid circular dependency
3381
3384
  // private readonly pendingTasks = inject(PendingTasks); // TODO: Fix PendingTasks API usage
3382
3385
  // Traditional @Input() decorators
3383
3386
  label = 'Choose file';
@@ -3731,12 +3734,22 @@ class CideEleFileInputComponent {
3731
3734
  if (existingComponentGroupId) {
3732
3735
  // Component already has its own group ID - use it
3733
3736
  console.log('🆔 [FileInput] Using existing component group ID:', existingComponentGroupId);
3737
+ // Open floating uploader with existing group ID
3738
+ if (this.showFloatingUploaderSignal()) {
3739
+ console.log('🔄 [FileInput] Opening floating uploader with existing group ID:', existingComponentGroupId);
3740
+ this.fileManagerService.triggerFloatingUploaderShow(existingComponentGroupId);
3741
+ }
3734
3742
  this.startMulti(files, existingComponentGroupId);
3735
3743
  }
3736
3744
  else if (existingUploadDataGroupId) {
3737
3745
  // Use group ID from uploadData and set it as component's group ID
3738
3746
  console.log('🆔 [FileInput] Using group ID from uploadData:', existingUploadDataGroupId);
3739
3747
  this.groupId.set(existingUploadDataGroupId);
3748
+ // Open floating uploader with group ID from uploadData
3749
+ if (this.showFloatingUploaderSignal()) {
3750
+ console.log('🔄 [FileInput] Opening floating uploader with uploadData group ID:', existingUploadDataGroupId);
3751
+ this.fileManagerService.triggerFloatingUploaderShow(existingUploadDataGroupId);
3752
+ }
3740
3753
  this.startMulti(files, existingUploadDataGroupId);
3741
3754
  }
3742
3755
  else {
@@ -3748,6 +3761,11 @@ class CideEleFileInputComponent {
3748
3761
  console.log('🆔 [FileInput] Generated new group ID just before upload:', newGroupId);
3749
3762
  // Set the group ID to this component so it can track its own files
3750
3763
  this.groupId.set(newGroupId);
3764
+ // Open floating uploader with newly generated group ID
3765
+ if (this.showFloatingUploaderSignal()) {
3766
+ console.log('🔄 [FileInput] Opening floating uploader with new group ID:', newGroupId);
3767
+ this.fileManagerService.triggerFloatingUploaderShow(newGroupId);
3768
+ }
3751
3769
  this.startMulti(files, newGroupId);
3752
3770
  },
3753
3771
  error: (error) => {
@@ -4038,13 +4056,13 @@ class CideEleFileInputComponent {
4038
4056
  }
4039
4057
  const groupId = this.groupId();
4040
4058
  if (groupId) {
4041
- console.log("groupId groupId", groupId);
4059
+ console.log(" [FileInput] Has existing group ID:", groupId);
4042
4060
  // Fetch files for the group and trigger floating uploader to show
4043
4061
  this.fileManagerService.fetchAndStoreFilesByGroupId(groupId)
4044
4062
  .pipe(takeUntilDestroyed(this.destroyRef))
4045
4063
  .subscribe({
4046
4064
  next: (files) => {
4047
- console.log('✅ [FileInput] Files fetched for floating uploader: groupId', files.length);
4065
+ console.log('✅ [FileInput] Files fetched for floating uploader:', files.length);
4048
4066
  // Trigger the floating uploader to show via service with group ID
4049
4067
  this.fileManagerService.triggerFloatingUploaderShow(groupId);
4050
4068
  },
@@ -4056,8 +4074,10 @@ class CideEleFileInputComponent {
4056
4074
  });
4057
4075
  }
4058
4076
  else {
4059
- // No group ID, just trigger show
4060
- this.fileManagerService.triggerFloatingUploaderShow();
4077
+ console.log('⚠️ [FileInput] No group ID yet - floating uploader will open when user uploads files');
4078
+ // No group ID yet - don't open floating uploader now
4079
+ // It will open automatically when user uploads files and group ID is generated
4080
+ // This prevents the "No active files" issue
4061
4081
  }
4062
4082
  }
4063
4083
  /**
@@ -4105,7 +4125,36 @@ class CideEleFileInputComponent {
4105
4125
  * Show floating uploader (alias for showUploader for template)
4106
4126
  */
4107
4127
  showFloatingUploaderDialog() {
4108
- this.showUploader();
4128
+ console.log('👁️ [FileInput] Opening floating file uploader via file manager service');
4129
+ if (!this.showFloatingUploaderSignal()) {
4130
+ console.log('⚠️ [FileInput] Floating uploader is disabled');
4131
+ return;
4132
+ }
4133
+ const groupId = this.groupId();
4134
+ if (groupId) {
4135
+ console.log("✅ [FileInput] Has existing group ID:", groupId);
4136
+ // Use the file manager service to trigger the floating uploader
4137
+ this.fileManagerService.triggerFloatingUploaderShow(groupId);
4138
+ console.log('✅ [FileInput] Floating file uploader triggered successfully');
4139
+ }
4140
+ else {
4141
+ console.log('⚠️ [FileInput] No group ID yet - generating one and opening uploader');
4142
+ // Generate a new group ID and open the uploader
4143
+ this.fileManagerService.generateObjectId().subscribe({
4144
+ next: (response) => {
4145
+ const newGroupId = response.data?.objectId;
4146
+ console.log('🆔 [FileInput] Generated new group ID for uploader:', newGroupId);
4147
+ this.groupId.set(newGroupId);
4148
+ // Use the file manager service to trigger the floating uploader
4149
+ this.fileManagerService.triggerFloatingUploaderShow(newGroupId);
4150
+ console.log('✅ [FileInput] Floating file uploader triggered successfully');
4151
+ },
4152
+ error: (error) => {
4153
+ console.error('❌ [FileInput] Failed to generate group ID for uploader:', error);
4154
+ this.notificationService.error('❌ Failed to open file uploader', { duration: 0 });
4155
+ }
4156
+ });
4157
+ }
4109
4158
  }
4110
4159
  /**
4111
4160
  * Get dynamic classes for drag and drop zone
@@ -4952,6 +5001,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
4952
5001
  ], 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"] }]
4953
5002
  }], ctorParameters: () => [] });
4954
5003
 
5004
+ var floatingFileUploader_component = /*#__PURE__*/Object.freeze({
5005
+ __proto__: null,
5006
+ CideEleFloatingFileUploaderComponent: CideEleFloatingFileUploaderComponent
5007
+ });
5008
+
4955
5009
  class CideTextareaComponent {
4956
5010
  label = '';
4957
5011
  labelHide = false;
@@ -9181,6 +9235,1124 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
9181
9235
  type: Output
9182
9236
  }] } });
9183
9237
 
9238
+ class CideEleFloatingContainerComponent {
9239
+ config = signal({
9240
+ id: '',
9241
+ title: 'Floating Container',
9242
+ icon: 'widgets',
9243
+ headerColor: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
9244
+ width: '400px',
9245
+ height: 'auto',
9246
+ minWidth: '300px',
9247
+ minHeight: '200px',
9248
+ maxWidth: '90vw',
9249
+ maxHeight: '90vh',
9250
+ resizable: true,
9251
+ draggable: true,
9252
+ closable: true,
9253
+ minimizable: true,
9254
+ maximizable: true
9255
+ }, ...(ngDevMode ? [{ debugName: "config" }] : []));
9256
+ isMinimized;
9257
+ isMaximized;
9258
+ isVisible;
9259
+ closeEvent = new EventEmitter();
9260
+ minimizeEvent = new EventEmitter();
9261
+ maximizeEvent = new EventEmitter();
9262
+ containerRef;
9263
+ // State signals
9264
+ position = signal({ x: 100, y: 100 }, ...(ngDevMode ? [{ debugName: "position" }] : []));
9265
+ isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : []));
9266
+ isResizing = signal(false, ...(ngDevMode ? [{ debugName: "isResizing" }] : []));
9267
+ // Computed properties
9268
+ computedConfig = computed(() => this.config(), ...(ngDevMode ? [{ debugName: "computedConfig" }] : []));
9269
+ dragStart = { x: 0, y: 0 };
9270
+ resizeStart = { x: 0, y: 0, width: 0, height: 0 };
9271
+ originalPosition = { x: 0, y: 0 };
9272
+ originalSize = { width: 0, height: 0 };
9273
+ savedPosition = { x: 100, y: 100 }; // Store position before maximizing
9274
+ savedHeight = ''; // Store height before maximizing
9275
+ ngAfterViewInit() {
9276
+ // Center the container on screen
9277
+ this.centerContainer();
9278
+ }
9279
+ constructor() {
9280
+ // Watch for maximize state changes
9281
+ effect(() => {
9282
+ const isMaximized = this.isMaximized();
9283
+ if (isMaximized && !this.savedHeight) {
9284
+ // Save current height when maximizing
9285
+ this.savedHeight = this.containerRef?.nativeElement?.style.height || this.config().height || '500px';
9286
+ }
9287
+ else if (!isMaximized && this.savedHeight) {
9288
+ // Restore height when unmaximizing
9289
+ this.savedHeight = '';
9290
+ }
9291
+ });
9292
+ }
9293
+ ngOnDestroy() {
9294
+ // Clean up any event listeners if needed
9295
+ }
9296
+ centerContainer() {
9297
+ if (this.containerRef?.nativeElement) {
9298
+ if (this.isMaximized()) {
9299
+ // For maximized state, position with equal margins (20px from all sides)
9300
+ this.position.set({ x: 20, y: 20 });
9301
+ }
9302
+ else {
9303
+ // For normal state, center based on container size
9304
+ const rect = this.containerRef.nativeElement.getBoundingClientRect();
9305
+ const centerX = (window.innerWidth - rect.width) / 2;
9306
+ const centerY = (window.innerHeight - rect.height) / 2;
9307
+ this.position.set({ x: Math.max(0, centerX), y: Math.max(0, centerY) });
9308
+ }
9309
+ }
9310
+ }
9311
+ startDrag(event) {
9312
+ if (!this.computedConfig().draggable)
9313
+ return;
9314
+ event.preventDefault();
9315
+ event.stopPropagation();
9316
+ this.isDragging.set(true);
9317
+ this.dragStart = { x: event.clientX, y: event.clientY };
9318
+ this.originalPosition = { ...this.position() };
9319
+ document.addEventListener('mousemove', this.onDragMove.bind(this));
9320
+ document.addEventListener('mouseup', this.onDragEnd.bind(this));
9321
+ }
9322
+ onDragMove(event) {
9323
+ if (!this.isDragging())
9324
+ return;
9325
+ const deltaX = event.clientX - this.dragStart.x;
9326
+ const deltaY = event.clientY - this.dragStart.y;
9327
+ const newX = Math.max(0, Math.min(window.innerWidth - 300, this.originalPosition.x + deltaX));
9328
+ const newY = Math.max(0, Math.min(window.innerHeight - 100, this.originalPosition.y + deltaY));
9329
+ this.position.set({ x: newX, y: newY });
9330
+ }
9331
+ onDragEnd() {
9332
+ this.isDragging.set(false);
9333
+ document.removeEventListener('mousemove', this.onDragMove.bind(this));
9334
+ document.removeEventListener('mouseup', this.onDragEnd.bind(this));
9335
+ }
9336
+ startResize(event) {
9337
+ if (!this.computedConfig().resizable)
9338
+ return;
9339
+ event.preventDefault();
9340
+ event.stopPropagation();
9341
+ this.isResizing.set(true);
9342
+ this.resizeStart = {
9343
+ x: event.clientX,
9344
+ y: event.clientY,
9345
+ width: this.containerRef.nativeElement.offsetWidth,
9346
+ height: this.containerRef.nativeElement.offsetHeight
9347
+ };
9348
+ this.originalSize = { ...this.resizeStart };
9349
+ document.addEventListener('mousemove', this.onResizeMove.bind(this));
9350
+ document.addEventListener('mouseup', this.onResizeEnd.bind(this));
9351
+ }
9352
+ onResizeMove(event) {
9353
+ if (!this.isResizing())
9354
+ return;
9355
+ const deltaX = event.clientX - this.resizeStart.x;
9356
+ const deltaY = event.clientY - this.resizeStart.y;
9357
+ const newWidth = Math.max(300, this.originalSize.width + deltaX);
9358
+ const newHeight = Math.max(200, this.originalSize.height + deltaY);
9359
+ this.containerRef.nativeElement.style.width = `${newWidth}px`;
9360
+ this.containerRef.nativeElement.style.height = `${newHeight}px`;
9361
+ }
9362
+ onResizeEnd() {
9363
+ this.isResizing.set(false);
9364
+ document.removeEventListener('mousemove', this.onResizeMove.bind(this));
9365
+ document.removeEventListener('mouseup', this.onResizeEnd.bind(this));
9366
+ }
9367
+ // Mouse event handlers for container
9368
+ onMouseDown(event) {
9369
+ // Prevent text selection during drag
9370
+ event.preventDefault();
9371
+ }
9372
+ onMouseMove(event) {
9373
+ // Handle any additional mouse move logic if needed
9374
+ }
9375
+ onMouseUp(event) {
9376
+ // Handle any additional mouse up logic if needed
9377
+ }
9378
+ // Action methods
9379
+ onHeaderClick(event) {
9380
+ // Only minimize if clicking on the header itself, not on buttons
9381
+ if (this.isMinimized() && !event.target.closest('button')) {
9382
+ this.minimize();
9383
+ }
9384
+ }
9385
+ minimize() {
9386
+ this.minimizeEvent.emit(this.computedConfig().id);
9387
+ }
9388
+ toggleMaximize() {
9389
+ this.maximizeEvent.emit(this.computedConfig().id);
9390
+ }
9391
+ close() {
9392
+ this.closeEvent.emit(this.computedConfig().id);
9393
+ }
9394
+ getHeaderBackground() {
9395
+ return 'linear-gradient(135deg, var(--cide-theme-primary-color) 0%, var(--tw-blue-400) 100%)';
9396
+ }
9397
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9398
+ 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: `
9399
+ <div
9400
+ #container
9401
+ 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"
9402
+ [style.left.px]="isMaximized() ? 20 : position().x"
9403
+ [style.top.px]="isMaximized() ? 20 : position().y"
9404
+ [style.width]="isMaximized() ? 'calc(100vw - 40px)' : (config().width || '400px')"
9405
+ [style.height]="isMaximized() ? 'calc(100vh - 40px)' : (isMinimized() ? 'auto' : (savedHeight || config().height || '500px'))"
9406
+ [style.min-width]="config().minWidth || '300px'"
9407
+ [style.min-height]="isMinimized() ? 'auto' : (config().minHeight || '200px')"
9408
+ [style.max-width]="config().maxWidth || '90vw'"
9409
+ [style.max-height]="config().maxHeight || '90vh'"
9410
+ [class.tw-cursor-move]="isDragging()"
9411
+ [class.tw-select-none]="true"
9412
+ (mousedown)="onMouseDown($event)"
9413
+ (mousemove)="onMouseMove($event)"
9414
+ (mouseup)="onMouseUp($event)"
9415
+ (mouseleave)="onMouseUp($event)">
9416
+
9417
+ <!-- Header -->
9418
+ <div
9419
+ class="tw-flex tw-items-center tw-justify-between tw-px-3 tw-py-2 tw-border-b tw-border-gray-200 tw-border-opacity-30 tw-rounded-t-xl tw-cursor-move tw-transition-all tw-duration-200 tw-shadow-sm tw-flex-shrink-0"
9420
+ [style.background]="getHeaderBackground()"
9421
+ (mousedown)="startDrag($event)"
9422
+ (click)="onHeaderClick($event)">
9423
+
9424
+ <!-- Title Section -->
9425
+ <div class="tw-flex tw-items-center tw-space-x-2 tw-text-white">
9426
+ @if (config().icon) {
9427
+ <cide-ele-icon class="tw-w-4 tw-h-4">{{ config().icon }}</cide-ele-icon>
9428
+ }
9429
+ <h2 class="tw-text-sm tw-font-medium tw-truncate">{{ config().title }}</h2>
9430
+ @if (isMinimized()) {
9431
+ <span class="tw-text-xs tw-opacity-75">(Click to restore)</span>
9432
+ }
9433
+ </div>
9434
+
9435
+ <!-- Action Buttons -->
9436
+ <div class="tw-flex tw-items-center tw-space-x-1">
9437
+ @if (config().minimizable !== false) {
9438
+ <button
9439
+ cideEleButton
9440
+ variant="ghost"
9441
+ size="xs"
9442
+ type="button"
9443
+ (click)="minimize(); $event.stopPropagation()"
9444
+ class="tw-w-6 tw-h-6 tw-rounded-lg tw-text-white hover:tw-bg-white hover:tw-bg-opacity-20 tw-transition-all tw-duration-200"
9445
+ [title]="isMinimized() ? 'Restore' : 'Minimize'">
9446
+ <cide-ele-icon class="tw-w-3 tw-h-3">{{ isMinimized() ? 'open_in_full' : 'remove' }}</cide-ele-icon>
9447
+ </button>
9448
+ }
9449
+ @if (config().maximizable !== false) {
9450
+ <button
9451
+ cideEleButton
9452
+ variant="ghost"
9453
+ size="xs"
9454
+ type="button"
9455
+ (click)="toggleMaximize(); $event.stopPropagation()"
9456
+ class="tw-w-6 tw-h-6 tw-rounded-lg tw-text-white hover:tw-bg-white hover:tw-bg-opacity-20 tw-transition-all tw-duration-200"
9457
+ [title]="isMaximized() ? 'Restore' : 'Maximize'">
9458
+ <cide-ele-icon class="tw-w-3 tw-h-3">{{ isMaximized() ? 'fullscreen_exit' : 'fullscreen' }}</cide-ele-icon>
9459
+ </button>
9460
+ }
9461
+ @if (config().closable !== false) {
9462
+ <button
9463
+ cideEleButton
9464
+ variant="ghost"
9465
+ size="xs"
9466
+ type="button"
9467
+ (click)="close(); $event.stopPropagation()"
9468
+ class="tw-w-6 tw-h-6 tw-rounded-lg tw-text-white hover:tw-bg-white hover:tw-bg-opacity-20 tw-transition-all tw-duration-200"
9469
+ title="Close">
9470
+ <cide-ele-icon class="tw-w-3 tw-h-3">close</cide-ele-icon>
9471
+ </button>
9472
+ }
9473
+ </div>
9474
+ </div>
9475
+
9476
+ <!-- Content with @defer for performance -->
9477
+ @if (!isMinimized()) {
9478
+ <div
9479
+ class="tw-flex-1 tw-overflow-auto tw-overflow-x-hidden floating-container-content tw-bg-gray-50 tw-bg-opacity-90"
9480
+ [style.height]="isMaximized() ? 'calc(100vh - 100px)' : 'auto'"
9481
+ [style.min-height]="'200px'">
9482
+ @defer (when !isMinimized() && isVisible()) {
9483
+ <div class="tw-p-4 tw-min-h-full">
9484
+ <ng-content></ng-content>
9485
+ </div>
9486
+ } @placeholder {
9487
+ <div class="tw-flex tw-items-center tw-justify-center tw-p-4 tw-min-h-[200px]">
9488
+ <cide-ele-spinner size="sm"></cide-ele-spinner>
9489
+ <span class="tw-ml-2 tw-text-sm tw-text-gray-600">Loading content...</span>
9490
+ </div>
9491
+ }
9492
+ </div>
9493
+ }
9494
+
9495
+ <!-- Resize Handle (if resizable) -->
9496
+ @if (config().resizable !== false) {
9497
+ <div
9498
+ class="tw-absolute tw-bottom-0 tw-right-0 tw-w-3 tw-h-3 tw-cursor-se-resize tw-bg-gray-300 tw-opacity-50 hover:tw-opacity-100"
9499
+ (mousedown)="startResize($event)">
9500
+ </div>
9501
+ }
9502
+ </div>
9503
+ `, isInline: true, styles: [".tw-cursor-move{cursor:move!important}.tw-cursor-se-resize{cursor:se-resize!important}.floating-container-content{overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scrollbar-color:#cbd5e1 #f1f5f9;position:relative;flex:1;display:flex;flex-direction:column}.floating-container-content::-webkit-scrollbar{width:8px}.floating-container-content::-webkit-scrollbar-track{background:#f8fafc;border-radius:4px;margin:4px}.floating-container-content::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:4px;transition:background-color .2s ease;border:1px solid #e2e8f0}.floating-container-content::-webkit-scrollbar-thumb:hover{background:#94a3b8;border-color:#cbd5e1}.floating-container-content::-webkit-scrollbar-thumb:active{background:#64748b}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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"] }, { kind: "component", type: CideSpinnerComponent, selector: "cide-ele-spinner", inputs: ["size", "type"] }] });
9504
+ }
9505
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerComponent, decorators: [{
9506
+ type: Component,
9507
+ args: [{ selector: 'cide-ele-floating-container', standalone: true, imports: [CommonModule, CideEleButtonComponent, CideIconComponent, CideSpinnerComponent], template: `
9508
+ <div
9509
+ #container
9510
+ 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"
9511
+ [style.left.px]="isMaximized() ? 20 : position().x"
9512
+ [style.top.px]="isMaximized() ? 20 : position().y"
9513
+ [style.width]="isMaximized() ? 'calc(100vw - 40px)' : (config().width || '400px')"
9514
+ [style.height]="isMaximized() ? 'calc(100vh - 40px)' : (isMinimized() ? 'auto' : (savedHeight || config().height || '500px'))"
9515
+ [style.min-width]="config().minWidth || '300px'"
9516
+ [style.min-height]="isMinimized() ? 'auto' : (config().minHeight || '200px')"
9517
+ [style.max-width]="config().maxWidth || '90vw'"
9518
+ [style.max-height]="config().maxHeight || '90vh'"
9519
+ [class.tw-cursor-move]="isDragging()"
9520
+ [class.tw-select-none]="true"
9521
+ (mousedown)="onMouseDown($event)"
9522
+ (mousemove)="onMouseMove($event)"
9523
+ (mouseup)="onMouseUp($event)"
9524
+ (mouseleave)="onMouseUp($event)">
9525
+
9526
+ <!-- Header -->
9527
+ <div
9528
+ class="tw-flex tw-items-center tw-justify-between tw-px-3 tw-py-2 tw-border-b tw-border-gray-200 tw-border-opacity-30 tw-rounded-t-xl tw-cursor-move tw-transition-all tw-duration-200 tw-shadow-sm tw-flex-shrink-0"
9529
+ [style.background]="getHeaderBackground()"
9530
+ (mousedown)="startDrag($event)"
9531
+ (click)="onHeaderClick($event)">
9532
+
9533
+ <!-- Title Section -->
9534
+ <div class="tw-flex tw-items-center tw-space-x-2 tw-text-white">
9535
+ @if (config().icon) {
9536
+ <cide-ele-icon class="tw-w-4 tw-h-4">{{ config().icon }}</cide-ele-icon>
9537
+ }
9538
+ <h2 class="tw-text-sm tw-font-medium tw-truncate">{{ config().title }}</h2>
9539
+ @if (isMinimized()) {
9540
+ <span class="tw-text-xs tw-opacity-75">(Click to restore)</span>
9541
+ }
9542
+ </div>
9543
+
9544
+ <!-- Action Buttons -->
9545
+ <div class="tw-flex tw-items-center tw-space-x-1">
9546
+ @if (config().minimizable !== false) {
9547
+ <button
9548
+ cideEleButton
9549
+ variant="ghost"
9550
+ size="xs"
9551
+ type="button"
9552
+ (click)="minimize(); $event.stopPropagation()"
9553
+ class="tw-w-6 tw-h-6 tw-rounded-lg tw-text-white hover:tw-bg-white hover:tw-bg-opacity-20 tw-transition-all tw-duration-200"
9554
+ [title]="isMinimized() ? 'Restore' : 'Minimize'">
9555
+ <cide-ele-icon class="tw-w-3 tw-h-3">{{ isMinimized() ? 'open_in_full' : 'remove' }}</cide-ele-icon>
9556
+ </button>
9557
+ }
9558
+ @if (config().maximizable !== false) {
9559
+ <button
9560
+ cideEleButton
9561
+ variant="ghost"
9562
+ size="xs"
9563
+ type="button"
9564
+ (click)="toggleMaximize(); $event.stopPropagation()"
9565
+ class="tw-w-6 tw-h-6 tw-rounded-lg tw-text-white hover:tw-bg-white hover:tw-bg-opacity-20 tw-transition-all tw-duration-200"
9566
+ [title]="isMaximized() ? 'Restore' : 'Maximize'">
9567
+ <cide-ele-icon class="tw-w-3 tw-h-3">{{ isMaximized() ? 'fullscreen_exit' : 'fullscreen' }}</cide-ele-icon>
9568
+ </button>
9569
+ }
9570
+ @if (config().closable !== false) {
9571
+ <button
9572
+ cideEleButton
9573
+ variant="ghost"
9574
+ size="xs"
9575
+ type="button"
9576
+ (click)="close(); $event.stopPropagation()"
9577
+ class="tw-w-6 tw-h-6 tw-rounded-lg tw-text-white hover:tw-bg-white hover:tw-bg-opacity-20 tw-transition-all tw-duration-200"
9578
+ title="Close">
9579
+ <cide-ele-icon class="tw-w-3 tw-h-3">close</cide-ele-icon>
9580
+ </button>
9581
+ }
9582
+ </div>
9583
+ </div>
9584
+
9585
+ <!-- Content with @defer for performance -->
9586
+ @if (!isMinimized()) {
9587
+ <div
9588
+ class="tw-flex-1 tw-overflow-auto tw-overflow-x-hidden floating-container-content tw-bg-gray-50 tw-bg-opacity-90"
9589
+ [style.height]="isMaximized() ? 'calc(100vh - 100px)' : 'auto'"
9590
+ [style.min-height]="'200px'">
9591
+ @defer (when !isMinimized() && isVisible()) {
9592
+ <div class="tw-p-4 tw-min-h-full">
9593
+ <ng-content></ng-content>
9594
+ </div>
9595
+ } @placeholder {
9596
+ <div class="tw-flex tw-items-center tw-justify-center tw-p-4 tw-min-h-[200px]">
9597
+ <cide-ele-spinner size="sm"></cide-ele-spinner>
9598
+ <span class="tw-ml-2 tw-text-sm tw-text-gray-600">Loading content...</span>
9599
+ </div>
9600
+ }
9601
+ </div>
9602
+ }
9603
+
9604
+ <!-- Resize Handle (if resizable) -->
9605
+ @if (config().resizable !== false) {
9606
+ <div
9607
+ class="tw-absolute tw-bottom-0 tw-right-0 tw-w-3 tw-h-3 tw-cursor-se-resize tw-bg-gray-300 tw-opacity-50 hover:tw-opacity-100"
9608
+ (mousedown)="startResize($event)">
9609
+ </div>
9610
+ }
9611
+ </div>
9612
+ `, styles: [".tw-cursor-move{cursor:move!important}.tw-cursor-se-resize{cursor:se-resize!important}.floating-container-content{overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scrollbar-color:#cbd5e1 #f1f5f9;position:relative;flex:1;display:flex;flex-direction:column}.floating-container-content::-webkit-scrollbar{width:8px}.floating-container-content::-webkit-scrollbar-track{background:#f8fafc;border-radius:4px;margin:4px}.floating-container-content::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:4px;transition:background-color .2s ease;border:1px solid #e2e8f0}.floating-container-content::-webkit-scrollbar-thumb:hover{background:#94a3b8;border-color:#cbd5e1}.floating-container-content::-webkit-scrollbar-thumb:active{background:#64748b}\n"] }]
9613
+ }], ctorParameters: () => [], propDecorators: { config: [{
9614
+ type: Input
9615
+ }], isMinimized: [{
9616
+ type: Input
9617
+ }], isMaximized: [{
9618
+ type: Input
9619
+ }], isVisible: [{
9620
+ type: Input
9621
+ }], closeEvent: [{
9622
+ type: Output
9623
+ }], minimizeEvent: [{
9624
+ type: Output
9625
+ }], maximizeEvent: [{
9626
+ type: Output
9627
+ }], containerRef: [{
9628
+ type: ViewChild,
9629
+ args: ['container']
9630
+ }] } });
9631
+
9632
+ class CideEleFloatingContainerService {
9633
+ injector;
9634
+ containers = signal(new Map(), ...(ngDevMode ? [{ debugName: "containers" }] : []));
9635
+ nextZIndex = signal(1000, ...(ngDevMode ? [{ debugName: "nextZIndex" }] : []));
9636
+ instanceCounter = signal(0, ...(ngDevMode ? [{ debugName: "instanceCounter" }] : []));
9637
+ // Dynamic component management
9638
+ componentRegistry = new Map();
9639
+ activeComponents = new Map();
9640
+ constructor(injector) {
9641
+ this.injector = injector;
9642
+ }
9643
+ // Computed properties
9644
+ visibleContainers = computed(() => Array.from(this.containers().values()).filter(container => container.isVisible), ...(ngDevMode ? [{ debugName: "visibleContainers" }] : []));
9645
+ minimizedContainers = computed(() => Array.from(this.containers().values()).filter(container => container.isMinimized), ...(ngDevMode ? [{ debugName: "minimizedContainers" }] : []));
9646
+ maximizedContainers = computed(() => Array.from(this.containers().values()).filter(container => container.isMaximized), ...(ngDevMode ? [{ debugName: "maximizedContainers" }] : []));
9647
+ // Container management methods
9648
+ show(config) {
9649
+ const containerId = config.id || this.generateId();
9650
+ const instanceId = this.generateInstanceId(config.componentId || 'default');
9651
+ const zIndex = this.nextZIndex();
9652
+ const now = new Date();
9653
+ const container = {
9654
+ id: containerId,
9655
+ config: { ...config, id: containerId },
9656
+ isVisible: true,
9657
+ isMinimized: false,
9658
+ isMaximized: false,
9659
+ zIndex,
9660
+ instanceId,
9661
+ componentType: config.componentId || 'default',
9662
+ createdAt: now,
9663
+ lastAccessed: now
9664
+ };
9665
+ this.containers.update(containers => {
9666
+ const newContainers = new Map(containers);
9667
+ newContainers.set(containerId, container);
9668
+ return newContainers;
9669
+ });
9670
+ this.nextZIndex.update(z => z + 1);
9671
+ return containerId;
9672
+ }
9673
+ hide(containerId) {
9674
+ this.containers.update(containers => {
9675
+ const newContainers = new Map(containers);
9676
+ const container = newContainers.get(containerId);
9677
+ if (container) {
9678
+ container.isVisible = false;
9679
+ newContainers.set(containerId, container);
9680
+ }
9681
+ return newContainers;
9682
+ });
9683
+ }
9684
+ minimize(containerId) {
9685
+ this.containers.update(containers => {
9686
+ const newContainers = new Map(containers);
9687
+ const container = newContainers.get(containerId);
9688
+ if (container) {
9689
+ container.isMinimized = !container.isMinimized;
9690
+ newContainers.set(containerId, container);
9691
+ }
9692
+ return newContainers;
9693
+ });
9694
+ }
9695
+ maximize(containerId) {
9696
+ this.containers.update(containers => {
9697
+ const newContainers = new Map(containers);
9698
+ const container = newContainers.get(containerId);
9699
+ if (container) {
9700
+ container.isMaximized = !container.isMaximized;
9701
+ newContainers.set(containerId, container);
9702
+ }
9703
+ return newContainers;
9704
+ });
9705
+ }
9706
+ bringToFront(containerId) {
9707
+ const zIndex = this.nextZIndex();
9708
+ this.containers.update(containers => {
9709
+ const newContainers = new Map(containers);
9710
+ const container = newContainers.get(containerId);
9711
+ if (container) {
9712
+ container.zIndex = zIndex;
9713
+ newContainers.set(containerId, container);
9714
+ }
9715
+ return newContainers;
9716
+ });
9717
+ this.nextZIndex.update(z => z + 1);
9718
+ }
9719
+ getContainer(containerId) {
9720
+ return this.containers().get(containerId);
9721
+ }
9722
+ isVisible(containerId) {
9723
+ const container = this.getContainer(containerId);
9724
+ return container ? container.isVisible : false;
9725
+ }
9726
+ isMinimized(containerId) {
9727
+ const container = this.getContainer(containerId);
9728
+ return container ? container.isMinimized : false;
9729
+ }
9730
+ isMaximized(containerId) {
9731
+ const container = this.getContainer(containerId);
9732
+ return container ? container.isMaximized : false;
9733
+ }
9734
+ hideAll() {
9735
+ this.containers.update(containers => {
9736
+ const newContainers = new Map(containers);
9737
+ for (const [id, container] of newContainers) {
9738
+ container.isVisible = false;
9739
+ newContainers.set(id, container);
9740
+ }
9741
+ return newContainers;
9742
+ });
9743
+ }
9744
+ minimizeAll() {
9745
+ this.containers.update(containers => {
9746
+ const newContainers = new Map(containers);
9747
+ for (const [id, container] of newContainers) {
9748
+ if (container.isVisible) {
9749
+ container.isMinimized = true;
9750
+ newContainers.set(id, container);
9751
+ }
9752
+ }
9753
+ return newContainers;
9754
+ });
9755
+ }
9756
+ generateId() {
9757
+ return `floating-container-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
9758
+ }
9759
+ generateInstanceId(componentType) {
9760
+ const counter = this.instanceCounter() + 1;
9761
+ this.instanceCounter.update(c => c + 1);
9762
+ return `${componentType}-instance-${counter}-${Date.now()}`;
9763
+ }
9764
+ // Multiple instance management methods
9765
+ getInstancesByComponentType(componentType) {
9766
+ return Array.from(this.containers().values())
9767
+ .filter(container => container.componentType === componentType);
9768
+ }
9769
+ getActiveInstancesByComponentType(componentType) {
9770
+ return Array.from(this.containers().values())
9771
+ .filter(container => container.componentType === componentType && container.isVisible);
9772
+ }
9773
+ getInstanceCount(componentType) {
9774
+ return this.getInstancesByComponentType(componentType).length;
9775
+ }
9776
+ getActiveInstanceCount(componentType) {
9777
+ return this.getActiveInstancesByComponentType(componentType).length;
9778
+ }
9779
+ // Close all instances of a component type
9780
+ closeAllInstancesOfType(componentType) {
9781
+ const instances = this.getInstancesByComponentType(componentType);
9782
+ instances.forEach(instance => {
9783
+ this.hide(instance.id);
9784
+ });
9785
+ }
9786
+ // Minimize all instances of a component type
9787
+ minimizeAllInstancesOfType(componentType) {
9788
+ const instances = this.getActiveInstancesByComponentType(componentType);
9789
+ instances.forEach(instance => {
9790
+ this.minimize(instance.id);
9791
+ });
9792
+ }
9793
+ // Bring all instances of a component type to front
9794
+ bringAllInstancesToFront(componentType) {
9795
+ const instances = this.getActiveInstancesByComponentType(componentType);
9796
+ instances.forEach(instance => {
9797
+ this.bringToFront(instance.id);
9798
+ });
9799
+ }
9800
+ // Get instance by unique instance ID
9801
+ getInstanceByInstanceId(instanceId) {
9802
+ return Array.from(this.containers().values())
9803
+ .find(container => container.instanceId === instanceId);
9804
+ }
9805
+ // Update last accessed time
9806
+ updateLastAccessed(containerId) {
9807
+ this.containers.update(containers => {
9808
+ const newContainers = new Map(containers);
9809
+ const container = newContainers.get(containerId);
9810
+ if (container) {
9811
+ container.lastAccessed = new Date();
9812
+ newContainers.set(containerId, container);
9813
+ }
9814
+ return newContainers;
9815
+ });
9816
+ }
9817
+ // ===== DYNAMIC COMPONENT MANAGEMENT =====
9818
+ /**
9819
+ * Register a component for dynamic loading
9820
+ */
9821
+ registerComponent(componentId, componentType) {
9822
+ this.componentRegistry.set(componentId, componentType);
9823
+ }
9824
+ /**
9825
+ * Unregister a component
9826
+ */
9827
+ unregisterComponent(componentId) {
9828
+ this.componentRegistry.delete(componentId);
9829
+ }
9830
+ /**
9831
+ * Get registered component type
9832
+ */
9833
+ getComponentType(componentId) {
9834
+ return this.componentRegistry.get(componentId);
9835
+ }
9836
+ /**
9837
+ * Check if component is registered
9838
+ */
9839
+ isComponentRegistered(componentId) {
9840
+ return this.componentRegistry.has(componentId);
9841
+ }
9842
+ /**
9843
+ * Get registered component IDs
9844
+ */
9845
+ getRegisteredComponentIds() {
9846
+ return Array.from(this.componentRegistry.keys());
9847
+ }
9848
+ /**
9849
+ * Create and load component dynamically
9850
+ */
9851
+ loadComponent(componentId, viewContainer, config) {
9852
+ const componentType = this.componentRegistry.get(componentId);
9853
+ if (!componentType) {
9854
+ return null;
9855
+ }
9856
+ try {
9857
+ viewContainer.clear();
9858
+ const componentRef = viewContainer.createComponent(componentType, {
9859
+ injector: this.injector
9860
+ });
9861
+ // Set inputs if provided
9862
+ if (config?.inputs) {
9863
+ Object.keys(config.inputs).forEach(key => {
9864
+ if (componentRef.instance && typeof componentRef.instance === 'object' && key in componentRef.instance) {
9865
+ componentRef.instance[key] = config.inputs[key];
9866
+ }
9867
+ });
9868
+ }
9869
+ // Set outputs if provided
9870
+ if (config?.outputs) {
9871
+ Object.keys(config.outputs).forEach(key => {
9872
+ if (componentRef.instance && typeof componentRef.instance === 'object' && key in componentRef.instance) {
9873
+ const output = componentRef.instance[key];
9874
+ if (output && typeof output.subscribe === 'function') {
9875
+ output.subscribe(config.outputs[key]);
9876
+ }
9877
+ }
9878
+ });
9879
+ }
9880
+ this.activeComponents.set(componentId, componentRef);
9881
+ return componentRef;
9882
+ }
9883
+ catch (error) {
9884
+ return null;
9885
+ }
9886
+ }
9887
+ /**
9888
+ * Destroy component
9889
+ */
9890
+ destroyComponent(componentId) {
9891
+ const componentRef = this.activeComponents.get(componentId);
9892
+ if (componentRef) {
9893
+ componentRef.destroy();
9894
+ this.activeComponents.delete(componentId);
9895
+ }
9896
+ }
9897
+ /**
9898
+ * Get active component count
9899
+ */
9900
+ getActiveComponentCount() {
9901
+ return this.activeComponents.size;
9902
+ }
9903
+ /**
9904
+ * Clear all active components
9905
+ */
9906
+ clearActiveComponents() {
9907
+ this.activeComponents.forEach(componentRef => componentRef.destroy());
9908
+ this.activeComponents.clear();
9909
+ }
9910
+ // ===== CONTAINER MANAGER FUNCTIONALITY =====
9911
+ /**
9912
+ * Get config signal for a container
9913
+ */
9914
+ getConfigSignal(config) {
9915
+ return signal(config);
9916
+ }
9917
+ /**
9918
+ * Get minimized signal for a container
9919
+ */
9920
+ getMinimizedSignal(containerId) {
9921
+ return computed(() => {
9922
+ const container = this.getContainer(containerId);
9923
+ return container?.isMinimized || false;
9924
+ });
9925
+ }
9926
+ /**
9927
+ * Get maximized signal for a container
9928
+ */
9929
+ getMaximizedSignal(containerId) {
9930
+ return computed(() => {
9931
+ const container = this.getContainer(containerId);
9932
+ return container?.isMaximized || false;
9933
+ });
9934
+ }
9935
+ /**
9936
+ * Get visible signal for a container
9937
+ */
9938
+ getVisibleSignal(containerId) {
9939
+ return computed(() => {
9940
+ const container = this.getContainer(containerId);
9941
+ return container?.isVisible || false;
9942
+ });
9943
+ }
9944
+ /**
9945
+ * Get component config for dynamic loading
9946
+ */
9947
+ getComponentConfig(config) {
9948
+ if (config.componentConfig) {
9949
+ return {
9950
+ componentId: config.componentId || config.id,
9951
+ inputs: config.componentConfig.inputs,
9952
+ outputs: config.componentConfig.outputs
9953
+ };
9954
+ }
9955
+ return undefined;
9956
+ }
9957
+ /**
9958
+ * Handle container close event
9959
+ */
9960
+ onClose(containerId) {
9961
+ this.hide(containerId);
9962
+ }
9963
+ /**
9964
+ * Handle container minimize event
9965
+ */
9966
+ onMinimize(containerId) {
9967
+ this.minimize(containerId);
9968
+ }
9969
+ /**
9970
+ * Handle container maximize event
9971
+ */
9972
+ onMaximize(containerId) {
9973
+ this.maximize(containerId);
9974
+ }
9975
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
9976
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerService, providedIn: 'root' });
9977
+ }
9978
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerService, decorators: [{
9979
+ type: Injectable,
9980
+ args: [{
9981
+ providedIn: 'root'
9982
+ }]
9983
+ }], ctorParameters: () => [{ type: i0.Injector }] });
9984
+
9985
+ class CideEleFloatingContainerManagerComponent {
9986
+ containerService = inject(CideEleFloatingContainerService);
9987
+ // Computed properties
9988
+ visibleContainers = computed(() => this.containerService.visibleContainers(), ...(ngDevMode ? [{ debugName: "visibleContainers" }] : []));
9989
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerManagerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9990
+ 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: `
9991
+ @for (container of visibleContainers(); track container.id) {
9992
+ <cide-ele-floating-container
9993
+ [config]="containerService.getConfigSignal(container.config)"
9994
+ [isMinimized]="containerService.getMinimizedSignal(container.id)"
9995
+ [isMaximized]="containerService.getMaximizedSignal(container.id)"
9996
+ [isVisible]="containerService.getVisibleSignal(container.id)"
9997
+ [style.z-index]="container.zIndex"
9998
+ (closeEvent)="containerService.onClose($event)"
9999
+ (minimizeEvent)="containerService.onMinimize($event)"
10000
+ (maximizeEvent)="containerService.onMaximize($event)">
10001
+
10002
+ <!-- Dynamic content loading with @defer for performance -->
10003
+ @defer (when container.isVisible) {
10004
+ <div
10005
+ cideEleFloatingDynamic
10006
+ [componentId]="container.config.componentId || container.config.id"
10007
+ [componentConfig]="containerService.getComponentConfig(container.config)"
10008
+ [isVisible]="container.isVisible">
10009
+ </div>
10010
+ } @placeholder {
10011
+ <div class="tw-flex tw-items-center tw-justify-center tw-p-4">
10012
+ <cide-ele-spinner size="sm"></cide-ele-spinner>
10013
+ <span class="tw-ml-2 tw-text-sm tw-text-gray-600">Loading component...</span>
10014
+ </div>
10015
+ } @error {
10016
+ <div class="tw-flex tw-flex-col tw-items-center tw-justify-center tw-p-4 tw-text-center">
10017
+ <cide-ele-icon class="tw-w-8 tw-h-8 tw-text-red-500 tw-mb-2">error</cide-ele-icon>
10018
+ <p class="tw-text-red-600 tw-font-medium">Failed to load component</p>
10019
+ <p class="tw-text-gray-500 tw-text-sm">Component "{{ container.config.componentId || container.config.id }}" is not available</p>
10020
+ <button
10021
+ cideEleButton
10022
+ variant="outline"
10023
+ size="xs"
10024
+ (click)="containerService.onClose(container.id)"
10025
+ class="tw-mt-2">
10026
+ Close
10027
+ </button>
10028
+ </div>
10029
+ }
10030
+ </cide-ele-floating-container>
10031
+ }
10032
+ `, 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)]] });
10033
+ }
10034
+ 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: [{
10035
+ type: Component,
10036
+ args: [{ selector: 'cide-ele-floating-container-manager', standalone: true, imports: [CommonModule, CideEleFloatingContainerComponent, CideEleFloatingContainerDynamicDirective, CideSpinnerComponent, CideEleButtonComponent, CideIconComponent], template: `
10037
+ @for (container of visibleContainers(); track container.id) {
10038
+ <cide-ele-floating-container
10039
+ [config]="containerService.getConfigSignal(container.config)"
10040
+ [isMinimized]="containerService.getMinimizedSignal(container.id)"
10041
+ [isMaximized]="containerService.getMaximizedSignal(container.id)"
10042
+ [isVisible]="containerService.getVisibleSignal(container.id)"
10043
+ [style.z-index]="container.zIndex"
10044
+ (closeEvent)="containerService.onClose($event)"
10045
+ (minimizeEvent)="containerService.onMinimize($event)"
10046
+ (maximizeEvent)="containerService.onMaximize($event)">
10047
+
10048
+ <!-- Dynamic content loading with @defer for performance -->
10049
+ @defer (when container.isVisible) {
10050
+ <div
10051
+ cideEleFloatingDynamic
10052
+ [componentId]="container.config.componentId || container.config.id"
10053
+ [componentConfig]="containerService.getComponentConfig(container.config)"
10054
+ [isVisible]="container.isVisible">
10055
+ </div>
10056
+ } @placeholder {
10057
+ <div class="tw-flex tw-items-center tw-justify-center tw-p-4">
10058
+ <cide-ele-spinner size="sm"></cide-ele-spinner>
10059
+ <span class="tw-ml-2 tw-text-sm tw-text-gray-600">Loading component...</span>
10060
+ </div>
10061
+ } @error {
10062
+ <div class="tw-flex tw-flex-col tw-items-center tw-justify-center tw-p-4 tw-text-center">
10063
+ <cide-ele-icon class="tw-w-8 tw-h-8 tw-text-red-500 tw-mb-2">error</cide-ele-icon>
10064
+ <p class="tw-text-red-600 tw-font-medium">Failed to load component</p>
10065
+ <p class="tw-text-gray-500 tw-text-sm">Component "{{ container.config.componentId || container.config.id }}" is not available</p>
10066
+ <button
10067
+ cideEleButton
10068
+ variant="outline"
10069
+ size="xs"
10070
+ (click)="containerService.onClose(container.id)"
10071
+ class="tw-mt-2">
10072
+ Close
10073
+ </button>
10074
+ </div>
10075
+ }
10076
+ </cide-ele-floating-container>
10077
+ }
10078
+ ` }]
10079
+ }], ctorParameters: null, propDecorators: null }) });
10080
+
10081
+ class CideEleFloatingFeaturesService {
10082
+ containerService = inject(CideEleFloatingContainerService);
10083
+ constructor() {
10084
+ // Auto-register file uploader component on service initialization
10085
+ this.initializeFileUploader();
10086
+ // Entity rights sharing is handled by its own dedicated service
10087
+ }
10088
+ async initializeFileUploader() {
10089
+ // Check if already registered to avoid duplicate registration
10090
+ if (this.containerService.isComponentRegistered('file-uploader')) {
10091
+ console.log('✅ File uploader component already registered');
10092
+ return;
10093
+ }
10094
+ try {
10095
+ // Use relative import to avoid circular dependency
10096
+ const module = await Promise.resolve().then(function () { return floatingFileUploader_component; });
10097
+ if (module.CideEleFloatingFileUploaderComponent) {
10098
+ this.containerService.registerComponent('file-uploader', module.CideEleFloatingFileUploaderComponent);
10099
+ console.log('✅ File uploader component registered successfully');
10100
+ }
10101
+ }
10102
+ catch (error) {
10103
+ console.error('❌ Failed to register file uploader component:', error);
10104
+ }
10105
+ }
10106
+ // File Uploader
10107
+ async showFileUploader(componentType, inputData) {
10108
+ // Ensure component is registered before showing
10109
+ if (!this.containerService.isComponentRegistered('file-uploader')) {
10110
+ console.log('📝 File uploader component not registered, registering now...');
10111
+ await this.initializeFileUploader();
10112
+ }
10113
+ const config = {
10114
+ id: 'file-uploader-main',
10115
+ title: 'File Uploader',
10116
+ icon: 'cloud_upload',
10117
+ width: '500px',
10118
+ height: '400px',
10119
+ minWidth: '400px',
10120
+ minHeight: '300px',
10121
+ resizable: true,
10122
+ draggable: true,
10123
+ closable: true,
10124
+ minimizable: true,
10125
+ maximizable: true,
10126
+ componentId: 'file-uploader',
10127
+ componentConfig: inputData ? {
10128
+ inputs: inputData,
10129
+ outputs: {}
10130
+ } : undefined
10131
+ };
10132
+ // Register component if provided
10133
+ if (componentType) {
10134
+ this.registerComponent('file-uploader', componentType);
10135
+ }
10136
+ return this.containerService.show(config);
10137
+ }
10138
+ hideFileUploader() {
10139
+ this.containerService.hide('file-uploader-main');
10140
+ }
10141
+ // Show file uploader with specific container ID (for multiple instances)
10142
+ showFileUploaderInstance(containerId, componentType, config = {}) {
10143
+ const defaultConfig = {
10144
+ id: containerId,
10145
+ title: 'File Uploader',
10146
+ icon: 'cloud_upload',
10147
+ width: '500px',
10148
+ height: '400px',
10149
+ minWidth: '400px',
10150
+ minHeight: '300px',
10151
+ resizable: true,
10152
+ draggable: true,
10153
+ closable: true,
10154
+ minimizable: true,
10155
+ maximizable: true,
10156
+ componentId: 'file-uploader',
10157
+ ...config
10158
+ };
10159
+ // Register component if provided
10160
+ if (componentType) {
10161
+ this.registerComponent('file-uploader', componentType);
10162
+ }
10163
+ return this.containerService.show(defaultConfig);
10164
+ }
10165
+ // Generic method to show any floating feature
10166
+ showFeature(featureId, config) {
10167
+ return this.containerService.show({ ...config, id: featureId });
10168
+ }
10169
+ // Generic method for showing any component dynamically
10170
+ showComponent(containerId, componentId, title, componentType, config = {}) {
10171
+ const containerConfig = {
10172
+ id: containerId,
10173
+ title,
10174
+ icon: 'widgets',
10175
+ width: '400px',
10176
+ height: '500px',
10177
+ minWidth: '300px',
10178
+ minHeight: '200px',
10179
+ resizable: true,
10180
+ draggable: true,
10181
+ closable: true,
10182
+ minimizable: true,
10183
+ maximizable: true,
10184
+ componentId,
10185
+ ...config
10186
+ };
10187
+ // Register component if provided
10188
+ if (componentType) {
10189
+ this.registerComponent(componentId, componentType);
10190
+ }
10191
+ return this.containerService.show(containerConfig);
10192
+ }
10193
+ // Show multiple instances of the same component
10194
+ showMultipleInstances(componentId, titlePrefix, count, config = {}) {
10195
+ const containerIds = [];
10196
+ for (let i = 1; i <= count; i++) {
10197
+ const containerId = `${componentId}-instance-${i}-${Date.now()}`;
10198
+ const title = `${titlePrefix} ${i}`;
10199
+ const containerConfig = {
10200
+ id: containerId,
10201
+ title,
10202
+ icon: 'widgets',
10203
+ width: '400px',
10204
+ height: '500px',
10205
+ minWidth: '300px',
10206
+ minHeight: '200px',
10207
+ resizable: true,
10208
+ draggable: true,
10209
+ closable: true,
10210
+ minimizable: true,
10211
+ maximizable: true,
10212
+ componentId,
10213
+ ...config
10214
+ };
10215
+ const id = this.containerService.show(containerConfig);
10216
+ containerIds.push(id);
10217
+ }
10218
+ return containerIds;
10219
+ }
10220
+ // Get all instances of a component type
10221
+ getInstancesOfType(componentType) {
10222
+ return this.containerService.getInstancesByComponentType(componentType);
10223
+ }
10224
+ // Get active instances of a component type
10225
+ getActiveInstancesOfType(componentType) {
10226
+ return this.containerService.getActiveInstancesByComponentType(componentType);
10227
+ }
10228
+ // Close all instances of a component type
10229
+ closeAllInstancesOfType(componentType) {
10230
+ this.containerService.closeAllInstancesOfType(componentType);
10231
+ }
10232
+ // Minimize all instances of a component type
10233
+ minimizeAllInstancesOfType(componentType) {
10234
+ this.containerService.minimizeAllInstancesOfType(componentType);
10235
+ }
10236
+ // Get instance count for a component type
10237
+ getInstanceCount(componentType) {
10238
+ return this.containerService.getInstanceCount(componentType);
10239
+ }
10240
+ // Get active instance count for a component type
10241
+ getActiveInstanceCount(componentType) {
10242
+ return this.containerService.getActiveInstanceCount(componentType);
10243
+ }
10244
+ // Register a component for dynamic loading
10245
+ registerComponent(componentId, componentType) {
10246
+ this.containerService.registerComponent(componentId, componentType);
10247
+ }
10248
+ // Unregister a component
10249
+ unregisterComponent(componentId) {
10250
+ this.containerService.unregisterComponent(componentId);
10251
+ }
10252
+ hideFeature(featureId) {
10253
+ this.containerService.hide(featureId);
10254
+ }
10255
+ // Utility methods
10256
+ bringToFront(featureId) {
10257
+ this.containerService.bringToFront(featureId);
10258
+ }
10259
+ minimize(featureId) {
10260
+ this.containerService.minimize(featureId);
10261
+ }
10262
+ maximize(featureId) {
10263
+ this.containerService.maximize(featureId);
10264
+ }
10265
+ isVisible(featureId) {
10266
+ return this.containerService.isVisible(featureId);
10267
+ }
10268
+ hideAll() {
10269
+ this.containerService.hideAll();
10270
+ }
10271
+ minimizeAll() {
10272
+ this.containerService.minimizeAll();
10273
+ }
10274
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingFeaturesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
10275
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingFeaturesService, providedIn: 'root' });
10276
+ }
10277
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingFeaturesService, decorators: [{
10278
+ type: Injectable,
10279
+ args: [{
10280
+ providedIn: 'root'
10281
+ }]
10282
+ }], ctorParameters: () => [] });
10283
+
10284
+ class CideEleFloatingContainerDynamicDirective {
10285
+ viewContainer;
10286
+ containerService;
10287
+ componentId;
10288
+ componentConfig;
10289
+ isVisible = true;
10290
+ componentRef = null;
10291
+ constructor(viewContainer, containerService) {
10292
+ this.viewContainer = viewContainer;
10293
+ this.containerService = containerService;
10294
+ }
10295
+ ngOnInit() {
10296
+ if (this.isVisible && this.componentId) {
10297
+ this.loadComponent();
10298
+ }
10299
+ }
10300
+ ngOnDestroy() {
10301
+ this.destroyComponent();
10302
+ }
10303
+ ngOnChanges() {
10304
+ if (this.isVisible && this.componentId && !this.componentRef) {
10305
+ this.loadComponent();
10306
+ }
10307
+ else if (!this.isVisible && this.componentRef) {
10308
+ this.destroyComponent();
10309
+ }
10310
+ }
10311
+ loadComponent() {
10312
+ if (this.componentId && this.containerService.isComponentRegistered(this.componentId)) {
10313
+ this.componentRef = this.containerService.loadComponent(this.componentId, this.viewContainer, this.componentConfig);
10314
+ }
10315
+ else {
10316
+ console.warn(`Component '${this.componentId}' is not registered. Available components:`, this.containerService.getRegisteredComponentIds());
10317
+ // Retry after a short delay in case registration is still in progress
10318
+ setTimeout(() => {
10319
+ if (this.containerService.isComponentRegistered(this.componentId)) {
10320
+ this.componentRef = this.containerService.loadComponent(this.componentId, this.viewContainer, this.componentConfig);
10321
+ }
10322
+ else {
10323
+ console.error(`Component '${this.componentId}' still not registered after retry`);
10324
+ }
10325
+ }, 100);
10326
+ }
10327
+ }
10328
+ destroyComponent() {
10329
+ if (this.componentRef) {
10330
+ this.componentRef.destroy();
10331
+ this.componentRef = null;
10332
+ }
10333
+ }
10334
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerDynamicDirective, deps: [{ token: i0.ViewContainerRef }, { token: CideEleFloatingContainerService }], target: i0.ɵɵFactoryTarget.Directive });
10335
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.7", type: CideEleFloatingContainerDynamicDirective, isStandalone: true, selector: "[cideEleFloatingDynamic]", inputs: { componentId: "componentId", componentConfig: "componentConfig", isVisible: "isVisible" }, usesOnChanges: true, ngImport: i0 });
10336
+ }
10337
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerDynamicDirective, decorators: [{
10338
+ type: Directive,
10339
+ args: [{
10340
+ selector: '[cideEleFloatingDynamic]',
10341
+ standalone: true
10342
+ }]
10343
+ }], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: CideEleFloatingContainerService }], propDecorators: { componentId: [{
10344
+ type: Input
10345
+ }], componentConfig: [{
10346
+ type: Input
10347
+ }], isVisible: [{
10348
+ type: Input
10349
+ }] } });
10350
+
10351
+ var floatingContainerDynamic_directive = /*#__PURE__*/Object.freeze({
10352
+ __proto__: null,
10353
+ CideEleFloatingContainerDynamicDirective: CideEleFloatingContainerDynamicDirective
10354
+ });
10355
+
9184
10356
  /*
9185
10357
  * Public API Surface of cloud-ide-element
9186
10358
  * Here we can add what need to be exported from library
@@ -9190,5 +10362,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
9190
10362
  * Generated bundle index. Do not edit.
9191
10363
  */
9192
10364
 
9193
- export { CideCoreFileManagerService, CideEleButtonComponent, CideEleConfirmationModalComponent, CideEleDataGridComponent, CideEleDropdownComponent, CideEleFileImageDirective, CideEleFileInputComponent, CideEleFileManagerService, CideEleFloatingFileUploaderComponent, CideEleGlobalNotificationsComponent, CideEleJsonEditorComponent, CideEleResizerDirective, CideEleSkeletonLoaderComponent, CideEleTabComponent, CideEleToastNotificationComponent, CideElementsService, CideIconComponent, CideInputComponent, CideSelectComponent, CideSelectOptionComponent, CideSpinnerComponent, CideTextareaComponent, ConfirmationService, CoreFileManagerInsertUpdatePayload, DEFAULT_GRID_CONFIG, DropdownManagerService, ICoreCyfmSave, MFileManager, NotificationService, TooltipDirective };
10365
+ export { CideCoreFileManagerService, CideEleButtonComponent, CideEleConfirmationModalComponent, CideEleDataGridComponent, CideEleDropdownComponent, CideEleFileImageDirective, CideEleFileInputComponent, CideEleFileManagerService, CideEleFloatingContainerComponent, CideEleFloatingContainerDynamicDirective, CideEleFloatingContainerManagerComponent, CideEleFloatingContainerService, CideEleFloatingFeaturesService, CideEleFloatingFileUploaderComponent, CideEleGlobalNotificationsComponent, CideEleJsonEditorComponent, CideEleResizerDirective, CideEleSkeletonLoaderComponent, CideEleTabComponent, CideEleToastNotificationComponent, CideElementsService, CideIconComponent, CideInputComponent, CideSelectComponent, CideSelectOptionComponent, CideSpinnerComponent, CideTextareaComponent, ConfirmationService, CoreFileManagerInsertUpdatePayload, DEFAULT_GRID_CONFIG, DropdownManagerService, ICoreCyfmSave, MFileManager, NotificationService, TooltipDirective };
9194
10366
  //# sourceMappingURL=cloud-ide-element.mjs.map