cloud-ide-element 1.0.12 → 1.0.14
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 +766 -766
- package/fesm2022/cloud-ide-element.mjs.map +1 -1
- package/index.d.ts +66 -65
- 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"',
|
|
@@ -3375,841 +3375,361 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
|
|
|
3375
3375
|
}]
|
|
3376
3376
|
}], ctorParameters: () => [] });
|
|
3377
3377
|
|
|
3378
|
-
class
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3378
|
+
class CideEleFloatingContainerService {
|
|
3379
|
+
injector;
|
|
3380
|
+
containers = signal(new Map(), ...(ngDevMode ? [{ debugName: "containers" }] : []));
|
|
3381
|
+
nextZIndex = signal(1000, ...(ngDevMode ? [{ debugName: "nextZIndex" }] : []));
|
|
3382
|
+
instanceCounter = signal(0, ...(ngDevMode ? [{ debugName: "instanceCounter" }] : []));
|
|
3383
|
+
// Dynamic component management
|
|
3384
|
+
componentRegistry = new Map();
|
|
3385
|
+
activeComponents = new Map();
|
|
3386
|
+
constructor(injector) {
|
|
3387
|
+
this.injector = injector;
|
|
3388
|
+
// Keyboard shortcuts are registered by FloatingContainerShortcutsService independently
|
|
3384
3389
|
}
|
|
3385
|
-
|
|
3386
|
-
|
|
3390
|
+
// Computed properties
|
|
3391
|
+
visibleContainers = computed(() => Array.from(this.containers().values()).filter(container => container.isVisible), ...(ngDevMode ? [{ debugName: "visibleContainers" }] : []));
|
|
3392
|
+
minimizedContainers = computed(() => Array.from(this.containers().values()).filter(container => container.isMinimized), ...(ngDevMode ? [{ debugName: "minimizedContainers" }] : []));
|
|
3393
|
+
maximizedContainers = computed(() => Array.from(this.containers().values()).filter(container => container.isMaximized), ...(ngDevMode ? [{ debugName: "maximizedContainers" }] : []));
|
|
3394
|
+
// Container management methods
|
|
3395
|
+
show(config) {
|
|
3396
|
+
const containerId = config.id || this.generateId();
|
|
3397
|
+
const instanceId = this.generateInstanceId(config.componentId || 'default');
|
|
3398
|
+
// Get the highest z-index and add 1 to bring new container to front
|
|
3399
|
+
const maxZIndex = this.getMaxZIndex();
|
|
3400
|
+
const zIndex = maxZIndex + 1;
|
|
3401
|
+
const now = new Date();
|
|
3402
|
+
const container = {
|
|
3403
|
+
id: containerId,
|
|
3404
|
+
config: { ...config, id: containerId },
|
|
3405
|
+
isVisible: true,
|
|
3406
|
+
isMinimized: false,
|
|
3407
|
+
isMaximized: false,
|
|
3408
|
+
zIndex,
|
|
3409
|
+
instanceId,
|
|
3410
|
+
componentType: config.componentId || 'default',
|
|
3411
|
+
createdAt: now,
|
|
3412
|
+
lastAccessed: now
|
|
3413
|
+
};
|
|
3414
|
+
this.containers.update(containers => {
|
|
3415
|
+
const newContainers = new Map(containers);
|
|
3416
|
+
newContainers.set(containerId, container);
|
|
3417
|
+
return newContainers;
|
|
3418
|
+
});
|
|
3419
|
+
this.nextZIndex.update(z => z + 1);
|
|
3420
|
+
return containerId;
|
|
3387
3421
|
}
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3422
|
+
hide(containerId) {
|
|
3423
|
+
this.containers.update(containers => {
|
|
3424
|
+
const newContainers = new Map(containers);
|
|
3425
|
+
const container = newContainers.get(containerId);
|
|
3426
|
+
if (container) {
|
|
3427
|
+
container.isVisible = false;
|
|
3428
|
+
newContainers.set(containerId, container);
|
|
3429
|
+
}
|
|
3430
|
+
return newContainers;
|
|
3431
|
+
});
|
|
3394
3432
|
}
|
|
3395
3433
|
/**
|
|
3396
|
-
*
|
|
3434
|
+
* Get the maximum z-index among all visible containers
|
|
3397
3435
|
*/
|
|
3398
|
-
|
|
3399
|
-
const
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3436
|
+
getMaxZIndex() {
|
|
3437
|
+
const containers = this.containers();
|
|
3438
|
+
let maxZIndex = 1000; // Base z-index
|
|
3439
|
+
for (const container of containers.values()) {
|
|
3440
|
+
if (container.isVisible && container.zIndex > maxZIndex) {
|
|
3441
|
+
maxZIndex = container.zIndex;
|
|
3442
|
+
}
|
|
3403
3443
|
}
|
|
3404
|
-
|
|
3405
|
-
shortcutId,
|
|
3406
|
-
newKey,
|
|
3407
|
-
newCtrlKey: options?.ctrlKey,
|
|
3408
|
-
newAltKey: options?.altKey,
|
|
3409
|
-
newShiftKey: options?.shiftKey,
|
|
3410
|
-
newMetaKey: options?.metaKey
|
|
3411
|
-
};
|
|
3412
|
-
this.overrides.set(shortcutId, override);
|
|
3413
|
-
console.log(`🔄 [KeyboardShortcut] Override registered for '${shortcutId}': ${this.getKeyDescription({ ...originalShortcut, ...options, key: newKey })}`);
|
|
3414
|
-
}
|
|
3415
|
-
/**
|
|
3416
|
-
* Remove a shortcut
|
|
3417
|
-
*/
|
|
3418
|
-
unregister(shortcutId) {
|
|
3419
|
-
this.shortcuts.delete(shortcutId);
|
|
3420
|
-
this.overrides.delete(shortcutId);
|
|
3421
|
-
console.log(`🗑️ [KeyboardShortcut] Removed shortcut: ${shortcutId}`);
|
|
3444
|
+
return maxZIndex;
|
|
3422
3445
|
}
|
|
3423
3446
|
/**
|
|
3424
|
-
*
|
|
3447
|
+
* Bring a container to the front (highest z-index)
|
|
3425
3448
|
*/
|
|
3426
|
-
|
|
3427
|
-
this.
|
|
3428
|
-
|
|
3449
|
+
bringToFront(containerId) {
|
|
3450
|
+
const maxZIndex = this.getMaxZIndex();
|
|
3451
|
+
const newZIndex = maxZIndex + 1;
|
|
3452
|
+
console.log(`🎯 [FloatingContainer] Bringing container '${containerId}' to front`);
|
|
3453
|
+
console.log(`🎯 [FloatingContainer] Current max z-index: ${maxZIndex}, new z-index: ${newZIndex}`);
|
|
3454
|
+
this.containers.update(containers => {
|
|
3455
|
+
const newContainers = new Map(containers);
|
|
3456
|
+
const container = newContainers.get(containerId);
|
|
3457
|
+
if (container) {
|
|
3458
|
+
const oldZIndex = container.zIndex;
|
|
3459
|
+
container.zIndex = newZIndex;
|
|
3460
|
+
container.lastAccessed = new Date();
|
|
3461
|
+
newContainers.set(containerId, container);
|
|
3462
|
+
console.log(`🎯 [FloatingContainer] Container '${containerId}' z-index updated: ${oldZIndex} → ${newZIndex}`);
|
|
3463
|
+
}
|
|
3464
|
+
else {
|
|
3465
|
+
console.warn(`⚠️ [FloatingContainer] Container '${containerId}' not found!`);
|
|
3466
|
+
}
|
|
3467
|
+
return newContainers;
|
|
3468
|
+
});
|
|
3429
3469
|
}
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3470
|
+
minimize(containerId) {
|
|
3471
|
+
this.containers.update(containers => {
|
|
3472
|
+
const newContainers = new Map(containers);
|
|
3473
|
+
const container = newContainers.get(containerId);
|
|
3474
|
+
if (container) {
|
|
3475
|
+
container.isMinimized = !container.isMinimized;
|
|
3476
|
+
newContainers.set(containerId, container);
|
|
3477
|
+
}
|
|
3478
|
+
return newContainers;
|
|
3479
|
+
});
|
|
3435
3480
|
}
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3481
|
+
maximize(containerId) {
|
|
3482
|
+
this.containers.update(containers => {
|
|
3483
|
+
const newContainers = new Map(containers);
|
|
3484
|
+
const container = newContainers.get(containerId);
|
|
3485
|
+
if (container) {
|
|
3486
|
+
container.isMaximized = !container.isMaximized;
|
|
3487
|
+
newContainers.set(containerId, container);
|
|
3488
|
+
}
|
|
3489
|
+
return newContainers;
|
|
3490
|
+
});
|
|
3442
3491
|
}
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
*/
|
|
3446
|
-
hasShortcut(shortcutId) {
|
|
3447
|
-
return this.shortcuts.has(shortcutId);
|
|
3492
|
+
getContainer(containerId) {
|
|
3493
|
+
return this.containers().get(containerId);
|
|
3448
3494
|
}
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
getShortcut(shortcutId) {
|
|
3453
|
-
return this.shortcuts.get(shortcutId);
|
|
3495
|
+
isVisible(containerId) {
|
|
3496
|
+
const container = this.getContainer(containerId);
|
|
3497
|
+
return container ? container.isVisible : false;
|
|
3454
3498
|
}
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
clearAll() {
|
|
3459
|
-
this.shortcuts.clear();
|
|
3460
|
-
this.overrides.clear();
|
|
3461
|
-
console.log(`🧹 [KeyboardShortcut] All shortcuts cleared`);
|
|
3499
|
+
isMinimized(containerId) {
|
|
3500
|
+
const container = this.getContainer(containerId);
|
|
3501
|
+
return container ? container.isMinimized : false;
|
|
3462
3502
|
}
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
setupGlobalListener() {
|
|
3467
|
-
this.keydownListener = (event) => {
|
|
3468
|
-
this.handleKeydown(event);
|
|
3469
|
-
};
|
|
3470
|
-
document.addEventListener('keydown', this.keydownListener);
|
|
3471
|
-
console.log(`🎧 [KeyboardShortcut] Global keyboard listener attached`);
|
|
3503
|
+
isMaximized(containerId) {
|
|
3504
|
+
const container = this.getContainer(containerId);
|
|
3505
|
+
return container ? container.isMaximized : false;
|
|
3472
3506
|
}
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
}
|
|
3507
|
+
hideAll() {
|
|
3508
|
+
this.containers.update(containers => {
|
|
3509
|
+
const newContainers = new Map(containers);
|
|
3510
|
+
for (const [id, container] of newContainers) {
|
|
3511
|
+
container.isVisible = false;
|
|
3512
|
+
newContainers.set(id, container);
|
|
3513
|
+
}
|
|
3514
|
+
return newContainers;
|
|
3515
|
+
});
|
|
3482
3516
|
}
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
const override = this.overrides.get(shortcutId);
|
|
3491
|
-
if (override && !this.matchesOverride(event, override)) {
|
|
3492
|
-
continue; // Skip if override doesn't match
|
|
3493
|
-
}
|
|
3494
|
-
if (shortcut.preventDefault !== false) {
|
|
3495
|
-
event.preventDefault();
|
|
3496
|
-
}
|
|
3497
|
-
if (shortcut.stopPropagation) {
|
|
3498
|
-
event.stopPropagation();
|
|
3517
|
+
minimizeAll() {
|
|
3518
|
+
this.containers.update(containers => {
|
|
3519
|
+
const newContainers = new Map(containers);
|
|
3520
|
+
for (const [id, container] of newContainers) {
|
|
3521
|
+
if (container.isVisible) {
|
|
3522
|
+
container.isMinimized = true;
|
|
3523
|
+
newContainers.set(id, container);
|
|
3499
3524
|
}
|
|
3500
|
-
console.log(`⌨️ [KeyboardShortcut] Executing shortcut: ${shortcutId}`);
|
|
3501
|
-
shortcut.action();
|
|
3502
|
-
break; // Only execute one shortcut per keydown
|
|
3503
3525
|
}
|
|
3504
|
-
|
|
3526
|
+
return newContainers;
|
|
3527
|
+
});
|
|
3505
3528
|
}
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
*/
|
|
3509
|
-
matchesShortcut(event, shortcut) {
|
|
3510
|
-
return event.key === shortcut.key &&
|
|
3511
|
-
(shortcut.ctrlKey === undefined || event.ctrlKey === shortcut.ctrlKey) &&
|
|
3512
|
-
(shortcut.altKey === undefined || event.altKey === shortcut.altKey) &&
|
|
3513
|
-
(shortcut.shiftKey === undefined || event.shiftKey === shortcut.shiftKey) &&
|
|
3514
|
-
(shortcut.metaKey === undefined || event.metaKey === shortcut.metaKey);
|
|
3529
|
+
generateId() {
|
|
3530
|
+
return `floating-container-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
3515
3531
|
}
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
return event.key === override.newKey &&
|
|
3521
|
-
(override.newCtrlKey === undefined || event.ctrlKey === override.newCtrlKey) &&
|
|
3522
|
-
(override.newAltKey === undefined || event.altKey === override.newAltKey) &&
|
|
3523
|
-
(override.newShiftKey === undefined || event.shiftKey === override.newShiftKey) &&
|
|
3524
|
-
(override.newMetaKey === undefined || event.metaKey === override.newMetaKey);
|
|
3532
|
+
generateInstanceId(componentType) {
|
|
3533
|
+
const counter = this.instanceCounter() + 1;
|
|
3534
|
+
this.instanceCounter.update(c => c + 1);
|
|
3535
|
+
return `${componentType}-instance-${counter}-${Date.now()}`;
|
|
3525
3536
|
}
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
const modifiers = [];
|
|
3531
|
-
if (shortcut.ctrlKey)
|
|
3532
|
-
modifiers.push('Ctrl');
|
|
3533
|
-
if (shortcut.altKey)
|
|
3534
|
-
modifiers.push('Alt');
|
|
3535
|
-
if (shortcut.shiftKey)
|
|
3536
|
-
modifiers.push('Shift');
|
|
3537
|
-
if (shortcut.metaKey)
|
|
3538
|
-
modifiers.push('Meta');
|
|
3539
|
-
return [...modifiers, shortcut.key].join(' + ');
|
|
3537
|
+
// Multiple instance management methods
|
|
3538
|
+
getInstancesByComponentType(componentType) {
|
|
3539
|
+
return Array.from(this.containers().values())
|
|
3540
|
+
.filter(container => container.componentType === componentType);
|
|
3540
3541
|
}
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
getKeyDescriptionForShortcut(shortcutId) {
|
|
3545
|
-
const shortcut = this.shortcuts.get(shortcutId);
|
|
3546
|
-
if (!shortcut)
|
|
3547
|
-
return 'Not found';
|
|
3548
|
-
const override = this.overrides.get(shortcutId);
|
|
3549
|
-
if (override) {
|
|
3550
|
-
return this.getKeyDescription({
|
|
3551
|
-
key: override.newKey,
|
|
3552
|
-
ctrlKey: override.newCtrlKey,
|
|
3553
|
-
altKey: override.newAltKey,
|
|
3554
|
-
shiftKey: override.newShiftKey,
|
|
3555
|
-
metaKey: override.newMetaKey
|
|
3556
|
-
});
|
|
3557
|
-
}
|
|
3558
|
-
return this.getKeyDescription(shortcut);
|
|
3542
|
+
getActiveInstancesByComponentType(componentType) {
|
|
3543
|
+
return Array.from(this.containers().values())
|
|
3544
|
+
.filter(container => container.componentType === componentType && container.isVisible);
|
|
3559
3545
|
}
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
}
|
|
3563
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: KeyboardShortcutService, decorators: [{
|
|
3564
|
-
type: Injectable,
|
|
3565
|
-
args: [{
|
|
3566
|
-
providedIn: 'root'
|
|
3567
|
-
}]
|
|
3568
|
-
}], ctorParameters: () => [] });
|
|
3569
|
-
|
|
3570
|
-
class FloatingContainerShortcutsService {
|
|
3571
|
-
keyboardShortcutService = inject(KeyboardShortcutService);
|
|
3572
|
-
containerService = inject(CideEleFloatingContainerService);
|
|
3573
|
-
// Z-index layers for different container states
|
|
3574
|
-
Z_INDEX_LAYERS = {
|
|
3575
|
-
HIDDEN: 100, // Hidden containers (behind everything)
|
|
3576
|
-
BACKGROUND: 1000, // Background containers
|
|
3577
|
-
NORMAL: 2000, // Normal visible containers
|
|
3578
|
-
FOCUSED: 3000, // Focused containers
|
|
3579
|
-
MODAL: 4000, // Modal containers
|
|
3580
|
-
TOOLTIP: 5000 // Tooltips and overlays
|
|
3581
|
-
};
|
|
3582
|
-
constructor() {
|
|
3583
|
-
this.registerDefaultShortcuts();
|
|
3546
|
+
getInstanceCount(componentType) {
|
|
3547
|
+
return this.getInstancesByComponentType(componentType).length;
|
|
3584
3548
|
}
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
this.keyboardShortcutService.register({
|
|
3594
|
-
id: 'floating-container-new',
|
|
3595
|
-
key: 'n',
|
|
3596
|
-
altKey: true,
|
|
3597
|
-
description: 'Create new floating container',
|
|
3598
|
-
action: () => this.openNewContainer(),
|
|
3599
|
-
preventDefault: true
|
|
3600
|
-
});
|
|
3601
|
-
// Alt + P - Previous container
|
|
3602
|
-
this.keyboardShortcutService.register({
|
|
3603
|
-
id: 'floating-container-previous',
|
|
3604
|
-
key: 'p',
|
|
3605
|
-
altKey: true,
|
|
3606
|
-
description: 'Focus previous container',
|
|
3607
|
-
action: () => this.focusPreviousContainer(),
|
|
3608
|
-
preventDefault: true
|
|
3609
|
-
});
|
|
3610
|
-
// Alt + H - Hide all containers
|
|
3611
|
-
this.keyboardShortcutService.register({
|
|
3612
|
-
id: 'floating-container-hide-all',
|
|
3613
|
-
key: 'h',
|
|
3614
|
-
altKey: true,
|
|
3615
|
-
description: 'Hide all containers',
|
|
3616
|
-
action: () => this.hideAllContainers(),
|
|
3617
|
-
preventDefault: true
|
|
3618
|
-
});
|
|
3619
|
-
// Alt + S - Show all containers
|
|
3620
|
-
this.keyboardShortcutService.register({
|
|
3621
|
-
id: 'floating-container-show-all',
|
|
3622
|
-
key: 's',
|
|
3623
|
-
altKey: true,
|
|
3624
|
-
description: 'Show all containers',
|
|
3625
|
-
action: () => this.showAllContainers(),
|
|
3626
|
-
preventDefault: true
|
|
3627
|
-
});
|
|
3628
|
-
// Alt + M - Minimize all containers
|
|
3629
|
-
this.keyboardShortcutService.register({
|
|
3630
|
-
id: 'floating-container-minimize-all',
|
|
3631
|
-
key: 'm',
|
|
3632
|
-
altKey: true,
|
|
3633
|
-
description: 'Minimize all containers',
|
|
3634
|
-
action: () => this.minimizeAllContainers(),
|
|
3635
|
-
preventDefault: true
|
|
3636
|
-
});
|
|
3637
|
-
// Alt + W - Close current container
|
|
3638
|
-
this.keyboardShortcutService.register({
|
|
3639
|
-
id: 'floating-container-close-current',
|
|
3640
|
-
key: 'w',
|
|
3641
|
-
altKey: true,
|
|
3642
|
-
description: 'Close current container',
|
|
3643
|
-
action: () => this.closeCurrentContainer(),
|
|
3644
|
-
preventDefault: true
|
|
3645
|
-
});
|
|
3646
|
-
// Alt + D - Duplicate current container
|
|
3647
|
-
this.keyboardShortcutService.register({
|
|
3648
|
-
id: 'floating-container-duplicate',
|
|
3649
|
-
key: 'd',
|
|
3650
|
-
altKey: true,
|
|
3651
|
-
description: 'Duplicate current container',
|
|
3652
|
-
action: () => this.duplicateCurrentContainer(),
|
|
3653
|
-
preventDefault: true
|
|
3549
|
+
getActiveInstanceCount(componentType) {
|
|
3550
|
+
return this.getActiveInstancesByComponentType(componentType).length;
|
|
3551
|
+
}
|
|
3552
|
+
// Close all instances of a component type
|
|
3553
|
+
closeAllInstancesOfType(componentType) {
|
|
3554
|
+
const instances = this.getInstancesByComponentType(componentType);
|
|
3555
|
+
instances.forEach(instance => {
|
|
3556
|
+
this.hide(instance.id);
|
|
3654
3557
|
});
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
action: () => this.toggleContainerVisibility(),
|
|
3662
|
-
preventDefault: true
|
|
3558
|
+
}
|
|
3559
|
+
// Minimize all instances of a component type
|
|
3560
|
+
minimizeAllInstancesOfType(componentType) {
|
|
3561
|
+
const instances = this.getActiveInstancesByComponentType(componentType);
|
|
3562
|
+
instances.forEach(instance => {
|
|
3563
|
+
this.minimize(instance.id);
|
|
3663
3564
|
});
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
action: () => this.openFileUploader(),
|
|
3671
|
-
preventDefault: true
|
|
3565
|
+
}
|
|
3566
|
+
// Bring all instances of a component type to front
|
|
3567
|
+
bringAllInstancesToFront(componentType) {
|
|
3568
|
+
const instances = this.getActiveInstancesByComponentType(componentType);
|
|
3569
|
+
instances.forEach(instance => {
|
|
3570
|
+
this.bringToFront(instance.id);
|
|
3672
3571
|
});
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3572
|
+
}
|
|
3573
|
+
// Get instance by unique instance ID
|
|
3574
|
+
getInstanceByInstanceId(instanceId) {
|
|
3575
|
+
return Array.from(this.containers().values())
|
|
3576
|
+
.find(container => container.instanceId === instanceId);
|
|
3577
|
+
}
|
|
3578
|
+
// Update last accessed time
|
|
3579
|
+
updateLastAccessed(containerId) {
|
|
3580
|
+
this.containers.update(containers => {
|
|
3581
|
+
const newContainers = new Map(containers);
|
|
3582
|
+
const container = newContainers.get(containerId);
|
|
3583
|
+
if (container) {
|
|
3584
|
+
container.lastAccessed = new Date();
|
|
3585
|
+
newContainers.set(containerId, container);
|
|
3586
|
+
}
|
|
3587
|
+
return newContainers;
|
|
3681
3588
|
});
|
|
3682
|
-
console.log('✅ [FloatingContainerShortcuts] Default shortcuts registered');
|
|
3683
3589
|
}
|
|
3590
|
+
// ===== DYNAMIC COMPONENT MANAGEMENT =====
|
|
3684
3591
|
/**
|
|
3685
|
-
* Register
|
|
3592
|
+
* Register a component for dynamic loading
|
|
3686
3593
|
*/
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
this.keyboardShortcutService.register({
|
|
3690
|
-
id: `floating-container-focus-${i}`,
|
|
3691
|
-
key: i.toString(),
|
|
3692
|
-
altKey: true,
|
|
3693
|
-
description: `Focus container ${i}`,
|
|
3694
|
-
action: () => this.focusContainerByIndex(i - 1),
|
|
3695
|
-
preventDefault: true
|
|
3696
|
-
});
|
|
3697
|
-
}
|
|
3594
|
+
registerComponent(componentId, componentType) {
|
|
3595
|
+
this.componentRegistry.set(componentId, componentType);
|
|
3698
3596
|
}
|
|
3699
3597
|
/**
|
|
3700
|
-
*
|
|
3598
|
+
* Unregister a component
|
|
3701
3599
|
*/
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
const containerId = this.containerService.show({
|
|
3705
|
-
id: 'new-container-' + Date.now(),
|
|
3706
|
-
title: 'New Container',
|
|
3707
|
-
width: '400px',
|
|
3708
|
-
height: '300px'
|
|
3709
|
-
});
|
|
3710
|
-
console.log('✅ [FloatingContainerShortcuts] New container created:', containerId);
|
|
3600
|
+
unregisterComponent(componentId) {
|
|
3601
|
+
this.componentRegistry.delete(componentId);
|
|
3711
3602
|
}
|
|
3712
3603
|
/**
|
|
3713
|
-
*
|
|
3604
|
+
* Get registered component type
|
|
3714
3605
|
*/
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
const containers = this.containerService.visibleContainers();
|
|
3718
|
-
if (containers.length > 0) {
|
|
3719
|
-
// For now, just focus the last container
|
|
3720
|
-
const previousIndex = containers.length - 1;
|
|
3721
|
-
this.containerService.bringToFront(containers[previousIndex].id);
|
|
3722
|
-
}
|
|
3606
|
+
getComponentType(componentId) {
|
|
3607
|
+
return this.componentRegistry.get(componentId);
|
|
3723
3608
|
}
|
|
3724
3609
|
/**
|
|
3725
|
-
*
|
|
3610
|
+
* Check if component is registered
|
|
3726
3611
|
*/
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
const containers = this.containerService.visibleContainers();
|
|
3730
|
-
containers.forEach(container => {
|
|
3731
|
-
this.containerService.setZIndex(container.id, this.Z_INDEX_LAYERS.HIDDEN);
|
|
3732
|
-
});
|
|
3733
|
-
console.log('✅ [FloatingContainerShortcuts] All containers hidden');
|
|
3612
|
+
isComponentRegistered(componentId) {
|
|
3613
|
+
return this.componentRegistry.has(componentId);
|
|
3734
3614
|
}
|
|
3735
3615
|
/**
|
|
3736
|
-
*
|
|
3616
|
+
* Get registered component IDs
|
|
3737
3617
|
*/
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
const containers = this.containerService.visibleContainers();
|
|
3741
|
-
containers.forEach((container, index) => {
|
|
3742
|
-
this.containerService.setZIndex(container.id, this.Z_INDEX_LAYERS.NORMAL + index);
|
|
3743
|
-
});
|
|
3744
|
-
console.log('✅ [FloatingContainerShortcuts] All containers shown');
|
|
3618
|
+
getRegisteredComponentIds() {
|
|
3619
|
+
return Array.from(this.componentRegistry.keys());
|
|
3745
3620
|
}
|
|
3746
3621
|
/**
|
|
3747
|
-
*
|
|
3622
|
+
* Create and load component dynamically
|
|
3748
3623
|
*/
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3624
|
+
loadComponent(componentId, viewContainer, config) {
|
|
3625
|
+
const componentType = this.componentRegistry.get(componentId);
|
|
3626
|
+
if (!componentType) {
|
|
3627
|
+
return null;
|
|
3628
|
+
}
|
|
3629
|
+
try {
|
|
3630
|
+
viewContainer.clear();
|
|
3631
|
+
const componentRef = viewContainer.createComponent(componentType, {
|
|
3632
|
+
injector: this.injector
|
|
3633
|
+
});
|
|
3634
|
+
// Set inputs if provided
|
|
3635
|
+
if (config?.inputs) {
|
|
3636
|
+
Object.keys(config.inputs).forEach(key => {
|
|
3637
|
+
if (componentRef.instance && typeof componentRef.instance === 'object' && key in componentRef.instance) {
|
|
3638
|
+
componentRef.instance[key] = config.inputs[key];
|
|
3639
|
+
}
|
|
3640
|
+
});
|
|
3641
|
+
}
|
|
3642
|
+
// Set outputs if provided
|
|
3643
|
+
if (config?.outputs) {
|
|
3644
|
+
Object.keys(config.outputs).forEach(key => {
|
|
3645
|
+
if (componentRef.instance && typeof componentRef.instance === 'object' && key in componentRef.instance) {
|
|
3646
|
+
const output = componentRef.instance[key];
|
|
3647
|
+
if (output && typeof output.subscribe === 'function') {
|
|
3648
|
+
output.subscribe(config.outputs[key]);
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
});
|
|
3652
|
+
}
|
|
3653
|
+
this.activeComponents.set(componentId, componentRef);
|
|
3654
|
+
return componentRef;
|
|
3655
|
+
}
|
|
3656
|
+
catch (error) {
|
|
3657
|
+
return null;
|
|
3658
|
+
}
|
|
3757
3659
|
}
|
|
3758
3660
|
/**
|
|
3759
|
-
*
|
|
3661
|
+
* Destroy component
|
|
3760
3662
|
*/
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
this.
|
|
3766
|
-
console.log('✅ [FloatingContainerShortcuts] Container focused:', containers[index].id);
|
|
3767
|
-
}
|
|
3768
|
-
else {
|
|
3769
|
-
console.warn('⚠️ [FloatingContainerShortcuts] Container not found at index:', index);
|
|
3663
|
+
destroyComponent(componentId) {
|
|
3664
|
+
const componentRef = this.activeComponents.get(componentId);
|
|
3665
|
+
if (componentRef) {
|
|
3666
|
+
componentRef.destroy();
|
|
3667
|
+
this.activeComponents.delete(componentId);
|
|
3770
3668
|
}
|
|
3771
3669
|
}
|
|
3772
3670
|
/**
|
|
3773
|
-
*
|
|
3671
|
+
* Get active component count
|
|
3774
3672
|
*/
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
// Implement file uploader opening logic here
|
|
3778
|
-
console.log('✅ [FloatingContainerShortcuts] File uploader opened');
|
|
3673
|
+
getActiveComponentCount() {
|
|
3674
|
+
return this.activeComponents.size;
|
|
3779
3675
|
}
|
|
3780
3676
|
/**
|
|
3781
|
-
*
|
|
3677
|
+
* Clear all active components
|
|
3782
3678
|
*/
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
console.log('✅ [FloatingContainerShortcuts] Entity rights sharing opened');
|
|
3679
|
+
clearActiveComponents() {
|
|
3680
|
+
this.activeComponents.forEach(componentRef => componentRef.destroy());
|
|
3681
|
+
this.activeComponents.clear();
|
|
3787
3682
|
}
|
|
3683
|
+
// ===== CONTAINER MANAGER FUNCTIONALITY =====
|
|
3788
3684
|
/**
|
|
3789
|
-
*
|
|
3685
|
+
* Get config signal for a container
|
|
3790
3686
|
*/
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
const containers = this.containerService.visibleContainers();
|
|
3794
|
-
if (containers.length > 0) {
|
|
3795
|
-
const containerToDuplicate = containers[containers.length - 1]; // Use last container
|
|
3796
|
-
const newContainerId = this.containerService.show({
|
|
3797
|
-
id: 'duplicate-' + Date.now(),
|
|
3798
|
-
title: `${containerToDuplicate.config.title} (Copy)`,
|
|
3799
|
-
width: containerToDuplicate.config.width,
|
|
3800
|
-
height: containerToDuplicate.config.height
|
|
3801
|
-
});
|
|
3802
|
-
console.log('✅ [FloatingContainerShortcuts] Container duplicated:', newContainerId);
|
|
3803
|
-
}
|
|
3804
|
-
else {
|
|
3805
|
-
console.warn('⚠️ [FloatingContainerShortcuts] No container to duplicate');
|
|
3806
|
-
}
|
|
3687
|
+
getConfigSignal(config) {
|
|
3688
|
+
return signal(config);
|
|
3807
3689
|
}
|
|
3808
3690
|
/**
|
|
3809
|
-
*
|
|
3691
|
+
* Get minimized signal for a container
|
|
3810
3692
|
*/
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
this.containerService.hide(containerToClose.id);
|
|
3817
|
-
console.log('✅ [FloatingContainerShortcuts] Container closed:', containerToClose.id);
|
|
3818
|
-
}
|
|
3819
|
-
else {
|
|
3820
|
-
console.warn('⚠️ [FloatingContainerShortcuts] No container to close');
|
|
3821
|
-
}
|
|
3693
|
+
getMinimizedSignal(containerId) {
|
|
3694
|
+
return computed(() => {
|
|
3695
|
+
const container = this.getContainer(containerId);
|
|
3696
|
+
return container?.isMinimized || false;
|
|
3697
|
+
});
|
|
3822
3698
|
}
|
|
3823
3699
|
/**
|
|
3824
|
-
*
|
|
3700
|
+
* Get maximized signal for a container
|
|
3825
3701
|
*/
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
const containerToToggle = containers[containers.length - 1]; // Use last container
|
|
3831
|
-
const currentZIndex = this.containerService.getZIndexSignal(containerToToggle.id)();
|
|
3832
|
-
if (currentZIndex === this.Z_INDEX_LAYERS.HIDDEN) {
|
|
3833
|
-
this.containerService.setZIndex(containerToToggle.id, this.Z_INDEX_LAYERS.NORMAL);
|
|
3834
|
-
console.log('✅ [FloatingContainerShortcuts] Container shown:', containerToToggle.id);
|
|
3835
|
-
}
|
|
3836
|
-
else {
|
|
3837
|
-
this.containerService.setZIndex(containerToToggle.id, this.Z_INDEX_LAYERS.HIDDEN);
|
|
3838
|
-
console.log('✅ [FloatingContainerShortcuts] Container hidden:', containerToToggle.id);
|
|
3839
|
-
}
|
|
3840
|
-
}
|
|
3841
|
-
else {
|
|
3842
|
-
console.warn('⚠️ [FloatingContainerShortcuts] No container to toggle');
|
|
3843
|
-
}
|
|
3844
|
-
}
|
|
3845
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3846
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, providedIn: 'root' });
|
|
3847
|
-
}
|
|
3848
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, decorators: [{
|
|
3849
|
-
type: Injectable,
|
|
3850
|
-
args: [{
|
|
3851
|
-
providedIn: 'root'
|
|
3852
|
-
}]
|
|
3853
|
-
}], ctorParameters: () => [] });
|
|
3854
|
-
|
|
3855
|
-
class CideEleFloatingContainerService {
|
|
3856
|
-
injector;
|
|
3857
|
-
shortcutsService;
|
|
3858
|
-
containers = signal(new Map(), ...(ngDevMode ? [{ debugName: "containers" }] : []));
|
|
3859
|
-
nextZIndex = signal(1000, ...(ngDevMode ? [{ debugName: "nextZIndex" }] : []));
|
|
3860
|
-
instanceCounter = signal(0, ...(ngDevMode ? [{ debugName: "instanceCounter" }] : []));
|
|
3861
|
-
// Dynamic component management
|
|
3862
|
-
componentRegistry = new Map();
|
|
3863
|
-
activeComponents = new Map();
|
|
3864
|
-
constructor(injector, shortcutsService) {
|
|
3865
|
-
this.injector = injector;
|
|
3866
|
-
this.shortcutsService = shortcutsService;
|
|
3867
|
-
// Keyboard shortcuts are automatically registered by FloatingContainerShortcutsService
|
|
3868
|
-
console.log('🎯 [FloatingContainerService] Shortcuts service injected and shortcuts registered');
|
|
3869
|
-
}
|
|
3870
|
-
// Computed properties
|
|
3871
|
-
visibleContainers = computed(() => Array.from(this.containers().values()).filter(container => container.isVisible), ...(ngDevMode ? [{ debugName: "visibleContainers" }] : []));
|
|
3872
|
-
minimizedContainers = computed(() => Array.from(this.containers().values()).filter(container => container.isMinimized), ...(ngDevMode ? [{ debugName: "minimizedContainers" }] : []));
|
|
3873
|
-
maximizedContainers = computed(() => Array.from(this.containers().values()).filter(container => container.isMaximized), ...(ngDevMode ? [{ debugName: "maximizedContainers" }] : []));
|
|
3874
|
-
// Container management methods
|
|
3875
|
-
show(config) {
|
|
3876
|
-
const containerId = config.id || this.generateId();
|
|
3877
|
-
const instanceId = this.generateInstanceId(config.componentId || 'default');
|
|
3878
|
-
// Get the highest z-index and add 1 to bring new container to front
|
|
3879
|
-
const maxZIndex = this.getMaxZIndex();
|
|
3880
|
-
const zIndex = maxZIndex + 1;
|
|
3881
|
-
const now = new Date();
|
|
3882
|
-
const container = {
|
|
3883
|
-
id: containerId,
|
|
3884
|
-
config: { ...config, id: containerId },
|
|
3885
|
-
isVisible: true,
|
|
3886
|
-
isMinimized: false,
|
|
3887
|
-
isMaximized: false,
|
|
3888
|
-
zIndex,
|
|
3889
|
-
instanceId,
|
|
3890
|
-
componentType: config.componentId || 'default',
|
|
3891
|
-
createdAt: now,
|
|
3892
|
-
lastAccessed: now
|
|
3893
|
-
};
|
|
3894
|
-
this.containers.update(containers => {
|
|
3895
|
-
const newContainers = new Map(containers);
|
|
3896
|
-
newContainers.set(containerId, container);
|
|
3897
|
-
return newContainers;
|
|
3702
|
+
getMaximizedSignal(containerId) {
|
|
3703
|
+
return computed(() => {
|
|
3704
|
+
const container = this.getContainer(containerId);
|
|
3705
|
+
return container?.isMaximized || false;
|
|
3898
3706
|
});
|
|
3899
|
-
this.nextZIndex.update(z => z + 1);
|
|
3900
|
-
return containerId;
|
|
3901
3707
|
}
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
const
|
|
3905
|
-
const
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
newContainers.set(containerId, container);
|
|
3909
|
-
}
|
|
3910
|
-
return newContainers;
|
|
3708
|
+
getZIndexSignal(containerId) {
|
|
3709
|
+
return computed(() => {
|
|
3710
|
+
const container = this.getContainer(containerId);
|
|
3711
|
+
const zIndex = container?.zIndex || 1000;
|
|
3712
|
+
console.log(`🎯 [FloatingContainer] Z-index signal for '${containerId}': ${zIndex}`);
|
|
3713
|
+
return zIndex;
|
|
3911
3714
|
});
|
|
3912
3715
|
}
|
|
3913
3716
|
/**
|
|
3914
|
-
*
|
|
3915
|
-
*/
|
|
3916
|
-
getMaxZIndex() {
|
|
3917
|
-
const containers = this.containers();
|
|
3918
|
-
let maxZIndex = 1000; // Base z-index
|
|
3919
|
-
for (const container of containers.values()) {
|
|
3920
|
-
if (container.isVisible && container.zIndex > maxZIndex) {
|
|
3921
|
-
maxZIndex = container.zIndex;
|
|
3922
|
-
}
|
|
3923
|
-
}
|
|
3924
|
-
return maxZIndex;
|
|
3925
|
-
}
|
|
3926
|
-
/**
|
|
3927
|
-
* Bring a container to the front (highest z-index)
|
|
3717
|
+
* Set z-index for a specific container
|
|
3928
3718
|
*/
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
const newZIndex = maxZIndex + 1;
|
|
3932
|
-
console.log(`🎯 [FloatingContainer] Bringing container '${containerId}' to front`);
|
|
3933
|
-
console.log(`🎯 [FloatingContainer] Current max z-index: ${maxZIndex}, new z-index: ${newZIndex}`);
|
|
3719
|
+
setZIndex(containerId, zIndex) {
|
|
3720
|
+
console.log(`🎯 [FloatingContainer] Setting z-index for '${containerId}' to ${zIndex}`);
|
|
3934
3721
|
this.containers.update(containers => {
|
|
3935
3722
|
const newContainers = new Map(containers);
|
|
3936
3723
|
const container = newContainers.get(containerId);
|
|
3937
3724
|
if (container) {
|
|
3938
3725
|
const oldZIndex = container.zIndex;
|
|
3939
|
-
container.zIndex =
|
|
3726
|
+
container.zIndex = zIndex;
|
|
3940
3727
|
container.lastAccessed = new Date();
|
|
3941
3728
|
newContainers.set(containerId, container);
|
|
3942
|
-
console.log(`🎯 [FloatingContainer] Container '${containerId}' z-index updated: ${oldZIndex} → ${
|
|
3729
|
+
console.log(`🎯 [FloatingContainer] Container '${containerId}' z-index updated: ${oldZIndex} → ${zIndex}`);
|
|
3943
3730
|
}
|
|
3944
3731
|
else {
|
|
3945
|
-
console.warn(`⚠️ [FloatingContainer] Container '${containerId}' not found!`);
|
|
3946
|
-
}
|
|
3947
|
-
return newContainers;
|
|
3948
|
-
});
|
|
3949
|
-
}
|
|
3950
|
-
minimize(containerId) {
|
|
3951
|
-
this.containers.update(containers => {
|
|
3952
|
-
const newContainers = new Map(containers);
|
|
3953
|
-
const container = newContainers.get(containerId);
|
|
3954
|
-
if (container) {
|
|
3955
|
-
container.isMinimized = !container.isMinimized;
|
|
3956
|
-
newContainers.set(containerId, container);
|
|
3957
|
-
}
|
|
3958
|
-
return newContainers;
|
|
3959
|
-
});
|
|
3960
|
-
}
|
|
3961
|
-
maximize(containerId) {
|
|
3962
|
-
this.containers.update(containers => {
|
|
3963
|
-
const newContainers = new Map(containers);
|
|
3964
|
-
const container = newContainers.get(containerId);
|
|
3965
|
-
if (container) {
|
|
3966
|
-
container.isMaximized = !container.isMaximized;
|
|
3967
|
-
newContainers.set(containerId, container);
|
|
3968
|
-
}
|
|
3969
|
-
return newContainers;
|
|
3970
|
-
});
|
|
3971
|
-
}
|
|
3972
|
-
getContainer(containerId) {
|
|
3973
|
-
return this.containers().get(containerId);
|
|
3974
|
-
}
|
|
3975
|
-
isVisible(containerId) {
|
|
3976
|
-
const container = this.getContainer(containerId);
|
|
3977
|
-
return container ? container.isVisible : false;
|
|
3978
|
-
}
|
|
3979
|
-
isMinimized(containerId) {
|
|
3980
|
-
const container = this.getContainer(containerId);
|
|
3981
|
-
return container ? container.isMinimized : false;
|
|
3982
|
-
}
|
|
3983
|
-
isMaximized(containerId) {
|
|
3984
|
-
const container = this.getContainer(containerId);
|
|
3985
|
-
return container ? container.isMaximized : false;
|
|
3986
|
-
}
|
|
3987
|
-
hideAll() {
|
|
3988
|
-
this.containers.update(containers => {
|
|
3989
|
-
const newContainers = new Map(containers);
|
|
3990
|
-
for (const [id, container] of newContainers) {
|
|
3991
|
-
container.isVisible = false;
|
|
3992
|
-
newContainers.set(id, container);
|
|
3993
|
-
}
|
|
3994
|
-
return newContainers;
|
|
3995
|
-
});
|
|
3996
|
-
}
|
|
3997
|
-
minimizeAll() {
|
|
3998
|
-
this.containers.update(containers => {
|
|
3999
|
-
const newContainers = new Map(containers);
|
|
4000
|
-
for (const [id, container] of newContainers) {
|
|
4001
|
-
if (container.isVisible) {
|
|
4002
|
-
container.isMinimized = true;
|
|
4003
|
-
newContainers.set(id, container);
|
|
4004
|
-
}
|
|
4005
|
-
}
|
|
4006
|
-
return newContainers;
|
|
4007
|
-
});
|
|
4008
|
-
}
|
|
4009
|
-
generateId() {
|
|
4010
|
-
return `floating-container-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
4011
|
-
}
|
|
4012
|
-
generateInstanceId(componentType) {
|
|
4013
|
-
const counter = this.instanceCounter() + 1;
|
|
4014
|
-
this.instanceCounter.update(c => c + 1);
|
|
4015
|
-
return `${componentType}-instance-${counter}-${Date.now()}`;
|
|
4016
|
-
}
|
|
4017
|
-
// Multiple instance management methods
|
|
4018
|
-
getInstancesByComponentType(componentType) {
|
|
4019
|
-
return Array.from(this.containers().values())
|
|
4020
|
-
.filter(container => container.componentType === componentType);
|
|
4021
|
-
}
|
|
4022
|
-
getActiveInstancesByComponentType(componentType) {
|
|
4023
|
-
return Array.from(this.containers().values())
|
|
4024
|
-
.filter(container => container.componentType === componentType && container.isVisible);
|
|
4025
|
-
}
|
|
4026
|
-
getInstanceCount(componentType) {
|
|
4027
|
-
return this.getInstancesByComponentType(componentType).length;
|
|
4028
|
-
}
|
|
4029
|
-
getActiveInstanceCount(componentType) {
|
|
4030
|
-
return this.getActiveInstancesByComponentType(componentType).length;
|
|
4031
|
-
}
|
|
4032
|
-
// Close all instances of a component type
|
|
4033
|
-
closeAllInstancesOfType(componentType) {
|
|
4034
|
-
const instances = this.getInstancesByComponentType(componentType);
|
|
4035
|
-
instances.forEach(instance => {
|
|
4036
|
-
this.hide(instance.id);
|
|
4037
|
-
});
|
|
4038
|
-
}
|
|
4039
|
-
// Minimize all instances of a component type
|
|
4040
|
-
minimizeAllInstancesOfType(componentType) {
|
|
4041
|
-
const instances = this.getActiveInstancesByComponentType(componentType);
|
|
4042
|
-
instances.forEach(instance => {
|
|
4043
|
-
this.minimize(instance.id);
|
|
4044
|
-
});
|
|
4045
|
-
}
|
|
4046
|
-
// Bring all instances of a component type to front
|
|
4047
|
-
bringAllInstancesToFront(componentType) {
|
|
4048
|
-
const instances = this.getActiveInstancesByComponentType(componentType);
|
|
4049
|
-
instances.forEach(instance => {
|
|
4050
|
-
this.bringToFront(instance.id);
|
|
4051
|
-
});
|
|
4052
|
-
}
|
|
4053
|
-
// Get instance by unique instance ID
|
|
4054
|
-
getInstanceByInstanceId(instanceId) {
|
|
4055
|
-
return Array.from(this.containers().values())
|
|
4056
|
-
.find(container => container.instanceId === instanceId);
|
|
4057
|
-
}
|
|
4058
|
-
// Update last accessed time
|
|
4059
|
-
updateLastAccessed(containerId) {
|
|
4060
|
-
this.containers.update(containers => {
|
|
4061
|
-
const newContainers = new Map(containers);
|
|
4062
|
-
const container = newContainers.get(containerId);
|
|
4063
|
-
if (container) {
|
|
4064
|
-
container.lastAccessed = new Date();
|
|
4065
|
-
newContainers.set(containerId, container);
|
|
4066
|
-
}
|
|
4067
|
-
return newContainers;
|
|
4068
|
-
});
|
|
4069
|
-
}
|
|
4070
|
-
// ===== DYNAMIC COMPONENT MANAGEMENT =====
|
|
4071
|
-
/**
|
|
4072
|
-
* Register a component for dynamic loading
|
|
4073
|
-
*/
|
|
4074
|
-
registerComponent(componentId, componentType) {
|
|
4075
|
-
this.componentRegistry.set(componentId, componentType);
|
|
4076
|
-
}
|
|
4077
|
-
/**
|
|
4078
|
-
* Unregister a component
|
|
4079
|
-
*/
|
|
4080
|
-
unregisterComponent(componentId) {
|
|
4081
|
-
this.componentRegistry.delete(componentId);
|
|
4082
|
-
}
|
|
4083
|
-
/**
|
|
4084
|
-
* Get registered component type
|
|
4085
|
-
*/
|
|
4086
|
-
getComponentType(componentId) {
|
|
4087
|
-
return this.componentRegistry.get(componentId);
|
|
4088
|
-
}
|
|
4089
|
-
/**
|
|
4090
|
-
* Check if component is registered
|
|
4091
|
-
*/
|
|
4092
|
-
isComponentRegistered(componentId) {
|
|
4093
|
-
return this.componentRegistry.has(componentId);
|
|
4094
|
-
}
|
|
4095
|
-
/**
|
|
4096
|
-
* Get registered component IDs
|
|
4097
|
-
*/
|
|
4098
|
-
getRegisteredComponentIds() {
|
|
4099
|
-
return Array.from(this.componentRegistry.keys());
|
|
4100
|
-
}
|
|
4101
|
-
/**
|
|
4102
|
-
* Create and load component dynamically
|
|
4103
|
-
*/
|
|
4104
|
-
loadComponent(componentId, viewContainer, config) {
|
|
4105
|
-
const componentType = this.componentRegistry.get(componentId);
|
|
4106
|
-
if (!componentType) {
|
|
4107
|
-
return null;
|
|
4108
|
-
}
|
|
4109
|
-
try {
|
|
4110
|
-
viewContainer.clear();
|
|
4111
|
-
const componentRef = viewContainer.createComponent(componentType, {
|
|
4112
|
-
injector: this.injector
|
|
4113
|
-
});
|
|
4114
|
-
// Set inputs if provided
|
|
4115
|
-
if (config?.inputs) {
|
|
4116
|
-
Object.keys(config.inputs).forEach(key => {
|
|
4117
|
-
if (componentRef.instance && typeof componentRef.instance === 'object' && key in componentRef.instance) {
|
|
4118
|
-
componentRef.instance[key] = config.inputs[key];
|
|
4119
|
-
}
|
|
4120
|
-
});
|
|
4121
|
-
}
|
|
4122
|
-
// Set outputs if provided
|
|
4123
|
-
if (config?.outputs) {
|
|
4124
|
-
Object.keys(config.outputs).forEach(key => {
|
|
4125
|
-
if (componentRef.instance && typeof componentRef.instance === 'object' && key in componentRef.instance) {
|
|
4126
|
-
const output = componentRef.instance[key];
|
|
4127
|
-
if (output && typeof output.subscribe === 'function') {
|
|
4128
|
-
output.subscribe(config.outputs[key]);
|
|
4129
|
-
}
|
|
4130
|
-
}
|
|
4131
|
-
});
|
|
4132
|
-
}
|
|
4133
|
-
this.activeComponents.set(componentId, componentRef);
|
|
4134
|
-
return componentRef;
|
|
4135
|
-
}
|
|
4136
|
-
catch (error) {
|
|
4137
|
-
return null;
|
|
4138
|
-
}
|
|
4139
|
-
}
|
|
4140
|
-
/**
|
|
4141
|
-
* Destroy component
|
|
4142
|
-
*/
|
|
4143
|
-
destroyComponent(componentId) {
|
|
4144
|
-
const componentRef = this.activeComponents.get(componentId);
|
|
4145
|
-
if (componentRef) {
|
|
4146
|
-
componentRef.destroy();
|
|
4147
|
-
this.activeComponents.delete(componentId);
|
|
4148
|
-
}
|
|
4149
|
-
}
|
|
4150
|
-
/**
|
|
4151
|
-
* Get active component count
|
|
4152
|
-
*/
|
|
4153
|
-
getActiveComponentCount() {
|
|
4154
|
-
return this.activeComponents.size;
|
|
4155
|
-
}
|
|
4156
|
-
/**
|
|
4157
|
-
* Clear all active components
|
|
4158
|
-
*/
|
|
4159
|
-
clearActiveComponents() {
|
|
4160
|
-
this.activeComponents.forEach(componentRef => componentRef.destroy());
|
|
4161
|
-
this.activeComponents.clear();
|
|
4162
|
-
}
|
|
4163
|
-
// ===== CONTAINER MANAGER FUNCTIONALITY =====
|
|
4164
|
-
/**
|
|
4165
|
-
* Get config signal for a container
|
|
4166
|
-
*/
|
|
4167
|
-
getConfigSignal(config) {
|
|
4168
|
-
return signal(config);
|
|
4169
|
-
}
|
|
4170
|
-
/**
|
|
4171
|
-
* Get minimized signal for a container
|
|
4172
|
-
*/
|
|
4173
|
-
getMinimizedSignal(containerId) {
|
|
4174
|
-
return computed(() => {
|
|
4175
|
-
const container = this.getContainer(containerId);
|
|
4176
|
-
return container?.isMinimized || false;
|
|
4177
|
-
});
|
|
4178
|
-
}
|
|
4179
|
-
/**
|
|
4180
|
-
* Get maximized signal for a container
|
|
4181
|
-
*/
|
|
4182
|
-
getMaximizedSignal(containerId) {
|
|
4183
|
-
return computed(() => {
|
|
4184
|
-
const container = this.getContainer(containerId);
|
|
4185
|
-
return container?.isMaximized || false;
|
|
4186
|
-
});
|
|
4187
|
-
}
|
|
4188
|
-
getZIndexSignal(containerId) {
|
|
4189
|
-
return computed(() => {
|
|
4190
|
-
const container = this.getContainer(containerId);
|
|
4191
|
-
const zIndex = container?.zIndex || 1000;
|
|
4192
|
-
console.log(`🎯 [FloatingContainer] Z-index signal for '${containerId}': ${zIndex}`);
|
|
4193
|
-
return zIndex;
|
|
4194
|
-
});
|
|
4195
|
-
}
|
|
4196
|
-
/**
|
|
4197
|
-
* Set z-index for a specific container
|
|
4198
|
-
*/
|
|
4199
|
-
setZIndex(containerId, zIndex) {
|
|
4200
|
-
console.log(`🎯 [FloatingContainer] Setting z-index for '${containerId}' to ${zIndex}`);
|
|
4201
|
-
this.containers.update(containers => {
|
|
4202
|
-
const newContainers = new Map(containers);
|
|
4203
|
-
const container = newContainers.get(containerId);
|
|
4204
|
-
if (container) {
|
|
4205
|
-
const oldZIndex = container.zIndex;
|
|
4206
|
-
container.zIndex = zIndex;
|
|
4207
|
-
container.lastAccessed = new Date();
|
|
4208
|
-
newContainers.set(containerId, container);
|
|
4209
|
-
console.log(`🎯 [FloatingContainer] Container '${containerId}' z-index updated: ${oldZIndex} → ${zIndex}`);
|
|
4210
|
-
}
|
|
4211
|
-
else {
|
|
4212
|
-
console.warn(`⚠️ [FloatingContainer] Container '${containerId}' not found for z-index update!`);
|
|
3732
|
+
console.warn(`⚠️ [FloatingContainer] Container '${containerId}' not found for z-index update!`);
|
|
4213
3733
|
}
|
|
4214
3734
|
return newContainers;
|
|
4215
3735
|
});
|
|
@@ -4254,7 +3774,7 @@ class CideEleFloatingContainerService {
|
|
|
4254
3774
|
onMaximize(containerId) {
|
|
4255
3775
|
this.maximize(containerId);
|
|
4256
3776
|
}
|
|
4257
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerService, deps: [{ token: i0.Injector }
|
|
3777
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4258
3778
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerService, providedIn: 'root' });
|
|
4259
3779
|
}
|
|
4260
3780
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingContainerService, decorators: [{
|
|
@@ -4262,7 +3782,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
|
|
|
4262
3782
|
args: [{
|
|
4263
3783
|
providedIn: 'root'
|
|
4264
3784
|
}]
|
|
4265
|
-
}], ctorParameters: () => [{ type: i0.Injector }
|
|
3785
|
+
}], ctorParameters: () => [{ type: i0.Injector }] });
|
|
4266
3786
|
|
|
4267
3787
|
class CideEleFloatingFileUploaderService {
|
|
4268
3788
|
containerService = inject(CideEleFloatingContainerService);
|
|
@@ -5468,6 +4988,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
|
|
|
5468
4988
|
class CideEleFloatingFileUploaderComponent {
|
|
5469
4989
|
destroyRef = inject(DestroyRef);
|
|
5470
4990
|
fileManagerService = inject(CideEleFileManagerService);
|
|
4991
|
+
fileInputRef;
|
|
5471
4992
|
// Input data from floating container
|
|
5472
4993
|
data = {};
|
|
5473
4994
|
// Signals for reactive state (simplified for floating container)
|
|
@@ -5863,10 +5384,8 @@ class CideEleFloatingFileUploaderComponent {
|
|
|
5863
5384
|
* Trigger file input click
|
|
5864
5385
|
*/
|
|
5865
5386
|
triggerFileInput() {
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
if (fileInput) {
|
|
5869
|
-
fileInput.click();
|
|
5387
|
+
if (this.fileInputRef?.nativeElement) {
|
|
5388
|
+
this.fileInputRef.nativeElement.click();
|
|
5870
5389
|
}
|
|
5871
5390
|
}
|
|
5872
5391
|
/**
|
|
@@ -5899,15 +5418,18 @@ class CideEleFloatingFileUploaderComponent {
|
|
|
5899
5418
|
});
|
|
5900
5419
|
}
|
|
5901
5420
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingFileUploaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5902
|
-
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=\"tw-w-full tw-h-full 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
|
|
5421
|
+
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-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\">\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 tw-max-h-[60vh] tw-overflow-y-auto tw-pr-1\">\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 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"] }] });
|
|
5903
5422
|
}
|
|
5904
5423
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleFloatingFileUploaderComponent, decorators: [{
|
|
5905
5424
|
type: Component,
|
|
5906
5425
|
args: [{ selector: 'cide-ele-floating-file-uploader', standalone: true, imports: [
|
|
5907
5426
|
CommonModule,
|
|
5908
5427
|
CideIconComponent
|
|
5909
|
-
], template: "<!-- File Uploader Content (No absolute positioning - works within floating container) -->\n@if (isVisible()) {\n<div class=\"tw-w-full tw-h-full 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
|
|
5910
|
-
}], ctorParameters: () => [], propDecorators: {
|
|
5428
|
+
], template: "<!-- File Uploader Content (No absolute positioning - works within floating container) -->\n@if (isVisible()) {\n<div class=\"tw-w-full tw-h-full 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\">\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 tw-max-h-[60vh] tw-overflow-y-auto tw-pr-1\">\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 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}" }]
|
|
5429
|
+
}], ctorParameters: () => [], propDecorators: { fileInputRef: [{
|
|
5430
|
+
type: ViewChild,
|
|
5431
|
+
args: ['fileInput']
|
|
5432
|
+
}], data: [{
|
|
5911
5433
|
type: Input
|
|
5912
5434
|
}] } });
|
|
5913
5435
|
|
|
@@ -6065,7 +5587,199 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
|
|
|
6065
5587
|
type: Output
|
|
6066
5588
|
}] } });
|
|
6067
5589
|
|
|
6068
|
-
|
|
5590
|
+
class KeyboardShortcutService {
|
|
5591
|
+
shortcuts = new Map();
|
|
5592
|
+
overrides = new Map();
|
|
5593
|
+
keydownListener;
|
|
5594
|
+
constructor() {
|
|
5595
|
+
this.setupGlobalListener();
|
|
5596
|
+
}
|
|
5597
|
+
ngOnDestroy() {
|
|
5598
|
+
this.removeGlobalListener();
|
|
5599
|
+
}
|
|
5600
|
+
/**
|
|
5601
|
+
* Register a new keyboard shortcut
|
|
5602
|
+
*/
|
|
5603
|
+
register(shortcut) {
|
|
5604
|
+
this.shortcuts.set(shortcut.id, shortcut);
|
|
5605
|
+
console.log(`⌨️ [KeyboardShortcut] Registered shortcut: ${shortcut.id} (${this.getKeyDescription(shortcut)})`);
|
|
5606
|
+
}
|
|
5607
|
+
/**
|
|
5608
|
+
* Override an existing shortcut with new key combination
|
|
5609
|
+
*/
|
|
5610
|
+
override(shortcutId, newKey, options) {
|
|
5611
|
+
const originalShortcut = this.shortcuts.get(shortcutId);
|
|
5612
|
+
if (!originalShortcut) {
|
|
5613
|
+
console.warn(`⚠️ [KeyboardShortcut] Cannot override shortcut '${shortcutId}' - not found`);
|
|
5614
|
+
return;
|
|
5615
|
+
}
|
|
5616
|
+
const override = {
|
|
5617
|
+
shortcutId,
|
|
5618
|
+
newKey,
|
|
5619
|
+
newCtrlKey: options?.ctrlKey,
|
|
5620
|
+
newAltKey: options?.altKey,
|
|
5621
|
+
newShiftKey: options?.shiftKey,
|
|
5622
|
+
newMetaKey: options?.metaKey
|
|
5623
|
+
};
|
|
5624
|
+
this.overrides.set(shortcutId, override);
|
|
5625
|
+
console.log(`🔄 [KeyboardShortcut] Override registered for '${shortcutId}': ${this.getKeyDescription({ ...originalShortcut, ...options, key: newKey })}`);
|
|
5626
|
+
}
|
|
5627
|
+
/**
|
|
5628
|
+
* Remove a shortcut
|
|
5629
|
+
*/
|
|
5630
|
+
unregister(shortcutId) {
|
|
5631
|
+
this.shortcuts.delete(shortcutId);
|
|
5632
|
+
this.overrides.delete(shortcutId);
|
|
5633
|
+
console.log(`🗑️ [KeyboardShortcut] Removed shortcut: ${shortcutId}`);
|
|
5634
|
+
}
|
|
5635
|
+
/**
|
|
5636
|
+
* Remove override for a shortcut (restore original key combination)
|
|
5637
|
+
*/
|
|
5638
|
+
removeOverride(shortcutId) {
|
|
5639
|
+
this.overrides.delete(shortcutId);
|
|
5640
|
+
console.log(`🔄 [KeyboardShortcut] Override removed for: ${shortcutId}`);
|
|
5641
|
+
}
|
|
5642
|
+
/**
|
|
5643
|
+
* Get all registered shortcuts
|
|
5644
|
+
*/
|
|
5645
|
+
getAllShortcuts() {
|
|
5646
|
+
return Array.from(this.shortcuts.values());
|
|
5647
|
+
}
|
|
5648
|
+
/**
|
|
5649
|
+
* Get shortcuts by category or filter
|
|
5650
|
+
*/
|
|
5651
|
+
getShortcuts(filter) {
|
|
5652
|
+
const shortcuts = this.getAllShortcuts();
|
|
5653
|
+
return filter ? shortcuts.filter(filter) : shortcuts;
|
|
5654
|
+
}
|
|
5655
|
+
/**
|
|
5656
|
+
* Check if a shortcut is registered
|
|
5657
|
+
*/
|
|
5658
|
+
hasShortcut(shortcutId) {
|
|
5659
|
+
return this.shortcuts.has(shortcutId);
|
|
5660
|
+
}
|
|
5661
|
+
/**
|
|
5662
|
+
* Get shortcut information
|
|
5663
|
+
*/
|
|
5664
|
+
getShortcut(shortcutId) {
|
|
5665
|
+
return this.shortcuts.get(shortcutId);
|
|
5666
|
+
}
|
|
5667
|
+
/**
|
|
5668
|
+
* Clear all shortcuts
|
|
5669
|
+
*/
|
|
5670
|
+
clearAll() {
|
|
5671
|
+
this.shortcuts.clear();
|
|
5672
|
+
this.overrides.clear();
|
|
5673
|
+
console.log(`🧹 [KeyboardShortcut] All shortcuts cleared`);
|
|
5674
|
+
}
|
|
5675
|
+
/**
|
|
5676
|
+
* Set up global keyboard listener
|
|
5677
|
+
*/
|
|
5678
|
+
setupGlobalListener() {
|
|
5679
|
+
this.keydownListener = (event) => {
|
|
5680
|
+
this.handleKeydown(event);
|
|
5681
|
+
};
|
|
5682
|
+
document.addEventListener('keydown', this.keydownListener);
|
|
5683
|
+
console.log(`🎧 [KeyboardShortcut] Global keyboard listener attached`);
|
|
5684
|
+
}
|
|
5685
|
+
/**
|
|
5686
|
+
* Remove global keyboard listener
|
|
5687
|
+
*/
|
|
5688
|
+
removeGlobalListener() {
|
|
5689
|
+
if (this.keydownListener) {
|
|
5690
|
+
document.removeEventListener('keydown', this.keydownListener);
|
|
5691
|
+
this.keydownListener = undefined;
|
|
5692
|
+
console.log(`🎧 [KeyboardShortcut] Global keyboard listener removed`);
|
|
5693
|
+
}
|
|
5694
|
+
}
|
|
5695
|
+
/**
|
|
5696
|
+
* Handle keydown events
|
|
5697
|
+
*/
|
|
5698
|
+
handleKeydown(event) {
|
|
5699
|
+
for (const [shortcutId, shortcut] of this.shortcuts) {
|
|
5700
|
+
if (this.matchesShortcut(event, shortcut)) {
|
|
5701
|
+
// Check for override
|
|
5702
|
+
const override = this.overrides.get(shortcutId);
|
|
5703
|
+
if (override && !this.matchesOverride(event, override)) {
|
|
5704
|
+
continue; // Skip if override doesn't match
|
|
5705
|
+
}
|
|
5706
|
+
if (shortcut.preventDefault !== false) {
|
|
5707
|
+
event.preventDefault();
|
|
5708
|
+
}
|
|
5709
|
+
if (shortcut.stopPropagation) {
|
|
5710
|
+
event.stopPropagation();
|
|
5711
|
+
}
|
|
5712
|
+
console.log(`⌨️ [KeyboardShortcut] Executing shortcut: ${shortcutId}`);
|
|
5713
|
+
shortcut.action();
|
|
5714
|
+
break; // Only execute one shortcut per keydown
|
|
5715
|
+
}
|
|
5716
|
+
}
|
|
5717
|
+
}
|
|
5718
|
+
/**
|
|
5719
|
+
* Check if event matches shortcut
|
|
5720
|
+
*/
|
|
5721
|
+
matchesShortcut(event, shortcut) {
|
|
5722
|
+
return event.key === shortcut.key &&
|
|
5723
|
+
(shortcut.ctrlKey === undefined || event.ctrlKey === shortcut.ctrlKey) &&
|
|
5724
|
+
(shortcut.altKey === undefined || event.altKey === shortcut.altKey) &&
|
|
5725
|
+
(shortcut.shiftKey === undefined || event.shiftKey === shortcut.shiftKey) &&
|
|
5726
|
+
(shortcut.metaKey === undefined || event.metaKey === shortcut.metaKey);
|
|
5727
|
+
}
|
|
5728
|
+
/**
|
|
5729
|
+
* Check if event matches override
|
|
5730
|
+
*/
|
|
5731
|
+
matchesOverride(event, override) {
|
|
5732
|
+
return event.key === override.newKey &&
|
|
5733
|
+
(override.newCtrlKey === undefined || event.ctrlKey === override.newCtrlKey) &&
|
|
5734
|
+
(override.newAltKey === undefined || event.altKey === override.newAltKey) &&
|
|
5735
|
+
(override.newShiftKey === undefined || event.shiftKey === override.newShiftKey) &&
|
|
5736
|
+
(override.newMetaKey === undefined || event.metaKey === override.newMetaKey);
|
|
5737
|
+
}
|
|
5738
|
+
/**
|
|
5739
|
+
* Get human-readable key description
|
|
5740
|
+
*/
|
|
5741
|
+
getKeyDescription(shortcut) {
|
|
5742
|
+
const modifiers = [];
|
|
5743
|
+
if (shortcut.ctrlKey)
|
|
5744
|
+
modifiers.push('Ctrl');
|
|
5745
|
+
if (shortcut.altKey)
|
|
5746
|
+
modifiers.push('Alt');
|
|
5747
|
+
if (shortcut.shiftKey)
|
|
5748
|
+
modifiers.push('Shift');
|
|
5749
|
+
if (shortcut.metaKey)
|
|
5750
|
+
modifiers.push('Meta');
|
|
5751
|
+
return [...modifiers, shortcut.key].join(' + ');
|
|
5752
|
+
}
|
|
5753
|
+
/**
|
|
5754
|
+
* Get key description for a shortcut ID
|
|
5755
|
+
*/
|
|
5756
|
+
getKeyDescriptionForShortcut(shortcutId) {
|
|
5757
|
+
const shortcut = this.shortcuts.get(shortcutId);
|
|
5758
|
+
if (!shortcut)
|
|
5759
|
+
return 'Not found';
|
|
5760
|
+
const override = this.overrides.get(shortcutId);
|
|
5761
|
+
if (override) {
|
|
5762
|
+
return this.getKeyDescription({
|
|
5763
|
+
key: override.newKey,
|
|
5764
|
+
ctrlKey: override.newCtrlKey,
|
|
5765
|
+
altKey: override.newAltKey,
|
|
5766
|
+
shiftKey: override.newShiftKey,
|
|
5767
|
+
metaKey: override.newMetaKey
|
|
5768
|
+
});
|
|
5769
|
+
}
|
|
5770
|
+
return this.getKeyDescription(shortcut);
|
|
5771
|
+
}
|
|
5772
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: KeyboardShortcutService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5773
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: KeyboardShortcutService, providedIn: 'root' });
|
|
5774
|
+
}
|
|
5775
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: KeyboardShortcutService, decorators: [{
|
|
5776
|
+
type: Injectable,
|
|
5777
|
+
args: [{
|
|
5778
|
+
providedIn: 'root'
|
|
5779
|
+
}]
|
|
5780
|
+
}], ctorParameters: () => [] });
|
|
5781
|
+
|
|
5782
|
+
/**
|
|
6069
5783
|
<!-- Basic horizontal (left-right) layout -->
|
|
6070
5784
|
<div class="panel-container">
|
|
6071
5785
|
<div class="left-panel">
|
|
@@ -10654,8 +10368,294 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "20.1.7", ng
|
|
|
10654
10368
|
` }]
|
|
10655
10369
|
}], ctorParameters: null, propDecorators: null }) });
|
|
10656
10370
|
|
|
10371
|
+
class FloatingContainerShortcutsService {
|
|
10372
|
+
keyboardShortcutService = inject(KeyboardShortcutService);
|
|
10373
|
+
containerService = inject(CideEleFloatingContainerService);
|
|
10374
|
+
// Z-index layers for different container states
|
|
10375
|
+
Z_INDEX_LAYERS = {
|
|
10376
|
+
HIDDEN: 100, // Hidden containers (behind everything)
|
|
10377
|
+
BACKGROUND: 1000, // Background containers
|
|
10378
|
+
NORMAL: 2000, // Normal visible containers
|
|
10379
|
+
FOCUSED: 3000, // Focused containers
|
|
10380
|
+
MODAL: 4000, // Modal containers
|
|
10381
|
+
TOOLTIP: 5000 // Tooltips and overlays
|
|
10382
|
+
};
|
|
10383
|
+
constructor() {
|
|
10384
|
+
this.registerDefaultShortcuts();
|
|
10385
|
+
}
|
|
10386
|
+
/**
|
|
10387
|
+
* Register default floating container shortcuts
|
|
10388
|
+
*/
|
|
10389
|
+
registerDefaultShortcuts() {
|
|
10390
|
+
console.log('🎯 [FloatingContainerShortcuts] Registering default shortcuts');
|
|
10391
|
+
// Alt + 1, Alt + 2, etc. - Focus specific containers
|
|
10392
|
+
this.registerNumberShortcuts();
|
|
10393
|
+
// Alt + N - New container
|
|
10394
|
+
this.keyboardShortcutService.register({
|
|
10395
|
+
id: 'floating-container-new',
|
|
10396
|
+
key: 'n',
|
|
10397
|
+
altKey: true,
|
|
10398
|
+
description: 'Create new floating container',
|
|
10399
|
+
action: () => this.openNewContainer(),
|
|
10400
|
+
preventDefault: true
|
|
10401
|
+
});
|
|
10402
|
+
// Alt + P - Previous container
|
|
10403
|
+
this.keyboardShortcutService.register({
|
|
10404
|
+
id: 'floating-container-previous',
|
|
10405
|
+
key: 'p',
|
|
10406
|
+
altKey: true,
|
|
10407
|
+
description: 'Focus previous container',
|
|
10408
|
+
action: () => this.focusPreviousContainer(),
|
|
10409
|
+
preventDefault: true
|
|
10410
|
+
});
|
|
10411
|
+
// Alt + H - Hide all containers
|
|
10412
|
+
this.keyboardShortcutService.register({
|
|
10413
|
+
id: 'floating-container-hide-all',
|
|
10414
|
+
key: 'h',
|
|
10415
|
+
altKey: true,
|
|
10416
|
+
description: 'Hide all containers',
|
|
10417
|
+
action: () => this.hideAllContainers(),
|
|
10418
|
+
preventDefault: true
|
|
10419
|
+
});
|
|
10420
|
+
// Alt + S - Show all containers
|
|
10421
|
+
this.keyboardShortcutService.register({
|
|
10422
|
+
id: 'floating-container-show-all',
|
|
10423
|
+
key: 's',
|
|
10424
|
+
altKey: true,
|
|
10425
|
+
description: 'Show all containers',
|
|
10426
|
+
action: () => this.showAllContainers(),
|
|
10427
|
+
preventDefault: true
|
|
10428
|
+
});
|
|
10429
|
+
// Alt + M - Minimize all containers
|
|
10430
|
+
this.keyboardShortcutService.register({
|
|
10431
|
+
id: 'floating-container-minimize-all',
|
|
10432
|
+
key: 'm',
|
|
10433
|
+
altKey: true,
|
|
10434
|
+
description: 'Minimize all containers',
|
|
10435
|
+
action: () => this.minimizeAllContainers(),
|
|
10436
|
+
preventDefault: true
|
|
10437
|
+
});
|
|
10438
|
+
// Alt + W - Close current container
|
|
10439
|
+
this.keyboardShortcutService.register({
|
|
10440
|
+
id: 'floating-container-close-current',
|
|
10441
|
+
key: 'w',
|
|
10442
|
+
altKey: true,
|
|
10443
|
+
description: 'Close current container',
|
|
10444
|
+
action: () => this.closeCurrentContainer(),
|
|
10445
|
+
preventDefault: true
|
|
10446
|
+
});
|
|
10447
|
+
// Alt + D - Duplicate current container
|
|
10448
|
+
this.keyboardShortcutService.register({
|
|
10449
|
+
id: 'floating-container-duplicate',
|
|
10450
|
+
key: 'd',
|
|
10451
|
+
altKey: true,
|
|
10452
|
+
description: 'Duplicate current container',
|
|
10453
|
+
action: () => this.duplicateCurrentContainer(),
|
|
10454
|
+
preventDefault: true
|
|
10455
|
+
});
|
|
10456
|
+
// Alt + T - Toggle container visibility
|
|
10457
|
+
this.keyboardShortcutService.register({
|
|
10458
|
+
id: 'floating-container-toggle-visibility',
|
|
10459
|
+
key: 't',
|
|
10460
|
+
altKey: true,
|
|
10461
|
+
description: 'Toggle container visibility',
|
|
10462
|
+
action: () => this.toggleContainerVisibility(),
|
|
10463
|
+
preventDefault: true
|
|
10464
|
+
});
|
|
10465
|
+
// Alt + O - Open file uploader
|
|
10466
|
+
this.keyboardShortcutService.register({
|
|
10467
|
+
id: 'floating-container-open-file-uploader',
|
|
10468
|
+
key: 'o',
|
|
10469
|
+
altKey: true,
|
|
10470
|
+
description: 'Open file uploader',
|
|
10471
|
+
action: () => this.openFileUploader(),
|
|
10472
|
+
preventDefault: true
|
|
10473
|
+
});
|
|
10474
|
+
// Alt + R - Open entity rights sharing
|
|
10475
|
+
this.keyboardShortcutService.register({
|
|
10476
|
+
id: 'floating-container-open-entity-rights',
|
|
10477
|
+
key: 'r',
|
|
10478
|
+
altKey: true,
|
|
10479
|
+
description: 'Open entity rights sharing',
|
|
10480
|
+
action: () => this.openEntityRightsSharing(),
|
|
10481
|
+
preventDefault: true
|
|
10482
|
+
});
|
|
10483
|
+
console.log('✅ [FloatingContainerShortcuts] Default shortcuts registered');
|
|
10484
|
+
}
|
|
10485
|
+
/**
|
|
10486
|
+
* Register number shortcuts (Alt + 1, Alt + 2, etc.)
|
|
10487
|
+
*/
|
|
10488
|
+
registerNumberShortcuts() {
|
|
10489
|
+
for (let i = 1; i <= 9; i++) {
|
|
10490
|
+
this.keyboardShortcutService.register({
|
|
10491
|
+
id: `floating-container-focus-${i}`,
|
|
10492
|
+
key: i.toString(),
|
|
10493
|
+
altKey: true,
|
|
10494
|
+
description: `Focus container ${i}`,
|
|
10495
|
+
action: () => this.focusContainerByIndex(i - 1),
|
|
10496
|
+
preventDefault: true
|
|
10497
|
+
});
|
|
10498
|
+
}
|
|
10499
|
+
}
|
|
10500
|
+
/**
|
|
10501
|
+
* Open new floating container
|
|
10502
|
+
*/
|
|
10503
|
+
openNewContainer() {
|
|
10504
|
+
console.log('🎯 [FloatingContainerShortcuts] Opening new container');
|
|
10505
|
+
const containerId = this.containerService.show({
|
|
10506
|
+
id: 'new-container-' + Date.now(),
|
|
10507
|
+
title: 'New Container',
|
|
10508
|
+
width: '400px',
|
|
10509
|
+
height: '300px'
|
|
10510
|
+
});
|
|
10511
|
+
console.log('✅ [FloatingContainerShortcuts] New container created:', containerId);
|
|
10512
|
+
}
|
|
10513
|
+
/**
|
|
10514
|
+
* Focus previous container
|
|
10515
|
+
*/
|
|
10516
|
+
focusPreviousContainer() {
|
|
10517
|
+
console.log('🎯 [FloatingContainerShortcuts] Focusing previous container');
|
|
10518
|
+
const containers = this.containerService.visibleContainers();
|
|
10519
|
+
if (containers.length > 0) {
|
|
10520
|
+
// For now, just focus the last container
|
|
10521
|
+
const previousIndex = containers.length - 1;
|
|
10522
|
+
this.containerService.bringToFront(containers[previousIndex].id);
|
|
10523
|
+
}
|
|
10524
|
+
}
|
|
10525
|
+
/**
|
|
10526
|
+
* Hide all containers
|
|
10527
|
+
*/
|
|
10528
|
+
hideAllContainers() {
|
|
10529
|
+
console.log('🎯 [FloatingContainerShortcuts] Hiding all containers');
|
|
10530
|
+
const containers = this.containerService.visibleContainers();
|
|
10531
|
+
containers.forEach(container => {
|
|
10532
|
+
this.containerService.setZIndex(container.id, this.Z_INDEX_LAYERS.HIDDEN);
|
|
10533
|
+
});
|
|
10534
|
+
console.log('✅ [FloatingContainerShortcuts] All containers hidden');
|
|
10535
|
+
}
|
|
10536
|
+
/**
|
|
10537
|
+
* Show all containers
|
|
10538
|
+
*/
|
|
10539
|
+
showAllContainers() {
|
|
10540
|
+
console.log('🎯 [FloatingContainerShortcuts] Showing all containers');
|
|
10541
|
+
const containers = this.containerService.visibleContainers();
|
|
10542
|
+
containers.forEach((container, index) => {
|
|
10543
|
+
this.containerService.setZIndex(container.id, this.Z_INDEX_LAYERS.NORMAL + index);
|
|
10544
|
+
});
|
|
10545
|
+
console.log('✅ [FloatingContainerShortcuts] All containers shown');
|
|
10546
|
+
}
|
|
10547
|
+
/**
|
|
10548
|
+
* Minimize all containers
|
|
10549
|
+
*/
|
|
10550
|
+
minimizeAllContainers() {
|
|
10551
|
+
console.log('🎯 [FloatingContainerShortcuts] Minimizing all containers');
|
|
10552
|
+
const containers = this.containerService.visibleContainers();
|
|
10553
|
+
containers.forEach(container => {
|
|
10554
|
+
// Implement minimize logic here
|
|
10555
|
+
console.log('📦 [FloatingContainerShortcuts] Minimizing container:', container.id);
|
|
10556
|
+
});
|
|
10557
|
+
console.log('✅ [FloatingContainerShortcuts] All containers minimized');
|
|
10558
|
+
}
|
|
10559
|
+
/**
|
|
10560
|
+
* Focus container by index
|
|
10561
|
+
*/
|
|
10562
|
+
focusContainerByIndex(index) {
|
|
10563
|
+
console.log('🎯 [FloatingContainerShortcuts] Focusing container at index:', index);
|
|
10564
|
+
const containers = this.containerService.visibleContainers();
|
|
10565
|
+
if (containers[index]) {
|
|
10566
|
+
this.containerService.bringToFront(containers[index].id);
|
|
10567
|
+
console.log('✅ [FloatingContainerShortcuts] Container focused:', containers[index].id);
|
|
10568
|
+
}
|
|
10569
|
+
else {
|
|
10570
|
+
console.warn('⚠️ [FloatingContainerShortcuts] Container not found at index:', index);
|
|
10571
|
+
}
|
|
10572
|
+
}
|
|
10573
|
+
/**
|
|
10574
|
+
* Open file uploader
|
|
10575
|
+
*/
|
|
10576
|
+
openFileUploader() {
|
|
10577
|
+
console.log('🎯 [FloatingContainerShortcuts] Opening file uploader');
|
|
10578
|
+
// Implement file uploader opening logic here
|
|
10579
|
+
console.log('✅ [FloatingContainerShortcuts] File uploader opened');
|
|
10580
|
+
}
|
|
10581
|
+
/**
|
|
10582
|
+
* Open entity rights sharing
|
|
10583
|
+
*/
|
|
10584
|
+
openEntityRightsSharing() {
|
|
10585
|
+
console.log('🎯 [FloatingContainerShortcuts] Opening entity rights sharing');
|
|
10586
|
+
// Implement entity rights sharing opening logic here
|
|
10587
|
+
console.log('✅ [FloatingContainerShortcuts] Entity rights sharing opened');
|
|
10588
|
+
}
|
|
10589
|
+
/**
|
|
10590
|
+
* Duplicate current container
|
|
10591
|
+
*/
|
|
10592
|
+
duplicateCurrentContainer() {
|
|
10593
|
+
console.log('🎯 [FloatingContainerShortcuts] Duplicating current container');
|
|
10594
|
+
const containers = this.containerService.visibleContainers();
|
|
10595
|
+
if (containers.length > 0) {
|
|
10596
|
+
const containerToDuplicate = containers[containers.length - 1]; // Use last container
|
|
10597
|
+
const newContainerId = this.containerService.show({
|
|
10598
|
+
id: 'duplicate-' + Date.now(),
|
|
10599
|
+
title: `${containerToDuplicate.config.title} (Copy)`,
|
|
10600
|
+
width: containerToDuplicate.config.width,
|
|
10601
|
+
height: containerToDuplicate.config.height
|
|
10602
|
+
});
|
|
10603
|
+
console.log('✅ [FloatingContainerShortcuts] Container duplicated:', newContainerId);
|
|
10604
|
+
}
|
|
10605
|
+
else {
|
|
10606
|
+
console.warn('⚠️ [FloatingContainerShortcuts] No container to duplicate');
|
|
10607
|
+
}
|
|
10608
|
+
}
|
|
10609
|
+
/**
|
|
10610
|
+
* Close current container
|
|
10611
|
+
*/
|
|
10612
|
+
closeCurrentContainer() {
|
|
10613
|
+
console.log('🎯 [FloatingContainerShortcuts] Closing current container');
|
|
10614
|
+
const containers = this.containerService.visibleContainers();
|
|
10615
|
+
if (containers.length > 0) {
|
|
10616
|
+
const containerToClose = containers[containers.length - 1]; // Use last container
|
|
10617
|
+
this.containerService.hide(containerToClose.id);
|
|
10618
|
+
console.log('✅ [FloatingContainerShortcuts] Container closed:', containerToClose.id);
|
|
10619
|
+
}
|
|
10620
|
+
else {
|
|
10621
|
+
console.warn('⚠️ [FloatingContainerShortcuts] No container to close');
|
|
10622
|
+
}
|
|
10623
|
+
}
|
|
10624
|
+
/**
|
|
10625
|
+
* Toggle container visibility
|
|
10626
|
+
*/
|
|
10627
|
+
toggleContainerVisibility() {
|
|
10628
|
+
console.log('🎯 [FloatingContainerShortcuts] Toggling container visibility');
|
|
10629
|
+
const containers = this.containerService.visibleContainers();
|
|
10630
|
+
if (containers.length > 0) {
|
|
10631
|
+
const containerToToggle = containers[containers.length - 1]; // Use last container
|
|
10632
|
+
const currentZIndex = this.containerService.getZIndexSignal(containerToToggle.id)();
|
|
10633
|
+
if (currentZIndex === this.Z_INDEX_LAYERS.HIDDEN) {
|
|
10634
|
+
this.containerService.setZIndex(containerToToggle.id, this.Z_INDEX_LAYERS.NORMAL);
|
|
10635
|
+
console.log('✅ [FloatingContainerShortcuts] Container shown:', containerToToggle.id);
|
|
10636
|
+
}
|
|
10637
|
+
else {
|
|
10638
|
+
this.containerService.setZIndex(containerToToggle.id, this.Z_INDEX_LAYERS.HIDDEN);
|
|
10639
|
+
console.log('✅ [FloatingContainerShortcuts] Container hidden:', containerToToggle.id);
|
|
10640
|
+
}
|
|
10641
|
+
}
|
|
10642
|
+
else {
|
|
10643
|
+
console.warn('⚠️ [FloatingContainerShortcuts] No container to toggle');
|
|
10644
|
+
}
|
|
10645
|
+
}
|
|
10646
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
10647
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, providedIn: 'root' });
|
|
10648
|
+
}
|
|
10649
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: FloatingContainerShortcutsService, decorators: [{
|
|
10650
|
+
type: Injectable,
|
|
10651
|
+
args: [{
|
|
10652
|
+
providedIn: 'root'
|
|
10653
|
+
}]
|
|
10654
|
+
}], ctorParameters: () => [] });
|
|
10655
|
+
|
|
10657
10656
|
class CideEleFloatingFeaturesService {
|
|
10658
10657
|
containerService = inject(CideEleFloatingContainerService);
|
|
10658
|
+
shortcutsService = inject(FloatingContainerShortcutsService);
|
|
10659
10659
|
constructor() {
|
|
10660
10660
|
// File uploader is handled by its own dedicated service
|
|
10661
10661
|
// Entity rights sharing is handled by its own dedicated service
|