mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-11 12:15:53 +00:00
- Update asciinema player CSS to use proper aspect ratios - Fix file browser z-index and layout issues - Remove old unused app.ts and server.ts files - Keep working app-new components structure 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
193 lines
No EOL
6.7 KiB
JavaScript
193 lines
No EOL
6.7 KiB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
};
|
|
import { LitElement, html } from 'lit';
|
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
import './file-browser.js';
|
|
let SessionCreateForm = class SessionCreateForm extends LitElement {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.workingDir = '~/';
|
|
this.command = '';
|
|
this.disabled = false;
|
|
this.isCreating = false;
|
|
this.showFileBrowser = false;
|
|
}
|
|
// Disable shadow DOM to use Tailwind
|
|
createRenderRoot() {
|
|
return this;
|
|
}
|
|
handleWorkingDirChange(e) {
|
|
const input = e.target;
|
|
this.workingDir = input.value;
|
|
this.dispatchEvent(new CustomEvent('working-dir-change', {
|
|
detail: this.workingDir
|
|
}));
|
|
}
|
|
handleCommandChange(e) {
|
|
const input = e.target;
|
|
this.command = input.value;
|
|
}
|
|
handleBrowse() {
|
|
this.showFileBrowser = true;
|
|
}
|
|
handleDirectorySelected(e) {
|
|
this.workingDir = e.detail;
|
|
this.showFileBrowser = false;
|
|
}
|
|
handleBrowserCancel() {
|
|
this.showFileBrowser = false;
|
|
}
|
|
async handleCreate() {
|
|
if (!this.workingDir.trim() || !this.command.trim()) {
|
|
this.dispatchEvent(new CustomEvent('error', {
|
|
detail: 'Please fill in both working directory and command'
|
|
}));
|
|
return;
|
|
}
|
|
this.isCreating = true;
|
|
const sessionData = {
|
|
command: this.parseCommand(this.command.trim()),
|
|
workingDir: this.workingDir.trim()
|
|
};
|
|
try {
|
|
const response = await fetch('/api/sessions', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(sessionData)
|
|
});
|
|
if (response.ok) {
|
|
const result = await response.json();
|
|
this.command = ''; // Clear command on success
|
|
this.dispatchEvent(new CustomEvent('session-created', {
|
|
detail: result
|
|
}));
|
|
}
|
|
else {
|
|
const error = await response.json();
|
|
this.dispatchEvent(new CustomEvent('error', {
|
|
detail: `Failed to create session: ${error.error}`
|
|
}));
|
|
}
|
|
}
|
|
catch (error) {
|
|
console.error('Error creating session:', error);
|
|
this.dispatchEvent(new CustomEvent('error', {
|
|
detail: 'Failed to create session'
|
|
}));
|
|
}
|
|
finally {
|
|
this.isCreating = false;
|
|
}
|
|
}
|
|
parseCommand(commandStr) {
|
|
// Simple command parsing - split by spaces but respect quotes
|
|
const args = [];
|
|
let current = '';
|
|
let inQuotes = false;
|
|
let quoteChar = '';
|
|
for (let i = 0; i < commandStr.length; i++) {
|
|
const char = commandStr[i];
|
|
if ((char === '"' || char === "'") && !inQuotes) {
|
|
inQuotes = true;
|
|
quoteChar = char;
|
|
}
|
|
else if (char === quoteChar && inQuotes) {
|
|
inQuotes = false;
|
|
quoteChar = '';
|
|
}
|
|
else if (char === ' ' && !inQuotes) {
|
|
if (current) {
|
|
args.push(current);
|
|
current = '';
|
|
}
|
|
}
|
|
else {
|
|
current += char;
|
|
}
|
|
}
|
|
if (current) {
|
|
args.push(current);
|
|
}
|
|
return args;
|
|
}
|
|
render() {
|
|
return html `
|
|
<div class="border border-vs-accent font-mono text-sm p-4 m-4 rounded">
|
|
<div class="text-vs-assistant text-sm mb-4">Create New Session</div>
|
|
|
|
<div class="mb-4">
|
|
<div class="text-vs-muted mb-2">Working Directory:</div>
|
|
<div class="flex gap-4">
|
|
<input
|
|
type="text"
|
|
class="flex-1 bg-vs-bg text-vs-text border border-vs-border outline-none font-mono px-4 py-2"
|
|
.value=${this.workingDir}
|
|
@input=${this.handleWorkingDirChange}
|
|
placeholder="~/"
|
|
?disabled=${this.disabled || this.isCreating}
|
|
/>
|
|
<button
|
|
class="bg-vs-function text-vs-bg hover:bg-vs-highlight font-mono px-4 py-2 border-none"
|
|
@click=${this.handleBrowse}
|
|
?disabled=${this.disabled || this.isCreating}
|
|
>
|
|
browse
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<div class="text-vs-muted mb-2">Command:</div>
|
|
<input
|
|
type="text"
|
|
class="w-full bg-vs-bg text-vs-text border border-vs-border outline-none font-mono px-4 py-2"
|
|
.value=${this.command}
|
|
@input=${this.handleCommandChange}
|
|
@keydown=${(e) => e.key === 'Enter' && this.handleCreate()}
|
|
placeholder="zsh"
|
|
?disabled=${this.disabled || this.isCreating}
|
|
/>
|
|
</div>
|
|
|
|
<button
|
|
class="bg-vs-user text-vs-text hover:bg-vs-accent font-mono px-4 py-2 border-none"
|
|
@click=${this.handleCreate}
|
|
?disabled=${this.disabled || this.isCreating || !this.workingDir.trim() || !this.command.trim()}
|
|
>
|
|
${this.isCreating ? 'creating...' : 'create'}
|
|
</button>
|
|
</div>
|
|
|
|
<file-browser
|
|
.visible=${this.showFileBrowser}
|
|
.currentPath=${this.workingDir}
|
|
@directory-selected=${this.handleDirectorySelected}
|
|
@browser-cancel=${this.handleBrowserCancel}
|
|
></file-browser>
|
|
`;
|
|
}
|
|
};
|
|
__decorate([
|
|
property({ type: String })
|
|
], SessionCreateForm.prototype, "workingDir", void 0);
|
|
__decorate([
|
|
property({ type: String })
|
|
], SessionCreateForm.prototype, "command", void 0);
|
|
__decorate([
|
|
property({ type: Boolean })
|
|
], SessionCreateForm.prototype, "disabled", void 0);
|
|
__decorate([
|
|
state()
|
|
], SessionCreateForm.prototype, "isCreating", void 0);
|
|
__decorate([
|
|
state()
|
|
], SessionCreateForm.prototype, "showFileBrowser", void 0);
|
|
SessionCreateForm = __decorate([
|
|
customElement('session-create-form')
|
|
], SessionCreateForm);
|
|
export { SessionCreateForm };
|
|
//# sourceMappingURL=session-create-form.js.map
|