mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-17 13:15:53 +00:00
frontend design tweaks
This commit is contained in:
parent
08bdc5ecb4
commit
ad60da3140
2 changed files with 70 additions and 5 deletions
45
web/src/client/components/copy-icon.ts
Normal file
45
web/src/client/components/copy-icon.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { LitElement, html, css } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
|
||||
@customElement('copy-icon')
|
||||
export class CopyIcon extends LitElement {
|
||||
@property({ type: Number }) size = 16;
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0.4;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
:host(:hover) {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
svg {
|
||||
display: block;
|
||||
width: var(--icon-size, 16px);
|
||||
height: var(--icon-size, 16px);
|
||||
}
|
||||
`;
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
style="--icon-size: ${this.size}px"
|
||||
class="copy-icon"
|
||||
>
|
||||
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
|
||||
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { LitElement, html } from 'lit';
|
||||
import { customElement, property, state } from 'lit/decorators.js';
|
||||
import './vibe-terminal-buffer.js';
|
||||
import './copy-icon.js';
|
||||
|
||||
export interface Session {
|
||||
id: string;
|
||||
|
|
@ -146,13 +147,27 @@ export class SessionCard extends LitElement {
|
|||
textArea.select();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
console.log('PID copied to clipboard (fallback):', text);
|
||||
console.log('Text copied to clipboard (fallback):', text);
|
||||
} catch (error) {
|
||||
console.error('Fallback copy failed:', error);
|
||||
}
|
||||
document.body.removeChild(textArea);
|
||||
}
|
||||
|
||||
private async handlePathClick(e: Event) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(this.session.workingDir);
|
||||
console.log('Path copied to clipboard:', this.session.workingDir);
|
||||
} catch (error) {
|
||||
console.error('Failed to copy path to clipboard:', error);
|
||||
// Fallback: select text manually
|
||||
this.fallbackCopyToClipboard(this.session.workingDir);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div
|
||||
|
|
@ -238,18 +253,23 @@ export class SessionCard extends LitElement {
|
|||
${this.session.pid
|
||||
? html`
|
||||
<span
|
||||
class="cursor-pointer hover:text-accent-green transition-colors text-xs flex-shrink-0 ml-2"
|
||||
class="cursor-pointer hover:text-accent-green transition-colors text-xs flex-shrink-0 ml-2 inline-flex items-center gap-1"
|
||||
@click=${this.handlePidClick}
|
||||
title="Click to copy PID"
|
||||
>
|
||||
PID: ${this.session.pid} <span class="opacity-50">(click to copy)</span>
|
||||
PID: ${this.session.pid} <copy-icon size="14"></copy-icon>
|
||||
</span>
|
||||
`
|
||||
: ''}
|
||||
</div>
|
||||
<div class="text-xs opacity-75 min-w-0 mt-1">
|
||||
<div class="truncate" title="${this.session.workingDir}">
|
||||
${this.session.workingDir}
|
||||
<div
|
||||
class="truncate cursor-pointer hover:text-accent-green transition-colors inline-flex items-center gap-1 max-w-full"
|
||||
title="Click to copy path"
|
||||
@click=${this.handlePathClick}
|
||||
>
|
||||
<span class="truncate">${this.session.workingDir}</span>
|
||||
<copy-icon size="12" class="flex-shrink-0"></copy-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue