cloud-ide-element 1.0.120 → 1.1.0
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.
- package/fesm2022/cloud-ide-element.mjs +335 -490
- package/fesm2022/cloud-ide-element.mjs.map +1 -1
- package/index.d.ts +82 -144
- package/package.json +1 -1
|
@@ -1482,12 +1482,12 @@ class CideEleButtonComponent {
|
|
|
1482
1482
|
}
|
|
1483
1483
|
}
|
|
1484
1484
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleButtonComponent, deps: [{ token: CideElementsService }, { token: i2$1.Router }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1485
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleButtonComponent, isStandalone: true, selector: "button[cideEleButton], a[cideEleButton]", inputs: { label: "label", variant: "variant", size: "size", type: "type", shape: "shape", elevation: "elevation", disabled: "disabled", id: "id", loading: "loading", fullWidth: "fullWidth", leftIcon: "leftIcon", rightIcon: "rightIcon", customClass: "customClass", tooltip: "tooltip", ariaLabel: "ariaLabel", testId: "testId", routerLink: "routerLink", routerExtras: "routerExtras", preventDoubleClick: "preventDoubleClick", animated: "animated" }, outputs: { btnClick: "btnClick", doubleClick: "doubleClick" }, host: { listeners: { "click": "onClick($event)" }, properties: { "class.cide-button-disabled": "disabled || loading", "attr.disabled": "(disabled || loading) ? true : null", "class.primary": "variant === \"primary\"", "class.secondary": "variant === \"secondary\"", "class.outline": "variant === \"outline\"", "class.text": "variant === \"text\"", "class.link": "variant === \"link\"", "class.success": "variant === \"success\"", "class.danger": "variant === \"danger\"", "class.warning": "variant === \"warning\"", "class.info": "variant === \"info\"", "class.xs": "size === \"xs\"", "class.sm": "size === \"sm\"", "class.md": "size === \"md\"", "class.lg": "size === \"lg\"", "class.xl": "size === \"xl\"", "class.rounded": "shape === \"rounded\"", "class.pill": "shape === \"pill\"", "class.square": "shape === \"square\"", "class.elevation-none": "elevation === \"none\"", "class.elevation-low": "elevation === \"low\"", "class.elevation-medium": "elevation === \"medium\"", "class.elevation-high": "elevation === \"high\"", "attr.type": "type", "attr.aria-label": "ariaLabel", "attr.aria-disabled": "disabled || loading", "attr.data-testid": "testId", "attr.title": "tooltip", "class": "customClass" }, classAttribute: "cide-button tw-rounded-md tw-text-white tw-py-0.5 tw-select-none tw-
|
|
1485
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleButtonComponent, isStandalone: true, selector: "button[cideEleButton], a[cideEleButton]", inputs: { label: "label", variant: "variant", size: "size", type: "type", shape: "shape", elevation: "elevation", disabled: "disabled", id: "id", loading: "loading", fullWidth: "fullWidth", leftIcon: "leftIcon", rightIcon: "rightIcon", customClass: "customClass", tooltip: "tooltip", ariaLabel: "ariaLabel", testId: "testId", routerLink: "routerLink", routerExtras: "routerExtras", preventDoubleClick: "preventDoubleClick", animated: "animated" }, outputs: { btnClick: "btnClick", doubleClick: "doubleClick" }, host: { listeners: { "click": "onClick($event)" }, properties: { "class.cide-button-disabled": "disabled || loading", "attr.disabled": "(disabled || loading) ? true : null", "class.primary": "variant === \"primary\"", "class.secondary": "variant === \"secondary\"", "class.outline": "variant === \"outline\"", "class.text": "variant === \"text\"", "class.link": "variant === \"link\"", "class.success": "variant === \"success\"", "class.danger": "variant === \"danger\"", "class.warning": "variant === \"warning\"", "class.info": "variant === \"info\"", "class.xs": "size === \"xs\"", "class.sm": "size === \"sm\"", "class.md": "size === \"md\"", "class.lg": "size === \"lg\"", "class.xl": "size === \"xl\"", "class.rounded": "shape === \"rounded\"", "class.pill": "shape === \"pill\"", "class.square": "shape === \"square\"", "class.elevation-none": "elevation === \"none\"", "class.elevation-low": "elevation === \"low\"", "class.elevation-medium": "elevation === \"medium\"", "class.elevation-high": "elevation === \"high\"", "attr.type": "type", "attr.aria-label": "ariaLabel", "attr.aria-disabled": "disabled || loading", "attr.data-testid": "testId", "attr.title": "tooltip", "class": "customClass" }, classAttribute: "cide-button tw-rounded-md tw-text-white tw-py-0.5 tw-select-none tw-flex tw-items-center tw-justify-center" }, usesOnChanges: true, ngImport: i0, template: "<!-- Button content container -->\r\n<div class=\"tw-flex tw-items-center tw-justify-center cide-ele-btn-content tw-w-full\">\r\n <!-- Left icon -->\r\n @if (leftIcon) {\r\n <span class=\"tw-icon-container tw-mr-2\">\r\n <i class=\"tw-text-base material-symbols-outlined\">{{leftIcon}}</i>\r\n </span>\r\n }\r\n \r\n <!-- Loading spinner -->\r\n @if (loading) {\r\n <cide-ele-spinner\r\n class=\"tw-inline-block tw-my-1 tw-mr-2\" \r\n size=\"xs\"\r\n [ngClass]=\"{'cide-pill-disabled': (disabled || loading)}\">\r\n </cide-ele-spinner>\r\n }\r\n \r\n <!-- Button label or content -->\r\n @if (label) {\r\n <span>{{ label }}</span>\r\n } @else {\r\n <span class=\"tw-flex tw-items-center tw-justify-center\">\r\n <ng-content></ng-content>\r\n </span>\r\n }\r\n \r\n <!-- Right icon -->\r\n @if (rightIcon) {\r\n <span class=\"tw-icon-container tw-ml-2\">\r\n <i class=\"tw-text-base material-symbols-outlined\">{{rightIcon}}</i>\r\n </span>\r\n }\r\n \r\n <!-- Spacer for spinner when loading to maintain button width -->\r\n @if (loading) {\r\n <span class=\"tw-w-6 tw-p-1 tw-mr-2\"></span>\r\n }\r\n</div>\r\n", styles: [":host{position:relative;background-color:var(--cide-theme-color-brand-primary, #3b82f6);cursor:pointer;font-family:inherit;font-weight:500;outline:none;overflow:hidden;transition:all .2s ease-in-out;border:none;text-align:center;vertical-align:middle;text-decoration:none;line-height:1.5;letter-spacing:.025em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}:host:focus-visible{outline:2px solid var(--cide-theme-color-brand-primary);outline-offset:2px;box-shadow:0 0 0 3px #3b82f64d}:host:hover:not(:disabled){background-color:var(--cide-theme-color-brand-primary-hover, #2563eb);transform:translateY(-1px)}:host:active:not(:disabled){transform:translateY(1px)}:host.cide-button-disabled{background-color:var(--cide-button-background-disabled, #9ca3af)!important;cursor:var(--cide-button-cursor-disabled, not-allowed)!important;opacity:.7;pointer-events:none;transform:none!important}:host.xs{font-size:.75rem;padding:.2rem .4rem}:host.sm{font-size:.875rem;padding:.25rem .5rem}:host.md{font-size:1rem;padding:.25rem .75rem}:host.lg{font-size:1.125rem;padding:.75rem 1rem}:host.xl{font-size:1.25rem;padding:1rem 1.5rem}:host.rounded{border-radius:.5rem}:host.pill{border-radius:9999px}:host.square{border-radius:0}:host.elevation-none{box-shadow:none}:host.elevation-low{box-shadow:0 1px 2px #0000000d}:host.elevation-medium{box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f}:host.elevation-high{box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d}.ripple-effect{position:absolute;border-radius:50%;background-color:#fff6;transform:scale(0);animation:ripple .6s linear;pointer-events:none}@keyframes ripple{to{transform:scale(4);opacity:0}}:host{color:#fff}:host.secondary{background-color:var(--cide-theme-secondary-color, #4b5563);color:#fff}:host.secondary:hover:not(:disabled){background-color:var(--cide-theme-secondary-color-hover, #374151)}:host.success{background-color:var(--cide-theme-success-color, #10b981);color:#fff}:host.success:hover:not(:disabled){background-color:var(--cide-theme-success-color-hover, #059669)}:host.danger{background-color:var(--cide-theme-danger-color, #ef4444);color:#fff}:host.danger:hover:not(:disabled){background-color:var(--cide-theme-danger-color-hover, #dc2626)}:host.warning{background-color:var(--cide-theme-warning-color, #f59e0b);color:#fff}:host.warning:hover:not(:disabled){background-color:var(--cide-theme-warning-color-hover, #d97706)}:host.info{background-color:var(--cide-theme-info-color, #3b82f6);color:#fff}:host.info:hover:not(:disabled){background-color:var(--cide-theme-info-color-hover, #2563eb)}:host.outline{background-color:transparent;color:var(--cide-theme-color-brand-primary, #3b82f6);border:1px solid var(--cide-theme-color-brand-primary, #3b82f6)}:host.outline:hover:not(:disabled){background-color:#3b82f60d}:host.outline.secondary{color:var(--cide-theme-secondary-color, #4b5563);border-color:var(--cide-theme-secondary-color, #4b5563)}:host.outline.success{color:var(--cide-theme-success-color, #10b981);border-color:var(--cide-theme-success-color, #10b981)}:host.outline.danger{color:var(--cide-theme-danger-color, #ef4444);border-color:var(--cide-theme-danger-color, #ef4444)}:host.outline.warning{color:var(--cide-theme-warning-color, #f59e0b);border-color:var(--cide-theme-warning-color, #f59e0b)}:host.outline.info{color:var(--cide-theme-info-color, #3b82f6);border-color:var(--cide-theme-info-color, #3b82f6)}:host.text{background-color:transparent;color:var(--cide-theme-color-brand-primary, #3b82f6);border:none;padding-left:.5rem;padding-right:.5rem}:host.text:hover:not(:disabled){background-color:#3b82f60d;text-decoration:underline}:host.text.secondary{color:var(--cide-theme-secondary-color, #4b5563)}:host.text.success{color:var(--cide-theme-success-color, #10b981)}:host.text.danger{color:var(--cide-theme-danger-color, #ef4444)}:host.text.warning{color:var(--cide-theme-warning-color, #f59e0b)}:host.text.info{color:var(--cide-theme-info-color, #3b82f6)}:host.link{background-color:transparent;color:var(--cide-theme-color-brand-primary, #3b82f6);border:none;text-decoration:underline;padding:0;font-weight:400}:host.link:hover:not(:disabled){color:var(--cide-theme-color-brand-primary-hover, #2563eb);text-decoration:underline}:host.link.secondary{color:var(--cide-theme-secondary-color, #4b5563)}:host.link.success{color:var(--cide-theme-success-color, #10b981)}:host.link.danger{color:var(--cide-theme-danger-color, #ef4444)}:host.link.warning{color:var(--cide-theme-warning-color, #f59e0b)}:host.link.info{color:var(--cide-theme-info-color, #3b82f6)}.tw-icon-container{display:inline-flex;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: CideSpinnerComponent, selector: "cide-ele-spinner", inputs: ["size", "type"] }] });
|
|
1486
1486
|
}
|
|
1487
1487
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleButtonComponent, decorators: [{
|
|
1488
1488
|
type: Component,
|
|
1489
1489
|
args: [{ selector: 'button[cideEleButton], a[cideEleButton]', standalone: true, imports: [CommonModule, CideSpinnerComponent], host: {
|
|
1490
|
-
'class': 'cide-button tw-rounded-md tw-text-white tw-py-0.5 tw-select-none tw-
|
|
1490
|
+
'class': 'cide-button tw-rounded-md tw-text-white tw-py-0.5 tw-select-none tw-flex tw-items-center tw-justify-center',
|
|
1491
1491
|
'[class.cide-button-disabled]': 'disabled || loading',
|
|
1492
1492
|
'[attr.disabled]': '(disabled || loading) ? true : null',
|
|
1493
1493
|
'[class.primary]': 'variant === "primary"',
|
|
@@ -3385,7 +3385,7 @@ class CideEleFloatingContainerService {
|
|
|
3385
3385
|
activeComponents = new Map();
|
|
3386
3386
|
constructor(injector) {
|
|
3387
3387
|
this.injector = injector;
|
|
3388
|
-
// Keyboard shortcuts are
|
|
3388
|
+
// Keyboard shortcuts are registered by FloatingContainerShortcutsService independently
|
|
3389
3389
|
}
|
|
3390
3390
|
// Computed properties
|
|
3391
3391
|
visibleContainers = computed(() => Array.from(this.containers().values()).filter(container => container.isVisible), ...(ngDevMode ? [{ debugName: "visibleContainers" }] : []));
|
|
@@ -3449,10 +3449,23 @@ class CideEleFloatingContainerService {
|
|
|
3449
3449
|
bringToFront(containerId) {
|
|
3450
3450
|
const maxZIndex = this.getMaxZIndex();
|
|
3451
3451
|
const newZIndex = maxZIndex + 1;
|
|
3452
|
+
const baseZIndex = 1000;
|
|
3452
3453
|
console.log(`🎯 [FloatingContainer] Bringing container '${containerId}' to front`);
|
|
3453
3454
|
console.log(`🎯 [FloatingContainer] Current max z-index: ${maxZIndex}, new z-index: ${newZIndex}`);
|
|
3454
3455
|
this.containers.update(containers => {
|
|
3455
3456
|
const newContainers = new Map(containers);
|
|
3457
|
+
// First, decrement all other visible containers by 1 (clamped to base)
|
|
3458
|
+
for (const [id, c] of newContainers) {
|
|
3459
|
+
if (c.isVisible && id !== containerId) {
|
|
3460
|
+
const decremented = Math.max(baseZIndex, (c.zIndex || baseZIndex) - 1);
|
|
3461
|
+
if (decremented !== c.zIndex) {
|
|
3462
|
+
c.zIndex = decremented;
|
|
3463
|
+
c.lastAccessed = new Date();
|
|
3464
|
+
newContainers.set(id, c);
|
|
3465
|
+
}
|
|
3466
|
+
}
|
|
3467
|
+
}
|
|
3468
|
+
// Then set the focused container to max + 1
|
|
3456
3469
|
const container = newContainers.get(containerId);
|
|
3457
3470
|
if (container) {
|
|
3458
3471
|
const oldZIndex = container.zIndex;
|
|
@@ -4988,6 +5001,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
|
|
|
4988
5001
|
class CideEleFloatingFileUploaderComponent {
|
|
4989
5002
|
destroyRef = inject(DestroyRef);
|
|
4990
5003
|
fileManagerService = inject(CideEleFileManagerService);
|
|
5004
|
+
fileInputRef;
|
|
4991
5005
|
// Input data from floating container
|
|
4992
5006
|
data = {};
|
|
4993
5007
|
// Signals for reactive state (simplified for floating container)
|
|
@@ -5015,6 +5029,16 @@ class CideEleFloatingFileUploaderComponent {
|
|
|
5015
5029
|
hasFilesToShow = computed(() => {
|
|
5016
5030
|
return this.hasActiveUploads() || this.allFilesForGroup().length > 0;
|
|
5017
5031
|
}, ...(ngDevMode ? [{ debugName: "hasFilesToShow" }] : []));
|
|
5032
|
+
// Count methods for template
|
|
5033
|
+
getUploadingCount() {
|
|
5034
|
+
return this.activeUploadsLocal().length;
|
|
5035
|
+
}
|
|
5036
|
+
getCompletedCount() {
|
|
5037
|
+
return this.completedUploads().length;
|
|
5038
|
+
}
|
|
5039
|
+
getFailedCount() {
|
|
5040
|
+
return this.failedUploads().length;
|
|
5041
|
+
}
|
|
5018
5042
|
// Animation states
|
|
5019
5043
|
isAnimating = signal(false, ...(ngDevMode ? [{ debugName: "isAnimating" }] : []));
|
|
5020
5044
|
// Drag functionality removed - handled by floating container
|
|
@@ -5373,10 +5397,8 @@ class CideEleFloatingFileUploaderComponent {
|
|
|
5373
5397
|
* Trigger file input click
|
|
5374
5398
|
*/
|
|
5375
5399
|
triggerFileInput() {
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
if (fileInput) {
|
|
5379
|
-
fileInput.click();
|
|
5400
|
+
if (this.fileInputRef?.nativeElement) {
|
|
5401
|
+
this.fileInputRef.nativeElement.click();
|
|
5380
5402
|
}
|
|
5381
5403
|
}
|
|
5382
5404
|
/**
|
|
@@ -5409,15 +5431,18 @@ class CideEleFloatingFileUploaderComponent {
|
|
|
5409
5431
|
});
|
|
5410
5432
|
}
|
|
5411
5433
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingFileUploaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5412
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleFloatingFileUploaderComponent, isStandalone: true, selector: "cide-ele-floating-file-uploader", inputs: { data: "data" }, ngImport: i0, template: "<!-- File Uploader Content (No absolute positioning - works within floating container) -->\n@if (isVisible()) {\n<div class=\"file-uploader-content\">\n <!-- Simple header without window controls (floating container handles these) -->\n <div class=\"uploader-header\">\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 <!-- Content -->\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</div>\n}\n", styles: [".floating-uploader{position:fixed;width:320px;max-height:500px;background:#fff;border-radius:12px;box-shadow:0 8px 32px #0000001f;border:1px solid rgba(0,0,0,.08);z-index:1000;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateY(0);opacity:1}.floating-uploader.animating{transition:all .3s cubic-bezier(.4,0,.2,1)}.floating-uploader.minimized .uploader-content{display:none}.floating-uploader.minimized .uploader-footer{border-top:none}.floating-uploader.uploading{border-color:#3b82f6;box-shadow:0 8px 32px #3b82f626}.floating-uploader .uploader-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.floating-uploader .uploader-header.draggable-header{cursor:move;-webkit-user-select:none;user-select:none}.floating-uploader .uploader-header.draggable-header:hover{background:#f1f5f9}.floating-uploader .uploader-header.draggable-header:active{background:#e2e8f0;cursor:grabbing}.floating-uploader .uploader-header .header-left{display:flex;align-items:center;gap:8px}.floating-uploader .uploader-header .header-left .upload-icon{display:flex;align-items:center;justify-content:center;width:24px;height:24px;background:#3b82f6;border-radius:6px;color:#fff}.floating-uploader .uploader-header .header-left .upload-info .upload-title{font-size:14px;font-weight:600;color:#1e293b;margin:0}.floating-uploader .uploader-header .header-left .upload-info .upload-summary{font-size:12px;color:#64748b;margin:0}.floating-uploader .uploader-header .header-actions{display:flex;gap:4px}.floating-uploader .uploader-header .header-actions .action-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border:none;background:transparent;border-radius:4px;cursor:pointer;transition:background-color .2s;color:#64748b}.floating-uploader .uploader-header .header-actions .action-btn:hover{background:#e2e8f0;color:#1e293b}.floating-uploader .uploader-header .header-actions .action-btn.close-btn:hover{background:#fef2f2;color:#dc2626}.floating-uploader .uploader-content{max-height:400px;overflow-y:auto}.floating-uploader .uploader-content .upload-zone{margin:8px 16px;padding:12px;border:2px dashed #d1d5db;border-radius:6px;background:#f9fafb;cursor:pointer;transition:all .2s ease;text-align:center}.floating-uploader .uploader-content .upload-zone:hover{border-color:#3b82f6;background:#f0f9ff}.floating-uploader .uploader-content .upload-zone.drag-over{border-color:#3b82f6;background:#dbeafe;transform:scale(1.01)}.floating-uploader .uploader-content .upload-zone .upload-zone-content{display:flex;flex-direction:column;align-items:center;gap:6px}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-icon{color:#6b7280;transition:color .2s ease}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-text .upload-title{font-size:13px;font-weight:500;color:#374151;margin:0;line-height:1.2}.floating-uploader .uploader-content .upload-zone:hover .upload-zone-content .upload-icon{color:#3b82f6}.floating-uploader .uploader-content .upload-zone.drag-over .upload-zone-content .upload-icon{color:#1d4ed8}.floating-uploader .uploader-content .upload-queue .upload-item{display:flex;align-items:center;padding:8px 16px;border-bottom:1px solid #f1f5f9;transition:background-color .2s}.floating-uploader .uploader-content .upload-queue .upload-item:last-child{border-bottom:none}.floating-uploader .uploader-content .upload-queue .upload-item.status-uploading{background:#f0f9ff}.floating-uploader .uploader-content .upload-queue .upload-item.status-completed{background:#f0fdf4}.floating-uploader .uploader-content .upload-queue .upload-item.status-error{background:#fef2f2}.floating-uploader .uploader-content .upload-queue .upload-item .file-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .status-icon{flex-shrink:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details{min-width:0;flex:1}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-name{font-size:13px;font-weight:500;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-status{font-size:11px;margin:0}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-status span{font-weight:500}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress{display:flex;align-items:center;gap:8px;margin:0 8px;min-width:80px}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar{flex:1;height:3px;background:#e2e8f0;border-radius:2px;overflow:hidden}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar .progress-fill{height:100%;background:#3b82f6;transition:width .3s ease}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-text{font-size:10px;color:#64748b;min-width:24px;text-align:right}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions{display:flex;gap:4px}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn{display:flex;align-items:center;justify-content:center;width:20px;height:20px;border:none;background:transparent;border-radius:4px;cursor:pointer;transition:all .2s;color:#64748b}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn:hover{background:#e2e8f0}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.cancel-btn:hover{background:#fef2f2;color:#dc2626}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.retry-btn:hover{background:#f0f9ff;color:#3b82f6}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.success-btn{color:#16a34a}.floating-uploader .uploader-content .hidden-uploader{display:none}.floating-uploader .uploader-footer{padding:8px 16px;background:#f8fafc;border-top:1px solid #e2e8f0}.floating-uploader .uploader-footer .footer-stats{display:flex;gap:12px;font-size:11px}.floating-uploader .uploader-footer .footer-stats .stat{display:flex;align-items:center;gap:4px;color:#64748b}.floating-uploader .uploader-footer .footer-stats .stat.uploading{color:#3b82f6}.floating-uploader .uploader-footer .footer-stats .stat.completed{color:#16a34a}.floating-uploader .uploader-footer .footer-stats .stat.failed{color:#dc2626}@media (max-width: 640px){.floating-uploader{bottom:10px;right:10px;left:10px;width:auto;max-width:none}}@media (prefers-color-scheme: dark){.floating-uploader{background:#1e293b;border-color:#334155;box-shadow:0 8px 32px #0000004d}.floating-uploader.uploading{border-color:#3b82f6;box-shadow:0 8px 32px #3b82f633}.floating-uploader .uploader-header{background:#334155;border-bottom-color:#475569}.floating-uploader .uploader-header.draggable-header:hover{background:#475569}.floating-uploader .uploader-header.draggable-header:active{background:#64748b}.floating-uploader .uploader-header .header-left .upload-icon{background:#3b82f6}.floating-uploader .uploader-header .header-left .upload-info .upload-title{color:#f1f5f9}.floating-uploader .uploader-header .header-left .upload-info .upload-summary,.floating-uploader .uploader-header .header-actions .action-btn{color:#94a3b8}.floating-uploader .uploader-header .header-actions .action-btn:hover{background:#475569;color:#f1f5f9}.floating-uploader .uploader-header .header-actions .action-btn.close-btn:hover{background:#7f1d1d;color:#fca5a5}.floating-uploader .uploader-content .upload-zone{border-color:#475569;background:#334155}.floating-uploader .uploader-content .upload-zone:hover{border-color:#3b82f6;background:#1e3a8a}.floating-uploader .uploader-content .upload-zone.drag-over{border-color:#60a5fa;background:#1e40af}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-icon{color:#94a3b8}.floating-uploader .uploader-content .upload-zone .upload-zone-content .upload-text .upload-title{color:#f1f5f9}.floating-uploader .uploader-content .upload-zone:hover .upload-zone-content .upload-icon{color:#60a5fa}.floating-uploader .uploader-content .upload-zone.drag-over .upload-zone-content .upload-icon{color:#93c5fd}.floating-uploader .uploader-content .upload-queue .upload-item{border-bottom-color:#334155}.floating-uploader .uploader-content .upload-queue .upload-item.status-uploading{background:#1e3a8a}.floating-uploader .uploader-content .upload-queue .upload-item.status-completed{background:#14532d}.floating-uploader .uploader-content .upload-queue .upload-item.status-error{background:#7f1d1d}.floating-uploader .uploader-content .upload-queue .upload-item .file-info .file-details .file-name{color:#f1f5f9}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar{background:#475569}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-bar .progress-fill{background:#3b82f6}.floating-uploader .uploader-content .upload-queue .upload-item .file-progress .progress-text,.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn{color:#94a3b8}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn:hover{background:#475569}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.cancel-btn:hover{background:#7f1d1d;color:#fca5a5}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.retry-btn:hover{background:#1e3a8a;color:#60a5fa}.floating-uploader .uploader-content .upload-queue .upload-item .upload-actions .action-btn.success-btn{color:#4ade80}.floating-uploader .uploader-footer{background:#334155;border-top-color:#475569}.floating-uploader .uploader-footer .footer-stats .stat{color:#94a3b8}.floating-uploader .uploader-footer .footer-stats .stat.uploading{color:#60a5fa}.floating-uploader .uploader-footer .footer-stats .stat.completed{color:#4ade80}.floating-uploader .uploader-footer .footer-stats .stat.failed{color:#fca5a5}}@keyframes slideInUp{0%{transform:translateY(100%);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes slideOutDown{0%{transform:translateY(0);opacity:1}to{transform:translateY(100%);opacity:0}}.floating-uploader.animating{animation:slideInUp .3s cubic-bezier(.4,0,.2,1)}.floating-uploader.animating.hiding{animation:slideOutDown .3s cubic-bezier(.4,0,.2,1)}.no-uploads-message{padding:2rem;text-align:center;color:#6b7280}.no-uploads-message .message-content{display:flex;flex-direction:column;align-items:center;gap:1rem}.no-uploads-message .message-content .message-icon{color:#9ca3af;opacity:.7}.no-uploads-message .message-content .message-text h4{margin:0 0 .5rem;font-size:1.1rem;font-weight:600;color:#374151}.no-uploads-message .message-content .message-text p{margin:0;font-size:.9rem;color:#6b7280}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }] });
|
|
5434
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleFloatingFileUploaderComponent, isStandalone: true, selector: "cide-ele-floating-file-uploader", inputs: { data: "data" }, viewQueries: [{ propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<!-- File Uploader Content (No absolute positioning - works within floating container) -->\n@if (isVisible()) {\n<div class=\"tw-w-full tw-h-full tw-flex tw-flex-col tw-overflow-hidden\">\n <!-- Content starts directly - no header needed since floating container provides it -->\n\n <!-- Content -->\n <div class=\"tw-flex-1 tw-overflow-y-auto tw-p-4 tw-pb-4\">\n \n <!-- Drag and Drop Zone -->\n <div class=\"tw-mb-4 tw-p-6 tw-border-2 tw-border-dashed tw-border-gray-300 tw-rounded-lg tw-bg-gray-50 tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-center hover:tw-border-blue-500 hover:tw-bg-blue-50\" \n [class.tw-border-blue-500]=\"isDragOver()\"\n [class.tw-bg-blue-100]=\"isDragOver()\"\n [class.tw-scale-105]=\"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]=\"data.multiple !== false\" \n [accept]=\"data.allowedFileTypes?.join(',') || '*/*'\" \n (change)=\"onFileInputChange($event)\" \n class=\"tw-hidden\">\n \n <div class=\"tw-flex tw-flex-col tw-items-center tw-gap-2\">\n <cide-ele-icon class=\"tw-text-gray-400 tw-transition-colors tw-duration-200\" \n [class.tw-text-blue-500]=\"isDragOver()\"\n size=\"sm\">cloud_upload</cide-ele-icon>\n \n <div>\n <div class=\"tw-text-sm tw-font-medium tw-text-gray-700\">\n {{ isDragOver() ? 'Drop files here' : 'Drag files here or click to browse' }}\n </div>\n @if (data.description) {\n <div class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">{{ data.description }}</div>\n }\n </div>\n </div>\n </div>\n \n <!-- Upload Queue - Show files from service state -->\n @if (allFilesForGroup().length > 0) {\n <div class=\"tw-space-y-2\">\n <!-- Show all files from service state -->\n @for (file of allFilesForGroup(); track file.fileId) {\n <div class=\"tw-flex tw-items-center tw-px-4 tw-py-3 tw-rounded-lg tw-transition-colors tw-duration-200 tw-bg-white tw-border tw-border-gray-200 hover:tw-bg-gray-100 hover:tw-shadow-sm\"\n [class.tw-bg-blue-50]=\"file.stage === 'uploading'\"\n [class.tw-bg-green-50]=\"file.stage === 'complete'\"\n [class.tw-bg-red-50]=\"file.stage === 'error'\">\n <div class=\"tw-flex tw-items-center tw-gap-2 tw-flex-1 tw-min-w-0\">\n <cide-ele-icon class=\"tw-flex-shrink-0\" size=\"xs\">{{ getStatusIcon(file.stage) }}</cide-ele-icon>\n <div class=\"tw-min-w-0 tw-flex-1\">\n <div class=\"tw-text-sm tw-font-medium tw-text-gray-900 tw-truncate\">{{ file.fileName }}</div>\n <div class=\"tw-text-xs\">\n @switch (file.stage) {\n @case ('pending') {\n <span class=\"tw-text-yellow-600 tw-font-medium\">Waiting...</span>\n }\n @case ('reading') {\n <span class=\"tw-text-yellow-600 tw-font-medium\">Reading...</span>\n }\n @case ('uploading') {\n <span class=\"tw-text-blue-600 tw-font-medium\">Uploading...</span>\n }\n @case ('complete') {\n <span class=\"tw-text-green-600 tw-font-medium\">Completed</span>\n }\n @case ('error') {\n <span class=\"tw-text-red-600 tw-font-medium\">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=\"tw-flex tw-items-center tw-gap-2 tw-ml-2 tw-min-w-[80px]\">\n <div class=\"tw-flex-1 tw-h-1 tw-bg-gray-200 tw-rounded-full tw-overflow-hidden\">\n <div class=\"tw-h-full tw-bg-blue-500 tw-transition-all tw-duration-300\" [style.width.%]=\"file.percentage\"></div>\n </div>\n <span class=\"tw-text-xs tw-text-gray-500 tw-min-w-[24px] tw-text-right\">{{ file.percentage }}%</span>\n </div>\n }\n\n <!-- Actions -->\n <div class=\"tw-flex tw-gap-1 tw-ml-2\">\n @switch (file.stage) {\n @case ('pending') {\n <button class=\"tw-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-border-none tw-bg-transparent tw-rounded tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-400 hover:tw-bg-red-50 hover:tw-text-red-600\" \n (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=\"tw-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-border-none tw-bg-transparent tw-rounded tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-400 hover:tw-bg-red-50 hover:tw-text-red-600\" \n (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=\"tw-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-border-none tw-bg-transparent tw-rounded tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-400 hover:tw-bg-red-50 hover:tw-text-red-600\" \n (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=\"tw-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-border-none tw-bg-transparent tw-rounded tw-cursor-pointer tw-text-green-600\" title=\"Completed\">\n <cide-ele-icon size=\"xs\">check_circle</cide-ele-icon>\n </button>\n }\n @case ('error') {\n <button class=\"tw-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-border-none tw-bg-transparent tw-rounded tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-400 hover:tw-bg-blue-50 hover:tw-text-blue-600\" \n 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=\"tw-py-8 tw-text-center tw-text-gray-500\">\n <div class=\"tw-flex tw-flex-col tw-items-center tw-gap-4\">\n <cide-ele-icon size=\"md\" class=\"tw-text-gray-300 tw-opacity-70\">cloud_upload</cide-ele-icon>\n <div>\n <h4 class=\"tw-text-lg tw-font-semibold tw-text-gray-700 tw-mb-2\">No active uploads</h4>\n <p class=\"tw-text-sm tw-text-gray-500\">Upload files to see their progress here</p>\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Status summary - integrated into content -->\n @if (hasActiveUploads()) {\n <div class=\"tw-px-4 tw-py-2 tw-bg-gray-50\">\n <div class=\"tw-flex tw-gap-3 tw-text-xs\">\n <div class=\"tw-flex tw-items-center tw-gap-1 tw-text-blue-600\">\n <cide-ele-icon size=\"xs\">upload</cide-ele-icon>\n <span>{{ getUploadingCount() }} uploading</span>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1 tw-text-green-600\">\n <cide-ele-icon size=\"xs\">check_circle</cide-ele-icon>\n <span>{{ getCompletedCount() }} completed</span>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1 tw-text-red-600\">\n <cide-ele-icon size=\"xs\">error</cide-ele-icon>\n <span>{{ getFailedCount() }} failed</span>\n </div>\n </div>\n </div>\n }\n</div>\n}", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }] });
|
|
5413
5435
|
}
|
|
5414
5436
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingFileUploaderComponent, decorators: [{
|
|
5415
5437
|
type: Component,
|
|
5416
5438
|
args: [{ selector: 'cide-ele-floating-file-uploader', standalone: true, imports: [
|
|
5417
5439
|
CommonModule,
|
|
5418
5440
|
CideIconComponent
|
|
5419
|
-
], template: "<!-- File Uploader Content (No absolute positioning - works within floating container) -->\n@if (isVisible()) {\n<div class=\"file-uploader-content\">\n <!-- Simple header without window controls (floating container handles these) -->\n <div class=\"uploader-header\">\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 <!-- Content -->\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</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"] }]
|
|
5420
|
-
}], ctorParameters: () => [], propDecorators: {
|
|
5441
|
+
], template: "<!-- File Uploader Content (No absolute positioning - works within floating container) -->\n@if (isVisible()) {\n<div class=\"tw-w-full tw-h-full tw-flex tw-flex-col tw-overflow-hidden\">\n <!-- Content starts directly - no header needed since floating container provides it -->\n\n <!-- Content -->\n <div class=\"tw-flex-1 tw-overflow-y-auto tw-p-4 tw-pb-4\">\n \n <!-- Drag and Drop Zone -->\n <div class=\"tw-mb-4 tw-p-6 tw-border-2 tw-border-dashed tw-border-gray-300 tw-rounded-lg tw-bg-gray-50 tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-center hover:tw-border-blue-500 hover:tw-bg-blue-50\" \n [class.tw-border-blue-500]=\"isDragOver()\"\n [class.tw-bg-blue-100]=\"isDragOver()\"\n [class.tw-scale-105]=\"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]=\"data.multiple !== false\" \n [accept]=\"data.allowedFileTypes?.join(',') || '*/*'\" \n (change)=\"onFileInputChange($event)\" \n class=\"tw-hidden\">\n \n <div class=\"tw-flex tw-flex-col tw-items-center tw-gap-2\">\n <cide-ele-icon class=\"tw-text-gray-400 tw-transition-colors tw-duration-200\" \n [class.tw-text-blue-500]=\"isDragOver()\"\n size=\"sm\">cloud_upload</cide-ele-icon>\n \n <div>\n <div class=\"tw-text-sm tw-font-medium tw-text-gray-700\">\n {{ isDragOver() ? 'Drop files here' : 'Drag files here or click to browse' }}\n </div>\n @if (data.description) {\n <div class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">{{ data.description }}</div>\n }\n </div>\n </div>\n </div>\n \n <!-- Upload Queue - Show files from service state -->\n @if (allFilesForGroup().length > 0) {\n <div class=\"tw-space-y-2\">\n <!-- Show all files from service state -->\n @for (file of allFilesForGroup(); track file.fileId) {\n <div class=\"tw-flex tw-items-center tw-px-4 tw-py-3 tw-rounded-lg tw-transition-colors tw-duration-200 tw-bg-white tw-border tw-border-gray-200 hover:tw-bg-gray-100 hover:tw-shadow-sm\"\n [class.tw-bg-blue-50]=\"file.stage === 'uploading'\"\n [class.tw-bg-green-50]=\"file.stage === 'complete'\"\n [class.tw-bg-red-50]=\"file.stage === 'error'\">\n <div class=\"tw-flex tw-items-center tw-gap-2 tw-flex-1 tw-min-w-0\">\n <cide-ele-icon class=\"tw-flex-shrink-0\" size=\"xs\">{{ getStatusIcon(file.stage) }}</cide-ele-icon>\n <div class=\"tw-min-w-0 tw-flex-1\">\n <div class=\"tw-text-sm tw-font-medium tw-text-gray-900 tw-truncate\">{{ file.fileName }}</div>\n <div class=\"tw-text-xs\">\n @switch (file.stage) {\n @case ('pending') {\n <span class=\"tw-text-yellow-600 tw-font-medium\">Waiting...</span>\n }\n @case ('reading') {\n <span class=\"tw-text-yellow-600 tw-font-medium\">Reading...</span>\n }\n @case ('uploading') {\n <span class=\"tw-text-blue-600 tw-font-medium\">Uploading...</span>\n }\n @case ('complete') {\n <span class=\"tw-text-green-600 tw-font-medium\">Completed</span>\n }\n @case ('error') {\n <span class=\"tw-text-red-600 tw-font-medium\">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=\"tw-flex tw-items-center tw-gap-2 tw-ml-2 tw-min-w-[80px]\">\n <div class=\"tw-flex-1 tw-h-1 tw-bg-gray-200 tw-rounded-full tw-overflow-hidden\">\n <div class=\"tw-h-full tw-bg-blue-500 tw-transition-all tw-duration-300\" [style.width.%]=\"file.percentage\"></div>\n </div>\n <span class=\"tw-text-xs tw-text-gray-500 tw-min-w-[24px] tw-text-right\">{{ file.percentage }}%</span>\n </div>\n }\n\n <!-- Actions -->\n <div class=\"tw-flex tw-gap-1 tw-ml-2\">\n @switch (file.stage) {\n @case ('pending') {\n <button class=\"tw-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-border-none tw-bg-transparent tw-rounded tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-400 hover:tw-bg-red-50 hover:tw-text-red-600\" \n (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=\"tw-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-border-none tw-bg-transparent tw-rounded tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-400 hover:tw-bg-red-50 hover:tw-text-red-600\" \n (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=\"tw-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-border-none tw-bg-transparent tw-rounded tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-400 hover:tw-bg-red-50 hover:tw-text-red-600\" \n (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=\"tw-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-border-none tw-bg-transparent tw-rounded tw-cursor-pointer tw-text-green-600\" title=\"Completed\">\n <cide-ele-icon size=\"xs\">check_circle</cide-ele-icon>\n </button>\n }\n @case ('error') {\n <button class=\"tw-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-border-none tw-bg-transparent tw-rounded tw-cursor-pointer tw-transition-all tw-duration-200 tw-text-gray-400 hover:tw-bg-blue-50 hover:tw-text-blue-600\" \n 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=\"tw-py-8 tw-text-center tw-text-gray-500\">\n <div class=\"tw-flex tw-flex-col tw-items-center tw-gap-4\">\n <cide-ele-icon size=\"md\" class=\"tw-text-gray-300 tw-opacity-70\">cloud_upload</cide-ele-icon>\n <div>\n <h4 class=\"tw-text-lg tw-font-semibold tw-text-gray-700 tw-mb-2\">No active uploads</h4>\n <p class=\"tw-text-sm tw-text-gray-500\">Upload files to see their progress here</p>\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Status summary - integrated into content -->\n @if (hasActiveUploads()) {\n <div class=\"tw-px-4 tw-py-2 tw-bg-gray-50\">\n <div class=\"tw-flex tw-gap-3 tw-text-xs\">\n <div class=\"tw-flex tw-items-center tw-gap-1 tw-text-blue-600\">\n <cide-ele-icon size=\"xs\">upload</cide-ele-icon>\n <span>{{ getUploadingCount() }} uploading</span>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1 tw-text-green-600\">\n <cide-ele-icon size=\"xs\">check_circle</cide-ele-icon>\n <span>{{ getCompletedCount() }} completed</span>\n </div>\n <div class=\"tw-flex tw-items-center tw-gap-1 tw-text-red-600\">\n <cide-ele-icon size=\"xs\">error</cide-ele-icon>\n <span>{{ getFailedCount() }} failed</span>\n </div>\n </div>\n </div>\n }\n</div>\n}" }]
|
|
5442
|
+
}], ctorParameters: () => [], propDecorators: { fileInputRef: [{
|
|
5443
|
+
type: ViewChild,
|
|
5444
|
+
args: ['fileInput']
|
|
5445
|
+
}], data: [{
|
|
5421
5446
|
type: Input
|
|
5422
5447
|
}] } });
|
|
5423
5448
|
|
|
@@ -5767,477 +5792,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
|
|
|
5767
5792
|
}]
|
|
5768
5793
|
}], ctorParameters: () => [] });
|
|
5769
5794
|
|
|
5770
|
-
class FloatingContainerShortcutsService {
|
|
5771
|
-
keyboardShortcutService = inject(KeyboardShortcutService);
|
|
5772
|
-
containerService = inject(CideEleFloatingContainerService);
|
|
5773
|
-
// Z-index layers for different container states
|
|
5774
|
-
Z_INDEX_LAYERS = {
|
|
5775
|
-
HIDDEN: 100, // Hidden containers (behind everything)
|
|
5776
|
-
BACKGROUND: 1000, // Background containers
|
|
5777
|
-
NORMAL: 2000, // Normal visible containers
|
|
5778
|
-
FOCUSED: 3000, // Focused containers
|
|
5779
|
-
MODAL: 4000, // Modal containers
|
|
5780
|
-
TOOLTIP: 5000 // Tooltips and overlays
|
|
5781
|
-
};
|
|
5782
|
-
constructor() {
|
|
5783
|
-
this.registerDefaultShortcuts();
|
|
5784
|
-
}
|
|
5785
|
-
/**
|
|
5786
|
-
* Register default floating container shortcuts using custom key combinations
|
|
5787
|
-
*/
|
|
5788
|
-
registerDefaultShortcuts() {
|
|
5789
|
-
// C + 1: Focus on first container
|
|
5790
|
-
this.keyboardShortcutService.register({
|
|
5791
|
-
id: 'floating-container-focus-first',
|
|
5792
|
-
key: '1',
|
|
5793
|
-
ctrlKey: true,
|
|
5794
|
-
description: 'Focus on first floating container (C+1)',
|
|
5795
|
-
action: () => this.focusFirstContainer(),
|
|
5796
|
-
preventDefault: true
|
|
5797
|
-
});
|
|
5798
|
-
// C + 2: Focus on second container
|
|
5799
|
-
this.keyboardShortcutService.register({
|
|
5800
|
-
id: 'floating-container-focus-second',
|
|
5801
|
-
key: '2',
|
|
5802
|
-
ctrlKey: true,
|
|
5803
|
-
description: 'Focus on second floating container (C+2)',
|
|
5804
|
-
action: () => this.focusContainerByIndex(1),
|
|
5805
|
-
preventDefault: true
|
|
5806
|
-
});
|
|
5807
|
-
// C + 3: Focus on third container
|
|
5808
|
-
this.keyboardShortcutService.register({
|
|
5809
|
-
id: 'floating-container-focus-third',
|
|
5810
|
-
key: '3',
|
|
5811
|
-
ctrlKey: true,
|
|
5812
|
-
description: 'Focus on third floating container (C+3)',
|
|
5813
|
-
action: () => this.focusContainerByIndex(2),
|
|
5814
|
-
preventDefault: true
|
|
5815
|
-
});
|
|
5816
|
-
// C + 4: Focus on fourth container
|
|
5817
|
-
this.keyboardShortcutService.register({
|
|
5818
|
-
id: 'floating-container-focus-fourth',
|
|
5819
|
-
key: '4',
|
|
5820
|
-
ctrlKey: true,
|
|
5821
|
-
description: 'Focus on fourth floating container (C+4)',
|
|
5822
|
-
action: () => this.focusContainerByIndex(3),
|
|
5823
|
-
preventDefault: true
|
|
5824
|
-
});
|
|
5825
|
-
// C + 5: Focus on fifth container
|
|
5826
|
-
this.keyboardShortcutService.register({
|
|
5827
|
-
id: 'floating-container-focus-fifth',
|
|
5828
|
-
key: '5',
|
|
5829
|
-
ctrlKey: true,
|
|
5830
|
-
description: 'Focus on fifth floating container (C+5)',
|
|
5831
|
-
action: () => this.focusContainerByIndex(4),
|
|
5832
|
-
preventDefault: true
|
|
5833
|
-
});
|
|
5834
|
-
// C + N: Cycle to next container
|
|
5835
|
-
this.keyboardShortcutService.register({
|
|
5836
|
-
id: 'floating-container-cycle-forward',
|
|
5837
|
-
key: 'n',
|
|
5838
|
-
ctrlKey: true,
|
|
5839
|
-
description: 'Cycle forward through floating containers (C+N)',
|
|
5840
|
-
action: () => this.cycleToNextContainer(),
|
|
5841
|
-
preventDefault: true
|
|
5842
|
-
});
|
|
5843
|
-
// C + P: Cycle to previous container
|
|
5844
|
-
this.keyboardShortcutService.register({
|
|
5845
|
-
id: 'floating-container-cycle-backward',
|
|
5846
|
-
key: 'p',
|
|
5847
|
-
ctrlKey: true,
|
|
5848
|
-
description: 'Cycle backward through floating containers (C+P)',
|
|
5849
|
-
action: () => this.cycleToPreviousContainer(),
|
|
5850
|
-
preventDefault: true
|
|
5851
|
-
});
|
|
5852
|
-
// C + H: Hide all containers
|
|
5853
|
-
this.keyboardShortcutService.register({
|
|
5854
|
-
id: 'floating-container-hide-all',
|
|
5855
|
-
key: 'h',
|
|
5856
|
-
ctrlKey: true,
|
|
5857
|
-
description: 'Hide all floating containers (C+H)',
|
|
5858
|
-
action: () => this.hideAllContainers(),
|
|
5859
|
-
preventDefault: true
|
|
5860
|
-
});
|
|
5861
|
-
// C + M: Minimize all containers
|
|
5862
|
-
this.keyboardShortcutService.register({
|
|
5863
|
-
id: 'floating-container-minimize-all',
|
|
5864
|
-
key: 'm',
|
|
5865
|
-
ctrlKey: true,
|
|
5866
|
-
description: 'Minimize all floating containers (C+M)',
|
|
5867
|
-
action: () => this.minimizeAllContainers(),
|
|
5868
|
-
preventDefault: true
|
|
5869
|
-
});
|
|
5870
|
-
// C + O: Open file uploader
|
|
5871
|
-
this.keyboardShortcutService.register({
|
|
5872
|
-
id: 'floating-container-open-file-uploader',
|
|
5873
|
-
key: 'o',
|
|
5874
|
-
ctrlKey: true,
|
|
5875
|
-
description: 'Open file uploader (C+O)',
|
|
5876
|
-
action: () => this.openFileUploader(),
|
|
5877
|
-
preventDefault: true
|
|
5878
|
-
});
|
|
5879
|
-
// C + R: Open entity rights sharing
|
|
5880
|
-
this.keyboardShortcutService.register({
|
|
5881
|
-
id: 'floating-container-open-entity-rights',
|
|
5882
|
-
key: 'r',
|
|
5883
|
-
ctrlKey: true,
|
|
5884
|
-
description: 'Open entity rights sharing (C+R)',
|
|
5885
|
-
action: () => this.openEntityRightsSharing(),
|
|
5886
|
-
preventDefault: true
|
|
5887
|
-
});
|
|
5888
|
-
// C + S: Show all containers
|
|
5889
|
-
this.keyboardShortcutService.register({
|
|
5890
|
-
id: 'floating-container-show-all',
|
|
5891
|
-
key: 's',
|
|
5892
|
-
ctrlKey: true,
|
|
5893
|
-
description: 'Show all floating containers (C+S)',
|
|
5894
|
-
action: () => this.showAllContainers(),
|
|
5895
|
-
preventDefault: true
|
|
5896
|
-
});
|
|
5897
|
-
// C + D: Duplicate current container
|
|
5898
|
-
this.keyboardShortcutService.register({
|
|
5899
|
-
id: 'floating-container-duplicate',
|
|
5900
|
-
key: 'd',
|
|
5901
|
-
ctrlKey: true,
|
|
5902
|
-
description: 'Duplicate current container (C+D)',
|
|
5903
|
-
action: () => this.duplicateCurrentContainer(),
|
|
5904
|
-
preventDefault: true
|
|
5905
|
-
});
|
|
5906
|
-
// C + W: Close current container
|
|
5907
|
-
this.keyboardShortcutService.register({
|
|
5908
|
-
id: 'floating-container-close-current',
|
|
5909
|
-
key: 'w',
|
|
5910
|
-
ctrlKey: true,
|
|
5911
|
-
description: 'Close current container (C+W)',
|
|
5912
|
-
action: () => this.closeCurrentContainer(),
|
|
5913
|
-
preventDefault: true
|
|
5914
|
-
});
|
|
5915
|
-
// C + T: Toggle container visibility
|
|
5916
|
-
this.keyboardShortcutService.register({
|
|
5917
|
-
id: 'floating-container-toggle-visibility',
|
|
5918
|
-
key: 't',
|
|
5919
|
-
ctrlKey: true,
|
|
5920
|
-
description: 'Toggle container visibility (C+T)',
|
|
5921
|
-
action: () => this.toggleContainerVisibility(),
|
|
5922
|
-
preventDefault: true
|
|
5923
|
-
});
|
|
5924
|
-
console.log('🎯 [FloatingContainerShortcuts] Custom shortcuts registered (C+1, C+2, C+O, etc.)');
|
|
5925
|
-
}
|
|
5926
|
-
/**
|
|
5927
|
-
* Override a floating container shortcut
|
|
5928
|
-
*/
|
|
5929
|
-
overrideShortcut(shortcutId, newKey, options) {
|
|
5930
|
-
this.keyboardShortcutService.override(shortcutId, newKey, options);
|
|
5931
|
-
}
|
|
5932
|
-
/**
|
|
5933
|
-
* Add a custom floating container shortcut
|
|
5934
|
-
*/
|
|
5935
|
-
addCustomShortcut(shortcut) {
|
|
5936
|
-
this.keyboardShortcutService.register({
|
|
5937
|
-
...shortcut,
|
|
5938
|
-
preventDefault: true
|
|
5939
|
-
});
|
|
5940
|
-
}
|
|
5941
|
-
/**
|
|
5942
|
-
* Remove a floating container shortcut
|
|
5943
|
-
*/
|
|
5944
|
-
removeShortcut(shortcutId) {
|
|
5945
|
-
this.keyboardShortcutService.unregister(shortcutId);
|
|
5946
|
-
}
|
|
5947
|
-
/**
|
|
5948
|
-
* Get all floating container shortcuts
|
|
5949
|
-
*/
|
|
5950
|
-
getShortcuts() {
|
|
5951
|
-
return this.keyboardShortcutService.getShortcuts(shortcut => shortcut.id.startsWith('floating-container-'));
|
|
5952
|
-
}
|
|
5953
|
-
// Action methods
|
|
5954
|
-
cycleToNextContainer() {
|
|
5955
|
-
const visibleContainers = this.containerService.visibleContainers();
|
|
5956
|
-
if (visibleContainers.length === 0)
|
|
5957
|
-
return;
|
|
5958
|
-
// Sort by last accessed time (most recent first)
|
|
5959
|
-
const sortedContainers = visibleContainers.sort((a, b) => b.lastAccessed.getTime() - a.lastAccessed.getTime());
|
|
5960
|
-
// Find current front container
|
|
5961
|
-
const currentFront = sortedContainers[0];
|
|
5962
|
-
const currentIndex = sortedContainers.findIndex(c => c.id === currentFront.id);
|
|
5963
|
-
// Get next container (wrap around)
|
|
5964
|
-
const nextIndex = (currentIndex + 1) % sortedContainers.length;
|
|
5965
|
-
const nextContainer = sortedContainers[nextIndex];
|
|
5966
|
-
this.containerService.bringToFront(nextContainer.id);
|
|
5967
|
-
console.log(`🔄 [FloatingContainerShortcuts] Cycled to container: ${nextContainer.config.title}`);
|
|
5968
|
-
}
|
|
5969
|
-
cycleToPreviousContainer() {
|
|
5970
|
-
const visibleContainers = this.containerService.visibleContainers();
|
|
5971
|
-
if (visibleContainers.length === 0)
|
|
5972
|
-
return;
|
|
5973
|
-
// Sort by last accessed time (most recent first)
|
|
5974
|
-
const sortedContainers = visibleContainers.sort((a, b) => b.lastAccessed.getTime() - a.lastAccessed.getTime());
|
|
5975
|
-
// Find current front container
|
|
5976
|
-
const currentFront = sortedContainers[0];
|
|
5977
|
-
const currentIndex = sortedContainers.findIndex(c => c.id === currentFront.id);
|
|
5978
|
-
// Get previous container (wrap around)
|
|
5979
|
-
const prevIndex = currentIndex === 0 ? sortedContainers.length - 1 : currentIndex - 1;
|
|
5980
|
-
const prevContainer = sortedContainers[prevIndex];
|
|
5981
|
-
this.containerService.bringToFront(prevContainer.id);
|
|
5982
|
-
console.log(`🔄 [FloatingContainerShortcuts] Cycled backwards to container: ${prevContainer.config.title}`);
|
|
5983
|
-
}
|
|
5984
|
-
hideAllContainers() {
|
|
5985
|
-
const visibleContainers = this.containerService.visibleContainers();
|
|
5986
|
-
visibleContainers.forEach(container => {
|
|
5987
|
-
this.containerService.setZIndex(container.id, this.Z_INDEX_LAYERS.HIDDEN);
|
|
5988
|
-
});
|
|
5989
|
-
console.log(`👁️ [FloatingContainerShortcuts] All containers moved to hidden layer (z-index: ${this.Z_INDEX_LAYERS.HIDDEN})`);
|
|
5990
|
-
}
|
|
5991
|
-
focusFirstContainer() {
|
|
5992
|
-
const visibleContainers = this.containerService.visibleContainers();
|
|
5993
|
-
if (visibleContainers.length === 0)
|
|
5994
|
-
return;
|
|
5995
|
-
const firstContainer = visibleContainers[0];
|
|
5996
|
-
this.containerService.bringToFront(firstContainer.id);
|
|
5997
|
-
console.log(`🎯 [FloatingContainerShortcuts] Focused on first container: ${firstContainer.config.title}`);
|
|
5998
|
-
}
|
|
5999
|
-
minimizeAllContainers() {
|
|
6000
|
-
this.containerService.minimizeAll();
|
|
6001
|
-
console.log(`📦 [FloatingContainerShortcuts] All containers minimized`);
|
|
6002
|
-
}
|
|
6003
|
-
focusContainerByIndex(index) {
|
|
6004
|
-
const visibleContainers = this.containerService.visibleContainers();
|
|
6005
|
-
if (visibleContainers.length === 0 || index >= visibleContainers.length) {
|
|
6006
|
-
console.log(`⚠️ [FloatingContainerShortcuts] No container at index ${index}`);
|
|
6007
|
-
return;
|
|
6008
|
-
}
|
|
6009
|
-
const container = visibleContainers[index];
|
|
6010
|
-
this.containerService.bringToFront(container.id);
|
|
6011
|
-
console.log(`🎯 [FloatingContainerShortcuts] Focused on container ${index + 1}: ${container.config.title}`);
|
|
6012
|
-
}
|
|
6013
|
-
openFileUploader() {
|
|
6014
|
-
console.log(`📁 [FloatingContainerShortcuts] Opening file uploader...`);
|
|
6015
|
-
// This would need to be implemented based on your file uploader service
|
|
6016
|
-
// Example: this.fileUploaderService.show();
|
|
6017
|
-
}
|
|
6018
|
-
openEntityRightsSharing() {
|
|
6019
|
-
console.log(`🔐 [FloatingContainerShortcuts] Opening entity rights sharing...`);
|
|
6020
|
-
// This would need to be implemented based on your entity rights service
|
|
6021
|
-
// Example: this.entityRightsService.show();
|
|
6022
|
-
}
|
|
6023
|
-
showAllContainers() {
|
|
6024
|
-
const visibleContainers = this.containerService.visibleContainers();
|
|
6025
|
-
visibleContainers.forEach((container, index) => {
|
|
6026
|
-
// Give each container a slightly different z-index to maintain order
|
|
6027
|
-
const zIndex = this.Z_INDEX_LAYERS.NORMAL + index;
|
|
6028
|
-
this.containerService.setZIndex(container.id, zIndex);
|
|
6029
|
-
});
|
|
6030
|
-
console.log(`👁️ [FloatingContainerShortcuts] All containers moved to normal layer (z-index: ${this.Z_INDEX_LAYERS.NORMAL}+)`);
|
|
6031
|
-
}
|
|
6032
|
-
duplicateCurrentContainer() {
|
|
6033
|
-
const visibleContainers = this.containerService.visibleContainers();
|
|
6034
|
-
if (visibleContainers.length === 0) {
|
|
6035
|
-
console.log(`⚠️ [FloatingContainerShortcuts] No containers to duplicate`);
|
|
6036
|
-
return;
|
|
6037
|
-
}
|
|
6038
|
-
const currentContainer = visibleContainers[0]; // Most recent container
|
|
6039
|
-
console.log(`📋 [FloatingContainerShortcuts] Duplicating container: ${currentContainer.config.title}`);
|
|
6040
|
-
// This would need to be implemented based on your container duplication logic
|
|
6041
|
-
}
|
|
6042
|
-
closeCurrentContainer() {
|
|
6043
|
-
const visibleContainers = this.containerService.visibleContainers();
|
|
6044
|
-
if (visibleContainers.length === 0) {
|
|
6045
|
-
console.log(`⚠️ [FloatingContainerShortcuts] No containers to close`);
|
|
6046
|
-
return;
|
|
6047
|
-
}
|
|
6048
|
-
const currentContainer = visibleContainers[0]; // Most recent container
|
|
6049
|
-
this.containerService.hide(currentContainer.id);
|
|
6050
|
-
console.log(`❌ [FloatingContainerShortcuts] Closed container: ${currentContainer.config.title}`);
|
|
6051
|
-
}
|
|
6052
|
-
toggleContainerVisibility() {
|
|
6053
|
-
const visibleContainers = this.containerService.visibleContainers();
|
|
6054
|
-
if (visibleContainers.length === 0) {
|
|
6055
|
-
console.log(`⚠️ [FloatingContainerShortcuts] No containers to toggle`);
|
|
6056
|
-
return;
|
|
6057
|
-
}
|
|
6058
|
-
// Toggle visibility of the most recent container using z-index
|
|
6059
|
-
const currentContainer = visibleContainers[0];
|
|
6060
|
-
const currentZIndex = currentContainer.zIndex;
|
|
6061
|
-
if (currentZIndex >= this.Z_INDEX_LAYERS.NORMAL) {
|
|
6062
|
-
// Container is visible, move to hidden layer
|
|
6063
|
-
this.containerService.setZIndex(currentContainer.id, this.Z_INDEX_LAYERS.HIDDEN);
|
|
6064
|
-
console.log(`👁️ [FloatingContainerShortcuts] Hidden container (z-index: ${this.Z_INDEX_LAYERS.HIDDEN}): ${currentContainer.config.title}`);
|
|
6065
|
-
}
|
|
6066
|
-
else {
|
|
6067
|
-
// Container is hidden, move to normal layer
|
|
6068
|
-
this.containerService.setZIndex(currentContainer.id, this.Z_INDEX_LAYERS.NORMAL);
|
|
6069
|
-
console.log(`👁️ [FloatingContainerShortcuts] Shown container (z-index: ${this.Z_INDEX_LAYERS.NORMAL}): ${currentContainer.config.title}`);
|
|
6070
|
-
}
|
|
6071
|
-
}
|
|
6072
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
6073
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, providedIn: 'root' });
|
|
6074
|
-
}
|
|
6075
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, decorators: [{
|
|
6076
|
-
type: Injectable,
|
|
6077
|
-
args: [{
|
|
6078
|
-
providedIn: 'root'
|
|
6079
|
-
}]
|
|
6080
|
-
}], ctorParameters: () => [] });
|
|
6081
|
-
|
|
6082
|
-
class AppShortcutService {
|
|
6083
|
-
keyboardShortcutService = inject(KeyboardShortcutService);
|
|
6084
|
-
registeredShortcuts = new Map();
|
|
6085
|
-
/**
|
|
6086
|
-
* Register shortcuts from app component
|
|
6087
|
-
* @param shortcuts Array of shortcut configurations
|
|
6088
|
-
*/
|
|
6089
|
-
registerShortcuts(shortcuts) {
|
|
6090
|
-
console.log('🎯 [AppShortcut] Registering app shortcuts:', shortcuts.length);
|
|
6091
|
-
shortcuts.forEach(config => {
|
|
6092
|
-
const shortcutId = `app-${config.eventName}`;
|
|
6093
|
-
// Convert AppShortcutConfig to KeyboardShortcut format
|
|
6094
|
-
this.keyboardShortcutService.register({
|
|
6095
|
-
id: shortcutId,
|
|
6096
|
-
key: config.key,
|
|
6097
|
-
ctrlKey: config.ctrlKey,
|
|
6098
|
-
altKey: config.altKey,
|
|
6099
|
-
shiftKey: config.shiftKey,
|
|
6100
|
-
metaKey: config.metaKey,
|
|
6101
|
-
description: config.description,
|
|
6102
|
-
action: () => {
|
|
6103
|
-
console.log(`🎯 [AppShortcut] Executing app shortcut: ${config.eventName}`);
|
|
6104
|
-
this.executeAppEvent(config.eventName);
|
|
6105
|
-
},
|
|
6106
|
-
preventDefault: config.preventDefault !== false,
|
|
6107
|
-
stopPropagation: config.stopPropagation || false
|
|
6108
|
-
});
|
|
6109
|
-
// Store the configuration
|
|
6110
|
-
this.registeredShortcuts.set(shortcutId, config);
|
|
6111
|
-
console.log(`✅ [AppShortcut] Registered shortcut: ${shortcutId} (${this.getKeyDescription(config)})`);
|
|
6112
|
-
});
|
|
6113
|
-
}
|
|
6114
|
-
/**
|
|
6115
|
-
* Unregister shortcuts by event names
|
|
6116
|
-
* @param eventNames Array of event names to unregister
|
|
6117
|
-
*/
|
|
6118
|
-
unregisterShortcuts(eventNames) {
|
|
6119
|
-
console.log('🗑️ [AppShortcut] Unregistering app shortcuts:', eventNames);
|
|
6120
|
-
eventNames.forEach(eventName => {
|
|
6121
|
-
const shortcutId = `app-${eventName}`;
|
|
6122
|
-
if (this.registeredShortcuts.has(shortcutId)) {
|
|
6123
|
-
this.keyboardShortcutService.unregister(shortcutId);
|
|
6124
|
-
this.registeredShortcuts.delete(shortcutId);
|
|
6125
|
-
console.log(`✅ [AppShortcut] Unregistered shortcut: ${shortcutId}`);
|
|
6126
|
-
}
|
|
6127
|
-
else {
|
|
6128
|
-
console.warn(`⚠️ [AppShortcut] Shortcut not found: ${shortcutId}`);
|
|
6129
|
-
}
|
|
6130
|
-
});
|
|
6131
|
-
}
|
|
6132
|
-
/**
|
|
6133
|
-
* Get all registered app shortcuts
|
|
6134
|
-
*/
|
|
6135
|
-
getRegisteredShortcuts() {
|
|
6136
|
-
return Array.from(this.registeredShortcuts.values());
|
|
6137
|
-
}
|
|
6138
|
-
/**
|
|
6139
|
-
* Check if a shortcut is registered
|
|
6140
|
-
* @param eventName Event name to check
|
|
6141
|
-
*/
|
|
6142
|
-
isShortcutRegistered(eventName) {
|
|
6143
|
-
const shortcutId = `app-${eventName}`;
|
|
6144
|
-
return this.registeredShortcuts.has(shortcutId);
|
|
6145
|
-
}
|
|
6146
|
-
/**
|
|
6147
|
-
* Update an existing shortcut
|
|
6148
|
-
* @param eventName Event name to update
|
|
6149
|
-
* @param newConfig New shortcut configuration
|
|
6150
|
-
*/
|
|
6151
|
-
updateShortcut(eventName, newConfig) {
|
|
6152
|
-
const shortcutId = `app-${eventName}`;
|
|
6153
|
-
if (this.registeredShortcuts.has(shortcutId)) {
|
|
6154
|
-
// Unregister old shortcut
|
|
6155
|
-
this.keyboardShortcutService.unregister(shortcutId);
|
|
6156
|
-
// Register new shortcut
|
|
6157
|
-
this.keyboardShortcutService.register({
|
|
6158
|
-
id: shortcutId,
|
|
6159
|
-
key: newConfig.key,
|
|
6160
|
-
ctrlKey: newConfig.ctrlKey,
|
|
6161
|
-
altKey: newConfig.altKey,
|
|
6162
|
-
shiftKey: newConfig.shiftKey,
|
|
6163
|
-
metaKey: newConfig.metaKey,
|
|
6164
|
-
description: newConfig.description,
|
|
6165
|
-
action: () => {
|
|
6166
|
-
console.log(`🎯 [AppShortcut] Executing updated app shortcut: ${eventName}`);
|
|
6167
|
-
this.executeAppEvent(eventName);
|
|
6168
|
-
},
|
|
6169
|
-
preventDefault: newConfig.preventDefault !== false,
|
|
6170
|
-
stopPropagation: newConfig.stopPropagation || false
|
|
6171
|
-
});
|
|
6172
|
-
// Update stored configuration
|
|
6173
|
-
this.registeredShortcuts.set(shortcutId, newConfig);
|
|
6174
|
-
console.log(`🔄 [AppShortcut] Updated shortcut: ${shortcutId}`);
|
|
6175
|
-
}
|
|
6176
|
-
else {
|
|
6177
|
-
console.warn(`⚠️ [AppShortcut] Shortcut not found for update: ${shortcutId}`);
|
|
6178
|
-
}
|
|
6179
|
-
}
|
|
6180
|
-
/**
|
|
6181
|
-
* Clear all app shortcuts
|
|
6182
|
-
*/
|
|
6183
|
-
clearAllShortcuts() {
|
|
6184
|
-
console.log('🧹 [AppShortcut] Clearing all app shortcuts');
|
|
6185
|
-
const shortcutIds = Array.from(this.registeredShortcuts.keys());
|
|
6186
|
-
shortcutIds.forEach(shortcutId => {
|
|
6187
|
-
this.keyboardShortcutService.unregister(shortcutId);
|
|
6188
|
-
});
|
|
6189
|
-
this.registeredShortcuts.clear();
|
|
6190
|
-
console.log('✅ [AppShortcut] All app shortcuts cleared');
|
|
6191
|
-
}
|
|
6192
|
-
/**
|
|
6193
|
-
* Get shortcut information for help/documentation
|
|
6194
|
-
*/
|
|
6195
|
-
getShortcutHelp() {
|
|
6196
|
-
return Array.from(this.registeredShortcuts.values()).map(config => ({
|
|
6197
|
-
eventName: config.eventName,
|
|
6198
|
-
description: config.description,
|
|
6199
|
-
keys: this.getKeyDescription(config)
|
|
6200
|
-
}));
|
|
6201
|
-
}
|
|
6202
|
-
/**
|
|
6203
|
-
* Execute app event (this would be implemented by the app component)
|
|
6204
|
-
* @param eventName Name of the event to execute
|
|
6205
|
-
*/
|
|
6206
|
-
executeAppEvent(eventName) {
|
|
6207
|
-
// This method should be overridden by the app component
|
|
6208
|
-
// or connected to an event emitter system
|
|
6209
|
-
console.log(`🎯 [AppShortcut] Executing app event: ${eventName}`);
|
|
6210
|
-
// Emit custom event that the app component can listen to
|
|
6211
|
-
const customEvent = new CustomEvent('app-shortcut-triggered', {
|
|
6212
|
-
detail: { eventName }
|
|
6213
|
-
});
|
|
6214
|
-
window.dispatchEvent(customEvent);
|
|
6215
|
-
}
|
|
6216
|
-
/**
|
|
6217
|
-
* Get human-readable key description
|
|
6218
|
-
*/
|
|
6219
|
-
getKeyDescription(config) {
|
|
6220
|
-
const modifiers = [];
|
|
6221
|
-
if (config.ctrlKey)
|
|
6222
|
-
modifiers.push('Ctrl');
|
|
6223
|
-
if (config.altKey)
|
|
6224
|
-
modifiers.push('Alt');
|
|
6225
|
-
if (config.shiftKey)
|
|
6226
|
-
modifiers.push('Shift');
|
|
6227
|
-
if (config.metaKey)
|
|
6228
|
-
modifiers.push('Meta');
|
|
6229
|
-
return [...modifiers, config.key].join(' + ');
|
|
6230
|
-
}
|
|
6231
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AppShortcutService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
6232
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AppShortcutService, providedIn: 'root' });
|
|
6233
|
-
}
|
|
6234
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AppShortcutService, decorators: [{
|
|
6235
|
-
type: Injectable,
|
|
6236
|
-
args: [{
|
|
6237
|
-
providedIn: 'root'
|
|
6238
|
-
}]
|
|
6239
|
-
}] });
|
|
6240
|
-
|
|
6241
5795
|
/**
|
|
6242
5796
|
<!-- Basic horizontal (left-right) layout -->
|
|
6243
5797
|
<div class="panel-container">
|
|
@@ -10339,6 +9893,7 @@ class CideEleFloatingContainerComponent {
|
|
|
10339
9893
|
isMinimized;
|
|
10340
9894
|
isMaximized;
|
|
10341
9895
|
isVisible;
|
|
9896
|
+
zIndex;
|
|
10342
9897
|
closeEvent = new EventEmitter();
|
|
10343
9898
|
minimizeEvent = new EventEmitter();
|
|
10344
9899
|
maximizeEvent = new EventEmitter();
|
|
@@ -10493,10 +10048,10 @@ class CideEleFloatingContainerComponent {
|
|
|
10493
10048
|
return 'linear-gradient(135deg, var(--cide-theme-primary-color) 0%, var(--tw-blue-400) 100%)';
|
|
10494
10049
|
}
|
|
10495
10050
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10496
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleFloatingContainerComponent, isStandalone: true, selector: "cide-ele-floating-container", inputs: { config: "config", isMinimized: "isMinimized", isMaximized: "isMaximized", isVisible: "isVisible" }, outputs: { closeEvent: "closeEvent", minimizeEvent: "minimizeEvent", maximizeEvent: "maximizeEvent", clickEvent: "clickEvent" }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: `
|
|
10051
|
+
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", zIndex: "zIndex" }, outputs: { closeEvent: "closeEvent", minimizeEvent: "minimizeEvent", maximizeEvent: "maximizeEvent", clickEvent: "clickEvent" }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: `
|
|
10497
10052
|
<div
|
|
10498
10053
|
#container
|
|
10499
|
-
class="tw-fixed tw-
|
|
10054
|
+
class="tw-fixed 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"
|
|
10500
10055
|
[style.left.px]="isMaximized() ? 20 : position().x"
|
|
10501
10056
|
[style.top.px]="isMaximized() ? 20 : position().y"
|
|
10502
10057
|
[style.width]="isMaximized() ? 'calc(100vw - 40px)' : (config().width || '400px')"
|
|
@@ -10505,6 +10060,7 @@ class CideEleFloatingContainerComponent {
|
|
|
10505
10060
|
[style.min-height]="isMinimized() ? 'auto' : (config().minHeight || '200px')"
|
|
10506
10061
|
[style.max-width]="config().maxWidth || '90vw'"
|
|
10507
10062
|
[style.max-height]="config().maxHeight || '90vh'"
|
|
10063
|
+
[style.z-index]="zIndex?.()"
|
|
10508
10064
|
[class.tw-cursor-move]="isDragging()"
|
|
10509
10065
|
[class.tw-select-none]="true"
|
|
10510
10066
|
(mousedown)="onMouseDown($event)"
|
|
@@ -10578,7 +10134,7 @@ class CideEleFloatingContainerComponent {
|
|
|
10578
10134
|
[style.height]="isMaximized() ? 'calc(100vh - 100px)' : 'auto'"
|
|
10579
10135
|
[style.min-height]="'200px'">
|
|
10580
10136
|
@defer (when !isMinimized() && isVisible()) {
|
|
10581
|
-
<div class="tw-p-
|
|
10137
|
+
<div class="tw-p-0 tw-min-h-full">
|
|
10582
10138
|
<ng-content></ng-content>
|
|
10583
10139
|
</div>
|
|
10584
10140
|
} @placeholder {
|
|
@@ -10605,7 +10161,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
|
|
|
10605
10161
|
args: [{ selector: 'cide-ele-floating-container', standalone: true, imports: [CommonModule, CideEleButtonComponent, CideIconComponent, CideSpinnerComponent], template: `
|
|
10606
10162
|
<div
|
|
10607
10163
|
#container
|
|
10608
|
-
class="tw-fixed tw-
|
|
10164
|
+
class="tw-fixed 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"
|
|
10609
10165
|
[style.left.px]="isMaximized() ? 20 : position().x"
|
|
10610
10166
|
[style.top.px]="isMaximized() ? 20 : position().y"
|
|
10611
10167
|
[style.width]="isMaximized() ? 'calc(100vw - 40px)' : (config().width || '400px')"
|
|
@@ -10614,6 +10170,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
|
|
|
10614
10170
|
[style.min-height]="isMinimized() ? 'auto' : (config().minHeight || '200px')"
|
|
10615
10171
|
[style.max-width]="config().maxWidth || '90vw'"
|
|
10616
10172
|
[style.max-height]="config().maxHeight || '90vh'"
|
|
10173
|
+
[style.z-index]="zIndex?.()"
|
|
10617
10174
|
[class.tw-cursor-move]="isDragging()"
|
|
10618
10175
|
[class.tw-select-none]="true"
|
|
10619
10176
|
(mousedown)="onMouseDown($event)"
|
|
@@ -10687,7 +10244,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
|
|
|
10687
10244
|
[style.height]="isMaximized() ? 'calc(100vh - 100px)' : 'auto'"
|
|
10688
10245
|
[style.min-height]="'200px'">
|
|
10689
10246
|
@defer (when !isMinimized() && isVisible()) {
|
|
10690
|
-
<div class="tw-p-
|
|
10247
|
+
<div class="tw-p-0 tw-min-h-full">
|
|
10691
10248
|
<ng-content></ng-content>
|
|
10692
10249
|
</div>
|
|
10693
10250
|
} @placeholder {
|
|
@@ -10716,6 +10273,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
|
|
|
10716
10273
|
type: Input
|
|
10717
10274
|
}], isVisible: [{
|
|
10718
10275
|
type: Input
|
|
10276
|
+
}], zIndex: [{
|
|
10277
|
+
type: Input
|
|
10719
10278
|
}], closeEvent: [{
|
|
10720
10279
|
type: Output
|
|
10721
10280
|
}], minimizeEvent: [{
|
|
@@ -10741,7 +10300,7 @@ class CideEleFloatingContainerManagerComponent {
|
|
|
10741
10300
|
[isMinimized]="containerService.getMinimizedSignal(container.id)"
|
|
10742
10301
|
[isMaximized]="containerService.getMaximizedSignal(container.id)"
|
|
10743
10302
|
[isVisible]="containerService.getVisibleSignal(container.id)"
|
|
10744
|
-
[
|
|
10303
|
+
[zIndex]="containerService.getZIndexSignal(container.id)"
|
|
10745
10304
|
(closeEvent)="containerService.onClose($event)"
|
|
10746
10305
|
(minimizeEvent)="containerService.onMinimize($event)"
|
|
10747
10306
|
(maximizeEvent)="containerService.onMaximize($event)"
|
|
@@ -10777,7 +10336,7 @@ class CideEleFloatingContainerManagerComponent {
|
|
|
10777
10336
|
}
|
|
10778
10337
|
</cide-ele-floating-container>
|
|
10779
10338
|
}
|
|
10780
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideEleFloatingContainerComponent, selector: "cide-ele-floating-container", inputs: ["config", "isMinimized", "isMaximized", "isVisible"], outputs: ["closeEvent", "minimizeEvent", "maximizeEvent", "clickEvent"] }, { kind: "component", type: CideSpinnerComponent, selector: "cide-ele-spinner", inputs: ["size", "type"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton]", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }], deferBlockDependencies: [() => [Promise.resolve().then(function () { return floatingContainerDynamic_directive; }).then(m => m.CideEleFloatingContainerDynamicDirective)]] });
|
|
10339
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CideEleFloatingContainerComponent, selector: "cide-ele-floating-container", inputs: ["config", "isMinimized", "isMaximized", "isVisible", "zIndex"], outputs: ["closeEvent", "minimizeEvent", "maximizeEvent", "clickEvent"] }, { kind: "component", type: CideSpinnerComponent, selector: "cide-ele-spinner", inputs: ["size", "type"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton]", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }], deferBlockDependencies: [() => [Promise.resolve().then(function () { return floatingContainerDynamic_directive; }).then(m => m.CideEleFloatingContainerDynamicDirective)]] });
|
|
10781
10340
|
}
|
|
10782
10341
|
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: [{
|
|
10783
10342
|
type: Component,
|
|
@@ -10788,7 +10347,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "20.1.7", ng
|
|
|
10788
10347
|
[isMinimized]="containerService.getMinimizedSignal(container.id)"
|
|
10789
10348
|
[isMaximized]="containerService.getMaximizedSignal(container.id)"
|
|
10790
10349
|
[isVisible]="containerService.getVisibleSignal(container.id)"
|
|
10791
|
-
[
|
|
10350
|
+
[zIndex]="containerService.getZIndexSignal(container.id)"
|
|
10792
10351
|
(closeEvent)="containerService.onClose($event)"
|
|
10793
10352
|
(minimizeEvent)="containerService.onMinimize($event)"
|
|
10794
10353
|
(maximizeEvent)="containerService.onMaximize($event)"
|
|
@@ -10827,8 +10386,294 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "20.1.7", ng
|
|
|
10827
10386
|
` }]
|
|
10828
10387
|
}], ctorParameters: null, propDecorators: null }) });
|
|
10829
10388
|
|
|
10389
|
+
class FloatingContainerShortcutsService {
|
|
10390
|
+
keyboardShortcutService = inject(KeyboardShortcutService);
|
|
10391
|
+
containerService = inject(CideEleFloatingContainerService);
|
|
10392
|
+
// Z-index layers for different container states
|
|
10393
|
+
Z_INDEX_LAYERS = {
|
|
10394
|
+
HIDDEN: 100, // Hidden containers (behind everything)
|
|
10395
|
+
BACKGROUND: 1000, // Background containers
|
|
10396
|
+
NORMAL: 2000, // Normal visible containers
|
|
10397
|
+
FOCUSED: 3000, // Focused containers
|
|
10398
|
+
MODAL: 4000, // Modal containers
|
|
10399
|
+
TOOLTIP: 5000 // Tooltips and overlays
|
|
10400
|
+
};
|
|
10401
|
+
constructor() {
|
|
10402
|
+
this.registerDefaultShortcuts();
|
|
10403
|
+
}
|
|
10404
|
+
/**
|
|
10405
|
+
* Register default floating container shortcuts
|
|
10406
|
+
*/
|
|
10407
|
+
registerDefaultShortcuts() {
|
|
10408
|
+
console.log('🎯 [FloatingContainerShortcuts] Registering default shortcuts');
|
|
10409
|
+
// Alt + 1, Alt + 2, etc. - Focus specific containers
|
|
10410
|
+
this.registerNumberShortcuts();
|
|
10411
|
+
// Alt + N - New container
|
|
10412
|
+
this.keyboardShortcutService.register({
|
|
10413
|
+
id: 'floating-container-new',
|
|
10414
|
+
key: 'n',
|
|
10415
|
+
altKey: true,
|
|
10416
|
+
description: 'Create new floating container',
|
|
10417
|
+
action: () => this.openNewContainer(),
|
|
10418
|
+
preventDefault: true
|
|
10419
|
+
});
|
|
10420
|
+
// Alt + P - Previous container
|
|
10421
|
+
this.keyboardShortcutService.register({
|
|
10422
|
+
id: 'floating-container-previous',
|
|
10423
|
+
key: 'p',
|
|
10424
|
+
altKey: true,
|
|
10425
|
+
description: 'Focus previous container',
|
|
10426
|
+
action: () => this.focusPreviousContainer(),
|
|
10427
|
+
preventDefault: true
|
|
10428
|
+
});
|
|
10429
|
+
// Alt + H - Hide all containers
|
|
10430
|
+
this.keyboardShortcutService.register({
|
|
10431
|
+
id: 'floating-container-hide-all',
|
|
10432
|
+
key: 'h',
|
|
10433
|
+
altKey: true,
|
|
10434
|
+
description: 'Hide all containers',
|
|
10435
|
+
action: () => this.hideAllContainers(),
|
|
10436
|
+
preventDefault: true
|
|
10437
|
+
});
|
|
10438
|
+
// Alt + S - Show all containers
|
|
10439
|
+
this.keyboardShortcutService.register({
|
|
10440
|
+
id: 'floating-container-show-all',
|
|
10441
|
+
key: 's',
|
|
10442
|
+
altKey: true,
|
|
10443
|
+
description: 'Show all containers',
|
|
10444
|
+
action: () => this.showAllContainers(),
|
|
10445
|
+
preventDefault: true
|
|
10446
|
+
});
|
|
10447
|
+
// Alt + M - Minimize all containers
|
|
10448
|
+
this.keyboardShortcutService.register({
|
|
10449
|
+
id: 'floating-container-minimize-all',
|
|
10450
|
+
key: 'm',
|
|
10451
|
+
altKey: true,
|
|
10452
|
+
description: 'Minimize all containers',
|
|
10453
|
+
action: () => this.minimizeAllContainers(),
|
|
10454
|
+
preventDefault: true
|
|
10455
|
+
});
|
|
10456
|
+
// Alt + W - Close current container
|
|
10457
|
+
this.keyboardShortcutService.register({
|
|
10458
|
+
id: 'floating-container-close-current',
|
|
10459
|
+
key: 'w',
|
|
10460
|
+
altKey: true,
|
|
10461
|
+
description: 'Close current container',
|
|
10462
|
+
action: () => this.closeCurrentContainer(),
|
|
10463
|
+
preventDefault: true
|
|
10464
|
+
});
|
|
10465
|
+
// Alt + D - Duplicate current container
|
|
10466
|
+
this.keyboardShortcutService.register({
|
|
10467
|
+
id: 'floating-container-duplicate',
|
|
10468
|
+
key: 'd',
|
|
10469
|
+
altKey: true,
|
|
10470
|
+
description: 'Duplicate current container',
|
|
10471
|
+
action: () => this.duplicateCurrentContainer(),
|
|
10472
|
+
preventDefault: true
|
|
10473
|
+
});
|
|
10474
|
+
// Alt + T - Toggle container visibility
|
|
10475
|
+
this.keyboardShortcutService.register({
|
|
10476
|
+
id: 'floating-container-toggle-visibility',
|
|
10477
|
+
key: 't',
|
|
10478
|
+
altKey: true,
|
|
10479
|
+
description: 'Toggle container visibility',
|
|
10480
|
+
action: () => this.toggleContainerVisibility(),
|
|
10481
|
+
preventDefault: true
|
|
10482
|
+
});
|
|
10483
|
+
// Alt + O - Open file uploader
|
|
10484
|
+
this.keyboardShortcutService.register({
|
|
10485
|
+
id: 'floating-container-open-file-uploader',
|
|
10486
|
+
key: 'o',
|
|
10487
|
+
altKey: true,
|
|
10488
|
+
description: 'Open file uploader',
|
|
10489
|
+
action: () => this.openFileUploader(),
|
|
10490
|
+
preventDefault: true
|
|
10491
|
+
});
|
|
10492
|
+
// Alt + R - Open entity rights sharing
|
|
10493
|
+
this.keyboardShortcutService.register({
|
|
10494
|
+
id: 'floating-container-open-entity-rights',
|
|
10495
|
+
key: 'r',
|
|
10496
|
+
altKey: true,
|
|
10497
|
+
description: 'Open entity rights sharing',
|
|
10498
|
+
action: () => this.openEntityRightsSharing(),
|
|
10499
|
+
preventDefault: true
|
|
10500
|
+
});
|
|
10501
|
+
console.log('✅ [FloatingContainerShortcuts] Default shortcuts registered');
|
|
10502
|
+
}
|
|
10503
|
+
/**
|
|
10504
|
+
* Register number shortcuts (Alt + 1, Alt + 2, etc.)
|
|
10505
|
+
*/
|
|
10506
|
+
registerNumberShortcuts() {
|
|
10507
|
+
for (let i = 1; i <= 9; i++) {
|
|
10508
|
+
this.keyboardShortcutService.register({
|
|
10509
|
+
id: `floating-container-focus-${i}`,
|
|
10510
|
+
key: i.toString(),
|
|
10511
|
+
altKey: true,
|
|
10512
|
+
description: `Focus container ${i}`,
|
|
10513
|
+
action: () => this.focusContainerByIndex(i - 1),
|
|
10514
|
+
preventDefault: true
|
|
10515
|
+
});
|
|
10516
|
+
}
|
|
10517
|
+
}
|
|
10518
|
+
/**
|
|
10519
|
+
* Open new floating container
|
|
10520
|
+
*/
|
|
10521
|
+
openNewContainer() {
|
|
10522
|
+
console.log('🎯 [FloatingContainerShortcuts] Opening new container');
|
|
10523
|
+
const containerId = this.containerService.show({
|
|
10524
|
+
id: 'new-container-' + Date.now(),
|
|
10525
|
+
title: 'New Container',
|
|
10526
|
+
width: '400px',
|
|
10527
|
+
height: '300px'
|
|
10528
|
+
});
|
|
10529
|
+
console.log('✅ [FloatingContainerShortcuts] New container created:', containerId);
|
|
10530
|
+
}
|
|
10531
|
+
/**
|
|
10532
|
+
* Focus previous container
|
|
10533
|
+
*/
|
|
10534
|
+
focusPreviousContainer() {
|
|
10535
|
+
console.log('🎯 [FloatingContainerShortcuts] Focusing previous container');
|
|
10536
|
+
const containers = this.containerService.visibleContainers();
|
|
10537
|
+
if (containers.length > 0) {
|
|
10538
|
+
// For now, just focus the last container
|
|
10539
|
+
const previousIndex = containers.length - 1;
|
|
10540
|
+
this.containerService.bringToFront(containers[previousIndex].id);
|
|
10541
|
+
}
|
|
10542
|
+
}
|
|
10543
|
+
/**
|
|
10544
|
+
* Hide all containers
|
|
10545
|
+
*/
|
|
10546
|
+
hideAllContainers() {
|
|
10547
|
+
console.log('🎯 [FloatingContainerShortcuts] Hiding all containers');
|
|
10548
|
+
const containers = this.containerService.visibleContainers();
|
|
10549
|
+
containers.forEach(container => {
|
|
10550
|
+
this.containerService.setZIndex(container.id, this.Z_INDEX_LAYERS.HIDDEN);
|
|
10551
|
+
});
|
|
10552
|
+
console.log('✅ [FloatingContainerShortcuts] All containers hidden');
|
|
10553
|
+
}
|
|
10554
|
+
/**
|
|
10555
|
+
* Show all containers
|
|
10556
|
+
*/
|
|
10557
|
+
showAllContainers() {
|
|
10558
|
+
console.log('🎯 [FloatingContainerShortcuts] Showing all containers');
|
|
10559
|
+
const containers = this.containerService.visibleContainers();
|
|
10560
|
+
containers.forEach((container, index) => {
|
|
10561
|
+
this.containerService.setZIndex(container.id, this.Z_INDEX_LAYERS.NORMAL + index);
|
|
10562
|
+
});
|
|
10563
|
+
console.log('✅ [FloatingContainerShortcuts] All containers shown');
|
|
10564
|
+
}
|
|
10565
|
+
/**
|
|
10566
|
+
* Minimize all containers
|
|
10567
|
+
*/
|
|
10568
|
+
minimizeAllContainers() {
|
|
10569
|
+
console.log('🎯 [FloatingContainerShortcuts] Minimizing all containers');
|
|
10570
|
+
const containers = this.containerService.visibleContainers();
|
|
10571
|
+
containers.forEach(container => {
|
|
10572
|
+
// Implement minimize logic here
|
|
10573
|
+
console.log('📦 [FloatingContainerShortcuts] Minimizing container:', container.id);
|
|
10574
|
+
});
|
|
10575
|
+
console.log('✅ [FloatingContainerShortcuts] All containers minimized');
|
|
10576
|
+
}
|
|
10577
|
+
/**
|
|
10578
|
+
* Focus container by index
|
|
10579
|
+
*/
|
|
10580
|
+
focusContainerByIndex(index) {
|
|
10581
|
+
console.log('🎯 [FloatingContainerShortcuts] Focusing container at index:', index);
|
|
10582
|
+
const containers = this.containerService.visibleContainers();
|
|
10583
|
+
if (containers[index]) {
|
|
10584
|
+
this.containerService.bringToFront(containers[index].id);
|
|
10585
|
+
console.log('✅ [FloatingContainerShortcuts] Container focused:', containers[index].id);
|
|
10586
|
+
}
|
|
10587
|
+
else {
|
|
10588
|
+
console.warn('⚠️ [FloatingContainerShortcuts] Container not found at index:', index);
|
|
10589
|
+
}
|
|
10590
|
+
}
|
|
10591
|
+
/**
|
|
10592
|
+
* Open file uploader
|
|
10593
|
+
*/
|
|
10594
|
+
openFileUploader() {
|
|
10595
|
+
console.log('🎯 [FloatingContainerShortcuts] Opening file uploader');
|
|
10596
|
+
// Implement file uploader opening logic here
|
|
10597
|
+
console.log('✅ [FloatingContainerShortcuts] File uploader opened');
|
|
10598
|
+
}
|
|
10599
|
+
/**
|
|
10600
|
+
* Open entity rights sharing
|
|
10601
|
+
*/
|
|
10602
|
+
openEntityRightsSharing() {
|
|
10603
|
+
console.log('🎯 [FloatingContainerShortcuts] Opening entity rights sharing');
|
|
10604
|
+
// Implement entity rights sharing opening logic here
|
|
10605
|
+
console.log('✅ [FloatingContainerShortcuts] Entity rights sharing opened');
|
|
10606
|
+
}
|
|
10607
|
+
/**
|
|
10608
|
+
* Duplicate current container
|
|
10609
|
+
*/
|
|
10610
|
+
duplicateCurrentContainer() {
|
|
10611
|
+
console.log('🎯 [FloatingContainerShortcuts] Duplicating current container');
|
|
10612
|
+
const containers = this.containerService.visibleContainers();
|
|
10613
|
+
if (containers.length > 0) {
|
|
10614
|
+
const containerToDuplicate = containers[containers.length - 1]; // Use last container
|
|
10615
|
+
const newContainerId = this.containerService.show({
|
|
10616
|
+
id: 'duplicate-' + Date.now(),
|
|
10617
|
+
title: `${containerToDuplicate.config.title} (Copy)`,
|
|
10618
|
+
width: containerToDuplicate.config.width,
|
|
10619
|
+
height: containerToDuplicate.config.height
|
|
10620
|
+
});
|
|
10621
|
+
console.log('✅ [FloatingContainerShortcuts] Container duplicated:', newContainerId);
|
|
10622
|
+
}
|
|
10623
|
+
else {
|
|
10624
|
+
console.warn('⚠️ [FloatingContainerShortcuts] No container to duplicate');
|
|
10625
|
+
}
|
|
10626
|
+
}
|
|
10627
|
+
/**
|
|
10628
|
+
* Close current container
|
|
10629
|
+
*/
|
|
10630
|
+
closeCurrentContainer() {
|
|
10631
|
+
console.log('🎯 [FloatingContainerShortcuts] Closing current container');
|
|
10632
|
+
const containers = this.containerService.visibleContainers();
|
|
10633
|
+
if (containers.length > 0) {
|
|
10634
|
+
const containerToClose = containers[containers.length - 1]; // Use last container
|
|
10635
|
+
this.containerService.hide(containerToClose.id);
|
|
10636
|
+
console.log('✅ [FloatingContainerShortcuts] Container closed:', containerToClose.id);
|
|
10637
|
+
}
|
|
10638
|
+
else {
|
|
10639
|
+
console.warn('⚠️ [FloatingContainerShortcuts] No container to close');
|
|
10640
|
+
}
|
|
10641
|
+
}
|
|
10642
|
+
/**
|
|
10643
|
+
* Toggle container visibility
|
|
10644
|
+
*/
|
|
10645
|
+
toggleContainerVisibility() {
|
|
10646
|
+
console.log('🎯 [FloatingContainerShortcuts] Toggling container visibility');
|
|
10647
|
+
const containers = this.containerService.visibleContainers();
|
|
10648
|
+
if (containers.length > 0) {
|
|
10649
|
+
const containerToToggle = containers[containers.length - 1]; // Use last container
|
|
10650
|
+
const currentZIndex = this.containerService.getZIndexSignal(containerToToggle.id)();
|
|
10651
|
+
if (currentZIndex === this.Z_INDEX_LAYERS.HIDDEN) {
|
|
10652
|
+
this.containerService.setZIndex(containerToToggle.id, this.Z_INDEX_LAYERS.NORMAL);
|
|
10653
|
+
console.log('✅ [FloatingContainerShortcuts] Container shown:', containerToToggle.id);
|
|
10654
|
+
}
|
|
10655
|
+
else {
|
|
10656
|
+
this.containerService.setZIndex(containerToToggle.id, this.Z_INDEX_LAYERS.HIDDEN);
|
|
10657
|
+
console.log('✅ [FloatingContainerShortcuts] Container hidden:', containerToToggle.id);
|
|
10658
|
+
}
|
|
10659
|
+
}
|
|
10660
|
+
else {
|
|
10661
|
+
console.warn('⚠️ [FloatingContainerShortcuts] No container to toggle');
|
|
10662
|
+
}
|
|
10663
|
+
}
|
|
10664
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
10665
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, providedIn: 'root' });
|
|
10666
|
+
}
|
|
10667
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, decorators: [{
|
|
10668
|
+
type: Injectable,
|
|
10669
|
+
args: [{
|
|
10670
|
+
providedIn: 'root'
|
|
10671
|
+
}]
|
|
10672
|
+
}], ctorParameters: () => [] });
|
|
10673
|
+
|
|
10830
10674
|
class CideEleFloatingFeaturesService {
|
|
10831
10675
|
containerService = inject(CideEleFloatingContainerService);
|
|
10676
|
+
shortcutsService = inject(FloatingContainerShortcutsService);
|
|
10832
10677
|
constructor() {
|
|
10833
10678
|
// File uploader is handled by its own dedicated service
|
|
10834
10679
|
// Entity rights sharing is handled by its own dedicated service
|
|
@@ -11083,5 +10928,5 @@ var floatingContainerDynamic_directive = /*#__PURE__*/Object.freeze({
|
|
|
11083
10928
|
* Generated bundle index. Do not edit.
|
|
11084
10929
|
*/
|
|
11085
10930
|
|
|
11086
|
-
export {
|
|
10931
|
+
export { CideCoreFileManagerService, CideEleButtonComponent, CideEleConfirmationModalComponent, CideEleDataGridComponent, CideEleDropdownComponent, CideEleFileImageDirective, CideEleFileInputComponent, CideEleFileManagerService, CideEleFloatingContainerComponent, CideEleFloatingContainerDynamicDirective, CideEleFloatingContainerManagerComponent, CideEleFloatingContainerService, CideEleFloatingFeaturesService, CideEleFloatingFileUploaderComponent, CideEleFloatingFileUploaderService, CideEleGlobalNotificationsComponent, CideEleJsonEditorComponent, CideEleResizerDirective, CideEleSkeletonLoaderComponent, CideEleTabComponent, CideEleToastNotificationComponent, CideElementsService, CideIconComponent, CideInputComponent, CideSelectComponent, CideSelectOptionComponent, CideSpinnerComponent, CideTextareaComponent, ConfirmationService, CoreFileManagerInsertUpdatePayload, DEFAULT_GRID_CONFIG, DropdownManagerService, FloatingContainerShortcutsService, ICoreCyfmSave, KeyboardShortcutService, MFileManager, NotificationService, TooltipDirective };
|
|
11087
10932
|
//# sourceMappingURL=cloud-ide-element.mjs.map
|