@qodalis/vue-cli 2.0.0-beta.10 → 2.0.0-beta.12
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/dist/index.d.mts +79 -3
- package/dist/index.d.ts +79 -3
- package/dist/index.js +473 -104
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +474 -104
- package/dist/index.mjs.map +1 -1
- package/dist/package.json +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -275,38 +275,97 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
275
275
|
type: Function,
|
|
276
276
|
default: void 0
|
|
277
277
|
},
|
|
278
|
+
collapsed: { type: Boolean, default: void 0 },
|
|
279
|
+
hidden: { type: Boolean, default: void 0 },
|
|
280
|
+
maximized: { type: Boolean, default: void 0 },
|
|
281
|
+
activeTabId: { type: Number, default: void 0 },
|
|
282
|
+
position: { type: String, default: void 0 },
|
|
283
|
+
height: { type: Number, default: void 0 },
|
|
284
|
+
width: { type: Number, default: void 0 },
|
|
278
285
|
style: {
|
|
279
286
|
type: Object,
|
|
280
287
|
default: void 0
|
|
281
288
|
},
|
|
282
289
|
class: { type: String, default: void 0 }
|
|
283
290
|
},
|
|
284
|
-
|
|
291
|
+
emits: [
|
|
292
|
+
"update:collapsed",
|
|
293
|
+
"update:hidden",
|
|
294
|
+
"update:maximized",
|
|
295
|
+
"update:activeTabId",
|
|
296
|
+
"update:position",
|
|
297
|
+
"update:height",
|
|
298
|
+
"update:width",
|
|
299
|
+
"close",
|
|
300
|
+
"tab-added",
|
|
301
|
+
"tab-closed",
|
|
302
|
+
"pane-split",
|
|
303
|
+
"pane-closed"
|
|
304
|
+
],
|
|
305
|
+
setup(props, { expose, emit }) {
|
|
285
306
|
const config = (0, import_vue3.inject)(CliConfigKey, null);
|
|
286
|
-
const mergedOptions = (0, import_vue3.computed)(() => props.options
|
|
307
|
+
const mergedOptions = (0, import_vue3.computed)(() => props.options ? { ...config?.options, ...props.options } : config?.options);
|
|
287
308
|
const mergedModules = (0, import_vue3.computed)(() => props.modules ?? config?.modules);
|
|
288
309
|
const mergedProcessors = (0, import_vue3.computed)(() => props.processors ?? config?.processors);
|
|
289
310
|
const mergedServices = (0, import_vue3.computed)(() => props.services ?? config?.services);
|
|
290
311
|
const visible = (0, import_vue3.ref)(true);
|
|
291
|
-
const
|
|
292
|
-
const
|
|
293
|
-
const
|
|
294
|
-
const
|
|
312
|
+
const internalCollapsed = (0, import_vue3.ref)(mergedOptions.value?.isCollapsed ?? true);
|
|
313
|
+
const internalMaximized = (0, import_vue3.ref)(false);
|
|
314
|
+
const internalHeight = (0, import_vue3.ref)(600);
|
|
315
|
+
const internalWidth = (0, import_vue3.ref)(400);
|
|
295
316
|
const prevHeight = (0, import_vue3.ref)(600);
|
|
296
317
|
const prevWidth = (0, import_vue3.ref)(400);
|
|
297
318
|
const initialized = (0, import_vue3.ref)(false);
|
|
298
|
-
const
|
|
319
|
+
const internalHidden = (0, import_vue3.ref)(props.options?.isHidden ?? false);
|
|
299
320
|
let preHideCollapsed = true;
|
|
300
|
-
const
|
|
321
|
+
const internalActiveTabId = (0, import_vue3.ref)(0);
|
|
322
|
+
const internalPosition = (0, import_vue3.ref)(
|
|
323
|
+
(0, import_cli_core.loadPanelPosition)() ?? mergedOptions.value?.position ?? "bottom"
|
|
324
|
+
);
|
|
325
|
+
const resolvedCollapsed = (0, import_vue3.computed)(() => props.collapsed !== void 0 ? props.collapsed : internalCollapsed.value);
|
|
326
|
+
const resolvedHidden = (0, import_vue3.computed)(() => props.hidden !== void 0 ? props.hidden : internalHidden.value);
|
|
327
|
+
const resolvedMaximized = (0, import_vue3.computed)(() => props.maximized !== void 0 ? props.maximized : internalMaximized.value);
|
|
328
|
+
const resolvedActiveTabId = (0, import_vue3.computed)(() => props.activeTabId !== void 0 ? props.activeTabId : internalActiveTabId.value);
|
|
329
|
+
const resolvedHeight = (0, import_vue3.computed)(() => props.height !== void 0 ? props.height : internalHeight.value);
|
|
330
|
+
const resolvedWidth = (0, import_vue3.computed)(() => props.width !== void 0 ? props.width : internalWidth.value);
|
|
331
|
+
const resolvedPosition = (0, import_vue3.computed)(() => props.position !== void 0 ? props.position : internalPosition.value);
|
|
332
|
+
function updateCollapsed(value) {
|
|
333
|
+
internalCollapsed.value = value;
|
|
334
|
+
emit("update:collapsed", value);
|
|
335
|
+
}
|
|
336
|
+
function updateHidden(value) {
|
|
337
|
+
internalHidden.value = value;
|
|
338
|
+
emit("update:hidden", value);
|
|
339
|
+
}
|
|
340
|
+
function updateMaximized(value) {
|
|
341
|
+
internalMaximized.value = value;
|
|
342
|
+
emit("update:maximized", value);
|
|
343
|
+
}
|
|
344
|
+
function updateActiveTabId(value) {
|
|
345
|
+
internalActiveTabId.value = value;
|
|
346
|
+
emit("update:activeTabId", value);
|
|
347
|
+
}
|
|
348
|
+
function updateHeight(value) {
|
|
349
|
+
internalHeight.value = value;
|
|
350
|
+
emit("update:height", value);
|
|
351
|
+
}
|
|
352
|
+
function updateWidth(value) {
|
|
353
|
+
internalWidth.value = value;
|
|
354
|
+
emit("update:width", value);
|
|
355
|
+
}
|
|
356
|
+
function updatePosition(value) {
|
|
357
|
+
internalPosition.value = value;
|
|
358
|
+
(0, import_cli_core.savePanelPosition)(value);
|
|
359
|
+
emit("update:position", value);
|
|
360
|
+
}
|
|
301
361
|
const closable = (0, import_vue3.computed)(() => mergedOptions.value?.closable ?? true);
|
|
302
362
|
const resizable = (0, import_vue3.computed)(() => mergedOptions.value?.resizable ?? true);
|
|
303
|
-
const isHorizontal = (0, import_vue3.computed)(() =>
|
|
363
|
+
const isHorizontal = (0, import_vue3.computed)(() => resolvedPosition.value === "left" || resolvedPosition.value === "right");
|
|
304
364
|
const hideable = (0, import_vue3.computed)(() => mergedOptions.value?.hideable ?? true);
|
|
305
365
|
const hideAlignment = (0, import_vue3.computed)(() => mergedOptions.value?.hideAlignment ?? "center");
|
|
306
366
|
const syncTheme = (0, import_vue3.computed)(() => mergedOptions.value?.syncTheme ?? false);
|
|
307
367
|
const themeStyles = (0, import_vue3.ref)({});
|
|
308
368
|
const tabs = (0, import_vue3.ref)([]);
|
|
309
|
-
const activeTabId = (0, import_vue3.ref)(0);
|
|
310
369
|
const activePaneId = (0, import_vue3.ref)(0);
|
|
311
370
|
let nextTabId = 1;
|
|
312
371
|
let nextPaneId = 1;
|
|
@@ -327,19 +386,120 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
327
386
|
};
|
|
328
387
|
const panelResizing = (0, import_vue3.ref)(false);
|
|
329
388
|
let panelResizeState = { startY: 0, startHeight: 0, startX: 0, startWidth: 0 };
|
|
330
|
-
|
|
331
|
-
|
|
389
|
+
const statusExecutionState = (0, import_vue3.ref)("idle");
|
|
390
|
+
const statusLastCommand = (0, import_vue3.ref)(null);
|
|
391
|
+
const statusServiceCount = (0, import_vue3.ref)({ running: 0, total: 0 });
|
|
392
|
+
const statusServiceDetails = (0, import_vue3.ref)([]);
|
|
393
|
+
const statusServerState = (0, import_vue3.ref)("none");
|
|
394
|
+
const statusServerDetails = (0, import_vue3.ref)([]);
|
|
395
|
+
const statusUptime = (0, import_vue3.ref)(0);
|
|
396
|
+
const statusText = (0, import_vue3.ref)(null);
|
|
397
|
+
const servicesDropdownOpen = (0, import_vue3.ref)(false);
|
|
398
|
+
const serversDropdownOpen = (0, import_vue3.ref)(false);
|
|
399
|
+
const servicesDropdownTriggerRect = (0, import_vue3.ref)(null);
|
|
400
|
+
const serversDropdownTriggerRect = (0, import_vue3.ref)(null);
|
|
401
|
+
const formattedUptime = (0, import_vue3.computed)(() => {
|
|
402
|
+
const mins = Math.floor(statusUptime.value / 6e4);
|
|
403
|
+
if (mins < 60) return `${mins}m`;
|
|
404
|
+
const hrs = Math.floor(mins / 60);
|
|
405
|
+
return `${hrs}h${mins % 60}m`;
|
|
406
|
+
});
|
|
407
|
+
let execPollTimer;
|
|
408
|
+
let globalPollTimer;
|
|
409
|
+
function startStatusPolling() {
|
|
410
|
+
stopStatusPolling();
|
|
411
|
+
execPollTimer = setInterval(() => {
|
|
412
|
+
const tab = tabs.value.find((t) => t.id === resolvedActiveTabId.value);
|
|
413
|
+
if (!tab) return;
|
|
414
|
+
const engine = engineMap.get(tab.panes[0]?.id);
|
|
415
|
+
if (!engine) return;
|
|
416
|
+
const context = engine.getContext();
|
|
417
|
+
if (!context) return;
|
|
418
|
+
const running = !!context.isExecuting || !!context.contextProcessor;
|
|
419
|
+
statusExecutionState.value = running ? "running" : "idle";
|
|
420
|
+
const result = context.lastCommandResult;
|
|
421
|
+
statusLastCommand.value = result ? { name: result.command, success: result.success } : null;
|
|
422
|
+
const text = context.getStatusText?.();
|
|
423
|
+
statusText.value = text || null;
|
|
424
|
+
}, 300);
|
|
425
|
+
globalPollTimer = setInterval(() => {
|
|
426
|
+
const tab = tabs.value.find((t) => t.id === resolvedActiveTabId.value);
|
|
427
|
+
if (!tab) return;
|
|
428
|
+
const engine = engineMap.get(tab.panes[0]?.id);
|
|
429
|
+
if (!engine) return;
|
|
430
|
+
const context = engine.getContext();
|
|
431
|
+
if (!context) return;
|
|
432
|
+
try {
|
|
433
|
+
const services = context.backgroundServices?.list() ?? [];
|
|
434
|
+
statusServiceCount.value = { running: services.filter((s) => s.status === "running").length, total: services.length };
|
|
435
|
+
statusServiceDetails.value = services.map((s) => ({ name: s.name, status: s.status, description: s.description }));
|
|
436
|
+
} catch {
|
|
437
|
+
}
|
|
438
|
+
try {
|
|
439
|
+
const serverManager = context.services?.get?.("cli-server-manager");
|
|
440
|
+
const details = [];
|
|
441
|
+
if (serverManager?.connections?.size > 0) {
|
|
442
|
+
let anyConnected = false;
|
|
443
|
+
for (const [name, conn] of serverManager.connections) {
|
|
444
|
+
if (conn.connected) anyConnected = true;
|
|
445
|
+
details.push({
|
|
446
|
+
name,
|
|
447
|
+
url: conn.config?.url ?? "",
|
|
448
|
+
connected: !!conn.connected,
|
|
449
|
+
apiVersion: conn.connected ? conn.apiVersion : void 0,
|
|
450
|
+
commandCount: conn.connected ? conn.commands?.length : void 0
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
statusServerState.value = anyConnected ? "connected" : "disconnected";
|
|
454
|
+
} else {
|
|
455
|
+
const configuredServers = engine.options?.servers;
|
|
456
|
+
if (Array.isArray(configuredServers) && configuredServers.length > 0) {
|
|
457
|
+
for (const srv of configuredServers) {
|
|
458
|
+
if (srv.enabled === false) continue;
|
|
459
|
+
details.push({
|
|
460
|
+
name: srv.name,
|
|
461
|
+
url: srv.url ?? "",
|
|
462
|
+
connected: false
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
statusServerState.value = "disconnected";
|
|
466
|
+
} else {
|
|
467
|
+
statusServerState.value = "none";
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
statusServerDetails.value = details;
|
|
471
|
+
} catch {
|
|
472
|
+
}
|
|
473
|
+
statusUptime.value = engine.startedAt ? Date.now() - engine.startedAt : 0;
|
|
474
|
+
}, 2e3);
|
|
475
|
+
}
|
|
476
|
+
function stopStatusPolling() {
|
|
477
|
+
if (execPollTimer) {
|
|
478
|
+
clearInterval(execPollTimer);
|
|
479
|
+
execPollTimer = void 0;
|
|
480
|
+
}
|
|
481
|
+
if (globalPollTimer) {
|
|
482
|
+
clearInterval(globalPollTimer);
|
|
483
|
+
globalPollTimer = void 0;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
(0, import_vue3.watch)(initialized, (val) => {
|
|
487
|
+
if (val) startStatusPolling();
|
|
488
|
+
else stopStatusPolling();
|
|
489
|
+
});
|
|
490
|
+
function addTab(title) {
|
|
332
491
|
const tabId = nextTabId++;
|
|
333
|
-
const
|
|
334
|
-
|
|
492
|
+
const paneId = nextPaneId++;
|
|
493
|
+
tabs.value = [...tabs.value, {
|
|
335
494
|
id: tabId,
|
|
336
|
-
title: `Terminal ${tabId}`,
|
|
495
|
+
title: title ?? `Terminal ${tabId}`,
|
|
337
496
|
isEditing: false,
|
|
338
|
-
panes: [
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
activeTabId.value = tabId;
|
|
497
|
+
panes: [{ id: paneId, widthPercent: 100 }]
|
|
498
|
+
}];
|
|
499
|
+
updateActiveTabId(tabId);
|
|
342
500
|
activePaneId.value = paneId;
|
|
501
|
+
emit("tab-added", { tabId });
|
|
502
|
+
return tabId;
|
|
343
503
|
}
|
|
344
504
|
let themeObserver;
|
|
345
505
|
function syncThemeFromEngine() {
|
|
@@ -367,8 +527,9 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
367
527
|
document.removeEventListener("click", closePositionDropdown);
|
|
368
528
|
});
|
|
369
529
|
function toggle() {
|
|
370
|
-
|
|
371
|
-
|
|
530
|
+
const newVal = !resolvedCollapsed.value;
|
|
531
|
+
updateCollapsed(newVal);
|
|
532
|
+
if (!newVal && !initialized.value) {
|
|
372
533
|
initialized.value = true;
|
|
373
534
|
addTab();
|
|
374
535
|
setupThemeSync();
|
|
@@ -378,58 +539,65 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
378
539
|
const idx = tabs.value.findIndex((t) => t.id === id);
|
|
379
540
|
if (idx === -1) return;
|
|
380
541
|
tabs.value.splice(idx, 1);
|
|
542
|
+
emit("tab-closed", { tabId: id });
|
|
381
543
|
if (tabs.value.length === 0) {
|
|
382
544
|
initialized.value = false;
|
|
383
|
-
|
|
545
|
+
updateCollapsed(true);
|
|
384
546
|
return;
|
|
385
547
|
}
|
|
386
|
-
if (
|
|
548
|
+
if (resolvedActiveTabId.value === id) {
|
|
387
549
|
const newIdx = Math.min(idx, tabs.value.length - 1);
|
|
388
550
|
selectTab(tabs.value[newIdx].id);
|
|
389
551
|
}
|
|
390
552
|
}
|
|
391
553
|
function selectTab(id) {
|
|
392
|
-
|
|
554
|
+
updateActiveTabId(id);
|
|
393
555
|
const tab = tabs.value.find((t) => t.id === id);
|
|
394
556
|
if (tab && tab.panes.length > 0) {
|
|
395
557
|
activePaneId.value = tab.panes[0].id;
|
|
396
558
|
}
|
|
397
559
|
}
|
|
398
|
-
function
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
)
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
560
|
+
function splitPane(tabId) {
|
|
561
|
+
const targetTabId = tabId ?? resolvedActiveTabId.value;
|
|
562
|
+
const paneId = nextPaneId++;
|
|
563
|
+
tabs.value = tabs.value.map((t) => {
|
|
564
|
+
if (t.id !== targetTabId) return t;
|
|
565
|
+
const newPanes = [...t.panes, { id: paneId, widthPercent: 0 }];
|
|
566
|
+
const evenWidth = 100 / newPanes.length;
|
|
567
|
+
newPanes.forEach((p) => {
|
|
568
|
+
p.widthPercent = evenWidth;
|
|
569
|
+
});
|
|
570
|
+
normalizePanes(newPanes);
|
|
571
|
+
return { ...t, panes: newPanes };
|
|
410
572
|
});
|
|
411
|
-
|
|
412
|
-
|
|
573
|
+
activePaneId.value = paneId;
|
|
574
|
+
emit("pane-split", { paneId, tabId: targetTabId });
|
|
575
|
+
return paneId;
|
|
413
576
|
}
|
|
414
|
-
function closePane(
|
|
415
|
-
const tab
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
577
|
+
function closePane(paneId) {
|
|
578
|
+
for (const tab of tabs.value) {
|
|
579
|
+
const idx = tab.panes.findIndex((p) => p.id === paneId);
|
|
580
|
+
if (idx === -1) continue;
|
|
581
|
+
if (tab.panes.length <= 1) {
|
|
582
|
+
closeTab(tab.id);
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
engineMap.get(paneId)?.destroy();
|
|
586
|
+
engineMap.delete(paneId);
|
|
587
|
+
const newPanes = tab.panes.filter((p) => p.id !== paneId);
|
|
588
|
+
normalizePanes(newPanes);
|
|
589
|
+
if (activePaneId.value === paneId) {
|
|
590
|
+
activePaneId.value = newPanes[Math.min(idx, newPanes.length - 1)].id;
|
|
591
|
+
}
|
|
592
|
+
emit("pane-closed", { paneId });
|
|
593
|
+
tabs.value = tabs.value.map(
|
|
594
|
+
(t) => t.id === tab.id ? { ...t, panes: newPanes } : t
|
|
595
|
+
);
|
|
419
596
|
return;
|
|
420
597
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
const total = tab.panes.reduce((s, p) => s + p.widthPercent, 0);
|
|
425
|
-
if (total > 0)
|
|
426
|
-
tab.panes.forEach((p) => {
|
|
427
|
-
p.widthPercent = p.widthPercent / total * 100;
|
|
428
|
-
});
|
|
429
|
-
normalizePanes(tab.panes);
|
|
430
|
-
if (activePaneId.value === paneId) {
|
|
431
|
-
activePaneId.value = tab.panes[Math.min(idx, tab.panes.length - 1)].id;
|
|
432
|
-
}
|
|
598
|
+
}
|
|
599
|
+
function renameTab(tabId, title) {
|
|
600
|
+
tabs.value = tabs.value.map((t) => t.id === tabId ? { ...t, title } : t);
|
|
433
601
|
}
|
|
434
602
|
function startRename(tabId) {
|
|
435
603
|
tabs.value.forEach((t) => {
|
|
@@ -457,27 +625,27 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
457
625
|
function onPanelResizeStart(e) {
|
|
458
626
|
if (!resizable.value) return;
|
|
459
627
|
e.preventDefault();
|
|
460
|
-
if (
|
|
628
|
+
if (resolvedCollapsed.value) toggle();
|
|
461
629
|
panelResizing.value = true;
|
|
462
630
|
panelResizeState = {
|
|
463
631
|
startY: e.clientY,
|
|
464
|
-
startHeight:
|
|
632
|
+
startHeight: resolvedHeight.value,
|
|
465
633
|
startX: e.clientX,
|
|
466
|
-
startWidth:
|
|
634
|
+
startWidth: resolvedWidth.value
|
|
467
635
|
};
|
|
468
636
|
}
|
|
469
637
|
function onPanelResizeMove(e) {
|
|
470
638
|
if (!panelResizing.value) return;
|
|
471
639
|
if (isHorizontal.value) {
|
|
472
|
-
const deltaX =
|
|
640
|
+
const deltaX = resolvedPosition.value === "left" ? e.clientX - panelResizeState.startX : panelResizeState.startX - e.clientX;
|
|
473
641
|
let next = Math.max(100, panelResizeState.startWidth + deltaX);
|
|
474
642
|
if (next > window.innerWidth) next = window.innerWidth;
|
|
475
|
-
|
|
643
|
+
updateWidth(next);
|
|
476
644
|
} else {
|
|
477
|
-
const deltaY =
|
|
645
|
+
const deltaY = resolvedPosition.value === "top" ? e.clientY - panelResizeState.startY : panelResizeState.startY - e.clientY;
|
|
478
646
|
let next = Math.max(100, panelResizeState.startHeight + deltaY);
|
|
479
647
|
if (next > window.innerHeight) next = window.innerHeight;
|
|
480
|
-
|
|
648
|
+
updateHeight(next);
|
|
481
649
|
}
|
|
482
650
|
}
|
|
483
651
|
function onPanelResizeEnd() {
|
|
@@ -541,40 +709,44 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
541
709
|
(0, import_vue3.onBeforeUnmount)(() => {
|
|
542
710
|
document.removeEventListener("mousemove", onPaneResizeMove);
|
|
543
711
|
document.removeEventListener("mouseup", onPaneResizeEnd);
|
|
712
|
+
stopStatusPolling();
|
|
544
713
|
});
|
|
545
714
|
function toggleMaximize() {
|
|
546
|
-
if (!
|
|
715
|
+
if (!resolvedMaximized.value) {
|
|
547
716
|
if (isHorizontal.value) {
|
|
548
|
-
prevWidth.value =
|
|
549
|
-
|
|
717
|
+
prevWidth.value = resolvedWidth.value;
|
|
718
|
+
updateWidth(window.innerWidth);
|
|
550
719
|
} else {
|
|
551
|
-
prevHeight.value =
|
|
552
|
-
|
|
720
|
+
prevHeight.value = resolvedHeight.value;
|
|
721
|
+
updateHeight(window.innerHeight);
|
|
553
722
|
}
|
|
554
723
|
} else {
|
|
555
724
|
if (isHorizontal.value) {
|
|
556
|
-
|
|
725
|
+
updateWidth(prevWidth.value);
|
|
557
726
|
} else {
|
|
558
|
-
|
|
727
|
+
updateHeight(prevHeight.value);
|
|
559
728
|
}
|
|
560
729
|
}
|
|
561
|
-
|
|
730
|
+
updateMaximized(!resolvedMaximized.value);
|
|
562
731
|
}
|
|
563
732
|
function handleClose() {
|
|
564
733
|
visible.value = false;
|
|
734
|
+
emit("close");
|
|
565
735
|
props.onClose?.();
|
|
566
736
|
}
|
|
567
737
|
function handleHide() {
|
|
568
|
-
preHideCollapsed =
|
|
569
|
-
|
|
738
|
+
preHideCollapsed = resolvedCollapsed.value;
|
|
739
|
+
updateHidden(true);
|
|
570
740
|
}
|
|
571
741
|
function handleUnhide() {
|
|
572
|
-
|
|
573
|
-
|
|
742
|
+
updateHidden(false);
|
|
743
|
+
updateCollapsed(preHideCollapsed);
|
|
574
744
|
}
|
|
575
745
|
const positionDropdownOpen = (0, import_vue3.ref)(false);
|
|
576
746
|
function closePositionDropdown() {
|
|
577
747
|
positionDropdownOpen.value = false;
|
|
748
|
+
servicesDropdownOpen.value = false;
|
|
749
|
+
serversDropdownOpen.value = false;
|
|
578
750
|
}
|
|
579
751
|
function togglePositionDropdown(e) {
|
|
580
752
|
e.stopPropagation();
|
|
@@ -582,21 +754,106 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
582
754
|
}
|
|
583
755
|
function selectPosition(pos) {
|
|
584
756
|
positionDropdownOpen.value = false;
|
|
585
|
-
|
|
586
|
-
(0, import_cli_core.savePanelPosition)(pos);
|
|
757
|
+
updatePosition(pos);
|
|
587
758
|
}
|
|
759
|
+
function getEngine(paneId) {
|
|
760
|
+
const targetId = paneId ?? activePaneId.value;
|
|
761
|
+
return engineMap.get(targetId);
|
|
762
|
+
}
|
|
763
|
+
function getState() {
|
|
764
|
+
return {
|
|
765
|
+
collapsed: resolvedCollapsed.value,
|
|
766
|
+
hidden: resolvedHidden.value,
|
|
767
|
+
maximized: resolvedMaximized.value,
|
|
768
|
+
position: resolvedPosition.value,
|
|
769
|
+
height: resolvedHeight.value,
|
|
770
|
+
width: resolvedWidth.value,
|
|
771
|
+
activeTabId: resolvedActiveTabId.value,
|
|
772
|
+
activePaneId: activePaneId.value,
|
|
773
|
+
tabs: tabs.value.map((t) => ({
|
|
774
|
+
id: t.id,
|
|
775
|
+
title: t.title,
|
|
776
|
+
panes: t.panes.map((p) => ({ id: p.id, widthPercent: p.widthPercent }))
|
|
777
|
+
}))
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
expose({
|
|
781
|
+
open: () => {
|
|
782
|
+
if (!visible.value) {
|
|
783
|
+
visible.value = true;
|
|
784
|
+
}
|
|
785
|
+
if (resolvedHidden.value) {
|
|
786
|
+
updateHidden(false);
|
|
787
|
+
}
|
|
788
|
+
if (resolvedCollapsed.value) {
|
|
789
|
+
updateCollapsed(false);
|
|
790
|
+
if (!initialized.value) {
|
|
791
|
+
initialized.value = true;
|
|
792
|
+
addTab();
|
|
793
|
+
setupThemeSync();
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
},
|
|
797
|
+
collapse: () => {
|
|
798
|
+
if (!resolvedCollapsed.value) updateCollapsed(true);
|
|
799
|
+
},
|
|
800
|
+
toggleCollapse: () => {
|
|
801
|
+
if (resolvedCollapsed.value) {
|
|
802
|
+
updateCollapsed(false);
|
|
803
|
+
if (!initialized.value) {
|
|
804
|
+
initialized.value = true;
|
|
805
|
+
addTab();
|
|
806
|
+
setupThemeSync();
|
|
807
|
+
}
|
|
808
|
+
} else {
|
|
809
|
+
updateCollapsed(true);
|
|
810
|
+
}
|
|
811
|
+
},
|
|
812
|
+
hide: () => {
|
|
813
|
+
if (!resolvedHidden.value) updateHidden(true);
|
|
814
|
+
},
|
|
815
|
+
unhide: () => {
|
|
816
|
+
if (resolvedHidden.value) updateHidden(false);
|
|
817
|
+
},
|
|
818
|
+
toggleHide: () => {
|
|
819
|
+
updateHidden(!resolvedHidden.value);
|
|
820
|
+
},
|
|
821
|
+
close: handleClose,
|
|
822
|
+
maximize: () => {
|
|
823
|
+
if (!resolvedMaximized.value) updateMaximized(true);
|
|
824
|
+
},
|
|
825
|
+
restore: () => {
|
|
826
|
+
if (resolvedMaximized.value) updateMaximized(false);
|
|
827
|
+
},
|
|
828
|
+
toggleMaximize: () => {
|
|
829
|
+
updateMaximized(!resolvedMaximized.value);
|
|
830
|
+
},
|
|
831
|
+
resize: (dims) => {
|
|
832
|
+
if (dims.height !== void 0) updateHeight(dims.height);
|
|
833
|
+
if (dims.width !== void 0) updateWidth(dims.width);
|
|
834
|
+
},
|
|
835
|
+
setPosition: updatePosition,
|
|
836
|
+
addTab,
|
|
837
|
+
closeTab,
|
|
838
|
+
selectTab,
|
|
839
|
+
renameTab,
|
|
840
|
+
splitPane,
|
|
841
|
+
closePane,
|
|
842
|
+
getEngine,
|
|
843
|
+
getState
|
|
844
|
+
});
|
|
588
845
|
return () => {
|
|
589
846
|
if (!visible.value) return null;
|
|
590
847
|
const wrapperClass = [
|
|
591
848
|
"cli-panel-wrapper",
|
|
592
|
-
|
|
593
|
-
|
|
849
|
+
resolvedCollapsed.value && "collapsed",
|
|
850
|
+
resolvedMaximized.value && "maximized",
|
|
594
851
|
panelResizing.value && "resizing",
|
|
595
852
|
props.class
|
|
596
853
|
].filter(Boolean).join(" ");
|
|
597
854
|
const wrapperStyle = {
|
|
598
|
-
...isHorizontal.value ? { width: `${
|
|
599
|
-
...
|
|
855
|
+
...isHorizontal.value ? { width: `${resolvedWidth.value}px` } : { height: `${resolvedHeight.value}px` },
|
|
856
|
+
...resolvedHidden.value ? { display: "none" } : {},
|
|
600
857
|
...themeStyles.value,
|
|
601
858
|
...props.style
|
|
602
859
|
};
|
|
@@ -616,6 +873,54 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
616
873
|
]),
|
|
617
874
|
"CLI"
|
|
618
875
|
]),
|
|
876
|
+
// Status indicators (bottom/top only)
|
|
877
|
+
resolvedPosition.value === "bottom" || resolvedPosition.value === "top" ? (0, import_vue3.h)("div", { class: "cli-panel-status-indicators" }, [
|
|
878
|
+
// Execution state
|
|
879
|
+
(0, import_vue3.h)("span", { class: ["cli-panel-status-item", statusExecutionState.value === "running" ? "status-running" : ""].filter(Boolean).join(" ") }, [
|
|
880
|
+
(0, import_vue3.h)("span", { class: ["cli-panel-status-dot", statusExecutionState.value === "running" ? "dot-running" : "dot-idle"].join(" ") }),
|
|
881
|
+
(0, import_vue3.h)("span", { class: "cli-panel-status-label" }, statusExecutionState.value)
|
|
882
|
+
]),
|
|
883
|
+
// Background services
|
|
884
|
+
statusServiceCount.value.total > 0 ? (0, import_vue3.h)("span", {
|
|
885
|
+
class: "cli-panel-status-item status-clickable",
|
|
886
|
+
onClick: (e) => {
|
|
887
|
+
e.stopPropagation();
|
|
888
|
+
servicesDropdownTriggerRect.value = e.currentTarget.getBoundingClientRect();
|
|
889
|
+
servicesDropdownOpen.value = !servicesDropdownOpen.value;
|
|
890
|
+
serversDropdownOpen.value = false;
|
|
891
|
+
}
|
|
892
|
+
}, [
|
|
893
|
+
(0, import_vue3.h)("span", { class: "cli-panel-status-icon", innerHTML: "⚙" }),
|
|
894
|
+
(0, import_vue3.h)("span", { class: "cli-panel-status-label" }, `${statusServiceCount.value.running}/${statusServiceCount.value.total} services`)
|
|
895
|
+
]) : null,
|
|
896
|
+
// Last command
|
|
897
|
+
statusLastCommand.value ? (0, import_vue3.h)("span", { class: "cli-panel-status-item" }, [
|
|
898
|
+
(0, import_vue3.h)("span", { class: ["cli-panel-status-icon", statusLastCommand.value.success ? "status-success" : "status-error"].join(" "), innerHTML: statusLastCommand.value.success ? "✓" : "✕" }),
|
|
899
|
+
(0, import_vue3.h)("span", { class: "cli-panel-status-label" }, statusLastCommand.value.name)
|
|
900
|
+
]) : null,
|
|
901
|
+
// Server connection
|
|
902
|
+
statusServerState.value !== "none" ? (0, import_vue3.h)("span", {
|
|
903
|
+
class: "cli-panel-status-item status-clickable",
|
|
904
|
+
onClick: (e) => {
|
|
905
|
+
e.stopPropagation();
|
|
906
|
+
serversDropdownTriggerRect.value = e.currentTarget.getBoundingClientRect();
|
|
907
|
+
serversDropdownOpen.value = !serversDropdownOpen.value;
|
|
908
|
+
servicesDropdownOpen.value = false;
|
|
909
|
+
}
|
|
910
|
+
}, [
|
|
911
|
+
(0, import_vue3.h)("span", { class: ["cli-panel-status-dot", statusServerState.value === "connected" ? "dot-idle" : "dot-error"].join(" ") }),
|
|
912
|
+
(0, import_vue3.h)("span", { class: "cli-panel-status-label" }, `${statusServerDetails.value.filter((s) => s.connected).length}/${statusServerDetails.value.length} servers`)
|
|
913
|
+
]) : null,
|
|
914
|
+
// Uptime
|
|
915
|
+
statusUptime.value > 0 ? (0, import_vue3.h)("span", { class: "cli-panel-status-item status-muted" }, [
|
|
916
|
+
(0, import_vue3.h)("span", { class: "cli-panel-status-icon", innerHTML: "↑" }),
|
|
917
|
+
(0, import_vue3.h)("span", { class: "cli-panel-status-label" }, formattedUptime.value)
|
|
918
|
+
]) : null,
|
|
919
|
+
// Custom status text
|
|
920
|
+
statusText.value ? (0, import_vue3.h)("span", { class: "cli-panel-status-item status-text" }, [
|
|
921
|
+
(0, import_vue3.h)("span", { class: "cli-panel-status-label" }, statusText.value)
|
|
922
|
+
]) : null
|
|
923
|
+
].filter(Boolean)) : null,
|
|
619
924
|
(0, import_vue3.h)("div", { class: "cli-panel-action-buttons" }, [
|
|
620
925
|
(0, import_vue3.h)("div", {
|
|
621
926
|
class: "cli-panel-btn-position-wrapper",
|
|
@@ -625,13 +930,13 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
625
930
|
class: "cli-panel-btn cli-panel-btn-position",
|
|
626
931
|
title: "Move panel",
|
|
627
932
|
onClick: togglePositionDropdown
|
|
628
|
-
}, [positionIcon(
|
|
933
|
+
}, [positionIcon(resolvedPosition.value)]),
|
|
629
934
|
positionDropdownOpen.value ? (0, import_vue3.h)(
|
|
630
935
|
"div",
|
|
631
936
|
{ class: "cli-panel-position-dropdown" },
|
|
632
937
|
["bottom", "top", "left", "right"].map(
|
|
633
938
|
(pos) => (0, import_vue3.h)("button", {
|
|
634
|
-
class: ["cli-panel-position-dropdown-item",
|
|
939
|
+
class: ["cli-panel-position-dropdown-item", resolvedPosition.value === pos ? "active" : ""].filter(Boolean).join(" "),
|
|
635
940
|
onClick: () => selectPosition(pos)
|
|
636
941
|
}, [
|
|
637
942
|
positionIcon(pos, 16),
|
|
@@ -649,20 +954,20 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
649
954
|
"button",
|
|
650
955
|
{
|
|
651
956
|
class: "cli-panel-btn",
|
|
652
|
-
title:
|
|
653
|
-
disabled:
|
|
957
|
+
title: resolvedMaximized.value ? "Restore" : "Maximize",
|
|
958
|
+
disabled: resolvedCollapsed.value,
|
|
654
959
|
onClick: toggleMaximize
|
|
655
960
|
},
|
|
656
|
-
[
|
|
961
|
+
[resolvedMaximized.value ? restoreIcon() : maximizeIcon()]
|
|
657
962
|
),
|
|
658
963
|
(0, import_vue3.h)(
|
|
659
964
|
"button",
|
|
660
965
|
{
|
|
661
966
|
class: "cli-panel-btn",
|
|
662
|
-
title:
|
|
967
|
+
title: resolvedCollapsed.value ? "Expand" : "Collapse",
|
|
663
968
|
onClick: toggle
|
|
664
969
|
},
|
|
665
|
-
[collapseChevron(
|
|
970
|
+
[collapseChevron(resolvedPosition.value, resolvedCollapsed.value)]
|
|
666
971
|
),
|
|
667
972
|
closable.value ? (0, import_vue3.h)(
|
|
668
973
|
"button",
|
|
@@ -674,9 +979,10 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
674
979
|
[closeIcon()]
|
|
675
980
|
) : null
|
|
676
981
|
])
|
|
677
|
-
])
|
|
982
|
+
]),
|
|
983
|
+
(0, import_vue3.h)("div", { class: ["cli-panel-glow-line", statusExecutionState.value === "running" ? "glow-active" : ""].filter(Boolean).join(" ") })
|
|
678
984
|
]);
|
|
679
|
-
const contentEl = initialized.value ? (0, import_vue3.h)("div", { class: "cli-panel-content", style:
|
|
985
|
+
const contentEl = initialized.value ? (0, import_vue3.h)("div", { class: "cli-panel-content", style: resolvedCollapsed.value ? { display: "none" } : void 0 }, [
|
|
680
986
|
// Tab bar
|
|
681
987
|
(0, import_vue3.h)("div", { class: "cli-panel-tabs" }, [
|
|
682
988
|
(0, import_vue3.h)(
|
|
@@ -689,7 +995,7 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
689
995
|
key: tab.id,
|
|
690
996
|
class: [
|
|
691
997
|
"cli-panel-tab",
|
|
692
|
-
tab.id ===
|
|
998
|
+
tab.id === resolvedActiveTabId.value && "active"
|
|
693
999
|
].filter(Boolean).join(" "),
|
|
694
1000
|
onClick: () => selectTab(tab.id),
|
|
695
1001
|
onDblclick: () => startRename(tab.id),
|
|
@@ -727,6 +1033,12 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
727
1033
|
onDblclick: (e) => e.stopPropagation()
|
|
728
1034
|
})
|
|
729
1035
|
] : [
|
|
1036
|
+
(0, import_vue3.h)("span", { class: ["cli-panel-tab-dot", (() => {
|
|
1037
|
+
if (tab.id !== resolvedActiveTabId.value) return "dot-idle";
|
|
1038
|
+
if (statusExecutionState.value === "running") return "dot-running";
|
|
1039
|
+
if (statusLastCommand.value && !statusLastCommand.value.success) return "dot-error";
|
|
1040
|
+
return "dot-idle";
|
|
1041
|
+
})()].join(" ") }),
|
|
730
1042
|
(0, import_vue3.h)(
|
|
731
1043
|
"span",
|
|
732
1044
|
{
|
|
@@ -757,7 +1069,7 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
757
1069
|
{
|
|
758
1070
|
class: "cli-panel-add-tab",
|
|
759
1071
|
title: "New terminal",
|
|
760
|
-
onClick: addTab
|
|
1072
|
+
onClick: () => addTab()
|
|
761
1073
|
},
|
|
762
1074
|
"+"
|
|
763
1075
|
)
|
|
@@ -773,7 +1085,7 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
773
1085
|
key: tab.id,
|
|
774
1086
|
class: "cli-panel-instance",
|
|
775
1087
|
style: {
|
|
776
|
-
display: tab.id ===
|
|
1088
|
+
display: tab.id === resolvedActiveTabId.value ? void 0 : "none"
|
|
777
1089
|
}
|
|
778
1090
|
},
|
|
779
1091
|
[
|
|
@@ -813,7 +1125,7 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
813
1125
|
{
|
|
814
1126
|
class: [
|
|
815
1127
|
"cli-panel-pane",
|
|
816
|
-
pane.id === activePaneId.value && tab.id ===
|
|
1128
|
+
pane.id === activePaneId.value && tab.id === resolvedActiveTabId.value && "active-pane"
|
|
817
1129
|
].filter(
|
|
818
1130
|
Boolean
|
|
819
1131
|
).join(" "),
|
|
@@ -822,7 +1134,7 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
822
1134
|
},
|
|
823
1135
|
onClick: () => {
|
|
824
1136
|
activePaneId.value = pane.id;
|
|
825
|
-
|
|
1137
|
+
updateActiveTabId(tab.id);
|
|
826
1138
|
}
|
|
827
1139
|
},
|
|
828
1140
|
[
|
|
@@ -834,7 +1146,6 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
834
1146
|
onClick: (e) => {
|
|
835
1147
|
e.stopPropagation();
|
|
836
1148
|
closePane(
|
|
837
|
-
tab.id,
|
|
838
1149
|
pane.id
|
|
839
1150
|
);
|
|
840
1151
|
}
|
|
@@ -910,7 +1221,7 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
910
1221
|
{ id: paneId, widthPercent: 100, snapshot }
|
|
911
1222
|
]
|
|
912
1223
|
});
|
|
913
|
-
|
|
1224
|
+
updateActiveTabId(tabId);
|
|
914
1225
|
activePaneId.value = paneId;
|
|
915
1226
|
}
|
|
916
1227
|
},
|
|
@@ -922,7 +1233,7 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
922
1233
|
class: "cli-panel-context-menu-item",
|
|
923
1234
|
onClick: () => {
|
|
924
1235
|
closeContextMenu();
|
|
925
|
-
|
|
1236
|
+
splitPane(contextMenu.value.tabId);
|
|
926
1237
|
}
|
|
927
1238
|
},
|
|
928
1239
|
"Split Right"
|
|
@@ -952,7 +1263,7 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
952
1263
|
tabs.value = tabs.value.filter(
|
|
953
1264
|
(t) => t.id === id
|
|
954
1265
|
);
|
|
955
|
-
|
|
1266
|
+
updateActiveTabId(id);
|
|
956
1267
|
}
|
|
957
1268
|
},
|
|
958
1269
|
"Close Others"
|
|
@@ -987,16 +1298,16 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
987
1298
|
closeContextMenu();
|
|
988
1299
|
tabs.value = [];
|
|
989
1300
|
initialized.value = false;
|
|
990
|
-
|
|
1301
|
+
updateCollapsed(true);
|
|
991
1302
|
}
|
|
992
1303
|
},
|
|
993
1304
|
"Close All"
|
|
994
1305
|
)
|
|
995
1306
|
]
|
|
996
1307
|
) : null;
|
|
997
|
-
const hideTabEl =
|
|
1308
|
+
const hideTabEl = resolvedHidden.value ? (0, import_vue3.h)("button", {
|
|
998
1309
|
class: "cli-panel-hide-tab",
|
|
999
|
-
"data-position":
|
|
1310
|
+
"data-position": resolvedPosition.value,
|
|
1000
1311
|
"data-hide-align": hideAlignment.value,
|
|
1001
1312
|
style: themeStyles.value,
|
|
1002
1313
|
title: "Show CLI",
|
|
@@ -1007,8 +1318,64 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
1007
1318
|
(0, import_vue3.h)("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
|
|
1008
1319
|
]),
|
|
1009
1320
|
(0, import_vue3.h)("span", { class: "cli-panel-hide-tab-label" }, "CLI"),
|
|
1010
|
-
hideTabChevron(
|
|
1321
|
+
hideTabChevron(resolvedPosition.value)
|
|
1011
1322
|
]) : null;
|
|
1323
|
+
const servicesDropdownEl = servicesDropdownOpen.value && statusServiceCount.value.total > 0 ? (0, import_vue3.h)("div", {
|
|
1324
|
+
class: "cli-panel-services-dropdown",
|
|
1325
|
+
style: (() => {
|
|
1326
|
+
const rect = servicesDropdownTriggerRect.value;
|
|
1327
|
+
if (!rect) return {};
|
|
1328
|
+
return resolvedPosition.value === "top" ? { position: "fixed", top: `${rect.bottom + 4}px`, left: `${rect.left}px`, zIndex: 1100 } : { position: "fixed", bottom: `${window.innerHeight - rect.top + 4}px`, left: `${rect.left}px`, zIndex: 1100 };
|
|
1329
|
+
})(),
|
|
1330
|
+
onClick: (e) => e.stopPropagation()
|
|
1331
|
+
}, [
|
|
1332
|
+
(0, import_vue3.h)("div", { class: "cli-panel-services-dropdown-header" }, "Background Services"),
|
|
1333
|
+
(0, import_vue3.h)(
|
|
1334
|
+
"div",
|
|
1335
|
+
{ class: "cli-panel-services-dropdown-list" },
|
|
1336
|
+
statusServiceDetails.value.map(
|
|
1337
|
+
(svc, i) => (0, import_vue3.h)("div", { key: i, class: "cli-panel-services-dropdown-item" }, [
|
|
1338
|
+
(0, import_vue3.h)("span", { class: ["cli-panel-svc-dot", svc.status === "running" ? "svc-running" : "svc-stopped"].join(" ") }),
|
|
1339
|
+
(0, import_vue3.h)("div", { class: "cli-panel-svc-info" }, [
|
|
1340
|
+
(0, import_vue3.h)("span", { class: "cli-panel-svc-name" }, svc.name),
|
|
1341
|
+
svc.description ? (0, import_vue3.h)("span", { class: "cli-panel-svc-desc" }, svc.description) : null
|
|
1342
|
+
].filter(Boolean)),
|
|
1343
|
+
(0, import_vue3.h)("span", { class: "cli-panel-svc-status" }, svc.status)
|
|
1344
|
+
])
|
|
1345
|
+
)
|
|
1346
|
+
),
|
|
1347
|
+
statusServiceDetails.value.length === 0 ? (0, import_vue3.h)("div", { class: "cli-panel-services-dropdown-empty" }, "No services registered") : null
|
|
1348
|
+
].filter(Boolean)) : null;
|
|
1349
|
+
const serversDropdownEl = serversDropdownOpen.value && statusServerState.value !== "none" ? (0, import_vue3.h)("div", {
|
|
1350
|
+
class: "cli-panel-services-dropdown",
|
|
1351
|
+
style: (() => {
|
|
1352
|
+
const rect = serversDropdownTriggerRect.value;
|
|
1353
|
+
if (!rect) return {};
|
|
1354
|
+
return resolvedPosition.value === "top" ? { position: "fixed", top: `${rect.bottom + 4}px`, left: `${rect.left}px`, zIndex: 1100 } : { position: "fixed", bottom: `${window.innerHeight - rect.top + 4}px`, left: `${rect.left}px`, zIndex: 1100 };
|
|
1355
|
+
})(),
|
|
1356
|
+
onClick: (e) => e.stopPropagation()
|
|
1357
|
+
}, [
|
|
1358
|
+
(0, import_vue3.h)("div", { class: "cli-panel-services-dropdown-header" }, "Server Connections"),
|
|
1359
|
+
(0, import_vue3.h)(
|
|
1360
|
+
"div",
|
|
1361
|
+
{ class: "cli-panel-services-dropdown-list" },
|
|
1362
|
+
statusServerDetails.value.map(
|
|
1363
|
+
(srv, i) => (0, import_vue3.h)("div", { key: i, class: "cli-panel-services-dropdown-item" }, [
|
|
1364
|
+
(0, import_vue3.h)("span", { class: ["cli-panel-svc-dot", srv.connected ? "svc-running" : "svc-stopped"].join(" ") }),
|
|
1365
|
+
(0, import_vue3.h)("div", { class: "cli-panel-svc-info" }, [
|
|
1366
|
+
(0, import_vue3.h)("span", { class: "cli-panel-svc-name" }, srv.name),
|
|
1367
|
+
srv.url ? (0, import_vue3.h)("span", { class: "cli-panel-svc-desc" }, srv.url) : null
|
|
1368
|
+
].filter(Boolean)),
|
|
1369
|
+
(0, import_vue3.h)("div", { class: "cli-panel-srv-meta" }, [
|
|
1370
|
+
(0, import_vue3.h)("span", { class: "cli-panel-svc-status" }, srv.connected ? "connected" : "disconnected"),
|
|
1371
|
+
srv.apiVersion ? (0, import_vue3.h)("span", { class: "cli-panel-svc-desc" }, `v${srv.apiVersion}`) : null,
|
|
1372
|
+
srv.commandCount ? (0, import_vue3.h)("span", { class: "cli-panel-svc-desc" }, `${srv.commandCount} cmds`) : null
|
|
1373
|
+
].filter(Boolean))
|
|
1374
|
+
])
|
|
1375
|
+
)
|
|
1376
|
+
),
|
|
1377
|
+
statusServerDetails.value.length === 0 ? (0, import_vue3.h)("div", { class: "cli-panel-services-dropdown-empty" }, "No servers configured") : null
|
|
1378
|
+
].filter(Boolean)) : null;
|
|
1012
1379
|
return (0, import_vue3.h)("div", {}, [
|
|
1013
1380
|
hideTabEl,
|
|
1014
1381
|
(0, import_vue3.h)(
|
|
@@ -1016,14 +1383,16 @@ var CliPanel = (0, import_vue3.defineComponent)({
|
|
|
1016
1383
|
{
|
|
1017
1384
|
class: wrapperClass,
|
|
1018
1385
|
style: wrapperStyle,
|
|
1019
|
-
"data-position":
|
|
1386
|
+
"data-position": resolvedPosition.value,
|
|
1020
1387
|
"data-resizable": String(resizable.value),
|
|
1021
1388
|
"data-closable": String(closable.value),
|
|
1022
1389
|
"data-hideable": String(hideable.value)
|
|
1023
1390
|
},
|
|
1024
1391
|
[headerEl, contentEl]
|
|
1025
1392
|
),
|
|
1026
|
-
contextMenuEl
|
|
1393
|
+
contextMenuEl,
|
|
1394
|
+
servicesDropdownEl,
|
|
1395
|
+
serversDropdownEl
|
|
1027
1396
|
]);
|
|
1028
1397
|
};
|
|
1029
1398
|
}
|