import * as plugins from '../plugins.js'; import { apiService } from '../services/index.js'; import { themeStyles } from '../styles/index.js'; const { html, css, cssManager, customElement, property, state, DeesElement } = plugins; type TViewType = 'columns' | 'keys'; @customElement('tsview-s3-browser') export class TsviewS3Browser extends DeesElement { @property({ type: String }) public accessor bucketName: string = ''; @state() private accessor viewType: TViewType = 'columns'; @state() private accessor currentPrefix: string = ''; @state() private accessor selectedKey: string = ''; @state() private accessor refreshKey: number = 0; @state() private accessor previewWidth: number = 350; @state() private accessor isResizingPreview: boolean = false; public static styles = [ cssManager.defaultStyles, themeStyles, css` :host { display: block; height: 100%; } .browser-container { display: flex; flex-direction: column; height: 100%; } .toolbar { display: flex; align-items: center; gap: 12px; padding: 12px; background: rgba(0, 0, 0, 0.2); border-radius: 8px; margin-bottom: 16px; } .breadcrumb { display: flex; align-items: center; gap: 4px; flex: 1; font-size: 14px; color: #999; } .breadcrumb-item { cursor: pointer; padding: 4px 8px; border-radius: 4px; transition: background 0.15s; } .breadcrumb-item:hover { background: rgba(255, 255, 255, 0.1); color: #fff; } .breadcrumb-separator { color: #555; } .view-toggle { display: flex; gap: 4px; } .view-btn { padding: 6px 12px; background: transparent; border: 1px solid #444; color: #888; border-radius: 4px; cursor: pointer; font-size: 13px; transition: all 0.15s; } .view-btn:hover { border-color: #666; color: #aaa; } .view-btn.active { background: rgba(255, 255, 255, 0.1); border-color: #404040; color: #e0e0e0; } .content { flex: 1; display: grid; grid-template-columns: 1fr; gap: 0; overflow: hidden; } .content.has-preview { grid-template-columns: 1fr 4px var(--preview-width, 350px); } .resize-divider { width: 4px; background: transparent; cursor: col-resize; transition: background 0.2s; } .resize-divider:hover, .resize-divider.active { background: rgba(255, 255, 255, 0.2); } .main-view { overflow: auto; background: rgba(0, 0, 0, 0.2); border-radius: 8px; } .preview-panel { background: rgba(0, 0, 0, 0.2); border-radius: 8px; overflow: hidden; margin-left: 12px; } @media (max-width: 1024px) { .content, .content.has-preview { grid-template-columns: 1fr; } .preview-panel, .resize-divider { display: none; } } `, ]; private setViewType(type: TViewType) { this.viewType = type; } private navigateToPrefix(prefix: string) { this.currentPrefix = prefix; this.selectedKey = ''; } private handleKeySelected(e: CustomEvent) { this.selectedKey = e.detail.key; } private handleNavigate(e: CustomEvent) { this.navigateToPrefix(e.detail.prefix); } private handleObjectDeleted(e: CustomEvent) { this.selectedKey = ''; // Increment refresh key to trigger re-render of child components this.refreshKey++; } updated(changedProperties: Map) { if (changedProperties.has('bucketName')) { // Clear selection when bucket changes this.selectedKey = ''; this.currentPrefix = ''; } } private startPreviewResize = (e: MouseEvent) => { e.preventDefault(); this.isResizingPreview = true; document.addEventListener('mousemove', this.handlePreviewResize); document.addEventListener('mouseup', this.endPreviewResize); }; private handlePreviewResize = (e: MouseEvent) => { if (!this.isResizingPreview) return; const contentEl = this.shadowRoot?.querySelector('.content'); if (!contentEl) return; const containerRect = contentEl.getBoundingClientRect(); const newWidth = Math.min(Math.max(containerRect.right - e.clientX, 250), 600); this.previewWidth = newWidth; }; private endPreviewResize = () => { this.isResizingPreview = false; document.removeEventListener('mousemove', this.handlePreviewResize); document.removeEventListener('mouseup', this.endPreviewResize); }; render() { const breadcrumbParts = this.currentPrefix ? this.currentPrefix.split('/').filter(Boolean) : []; return html`
${this.viewType === 'columns' ? html` ` : html` `}
${this.selectedKey ? html`
` : ''}
`; } }