cloud-ide-element 1.0.114 → 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.
@@ -3380,6 +3380,7 @@ class CideEleFileInputComponent {
3380
3380
  notificationService = inject(NotificationService);
3381
3381
  elementService = inject(CideElementsService);
3382
3382
  destroyRef = inject(DestroyRef);
3383
+ // Removed direct injection to avoid circular dependency
3383
3384
  // private readonly pendingTasks = inject(PendingTasks); // TODO: Fix PendingTasks API usage
3384
3385
  // Traditional @Input() decorators
3385
3386
  label = 'Choose file';
@@ -4124,7 +4125,36 @@ class CideEleFileInputComponent {
4124
4125
  * Show floating uploader (alias for showUploader for template)
4125
4126
  */
4126
4127
  showFloatingUploaderDialog() {
4127
- 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
+ }
4128
4158
  }
4129
4159
  /**
4130
4160
  * Get dynamic classes for drag and drop zone
@@ -4971,6 +5001,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
4971
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"] }]
4972
5002
  }], ctorParameters: () => [] });
4973
5003
 
5004
+ var floatingFileUploader_component = /*#__PURE__*/Object.freeze({
5005
+ __proto__: null,
5006
+ CideEleFloatingFileUploaderComponent: CideEleFloatingFileUploaderComponent
5007
+ });
5008
+
4974
5009
  class CideTextareaComponent {
4975
5010
  label = '';
4976
5011
  labelHide = false;
@@ -9200,6 +9235,1124 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
9200
9235
  type: Output
9201
9236
  }] } });
9202
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
+
9203
10356
  /*
9204
10357
  * Public API Surface of cloud-ide-element
9205
10358
  * Here we can add what need to be exported from library
@@ -9209,5 +10362,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
9209
10362
  * Generated bundle index. Do not edit.
9210
10363
  */
9211
10364
 
9212
- 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 };
9213
10366
  //# sourceMappingURL=cloud-ide-element.mjs.map