224 lines
5.3 KiB
TypeScript
224 lines
5.3 KiB
TypeScript
import * as plugins from '../plugins.js';
|
|
import { apiService } from '../services/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 = '';
|
|
|
|
public static styles = [
|
|
cssManager.defaultStyles,
|
|
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(99, 102, 241, 0.2);
|
|
border-color: #6366f1;
|
|
color: #818cf8;
|
|
}
|
|
|
|
.content {
|
|
flex: 1;
|
|
display: grid;
|
|
grid-template-columns: 1fr 350px;
|
|
gap: 16px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.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;
|
|
}
|
|
|
|
@media (max-width: 1024px) {
|
|
.content {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.preview-panel {
|
|
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);
|
|
}
|
|
|
|
render() {
|
|
const breadcrumbParts = this.currentPrefix
|
|
? this.currentPrefix.split('/').filter(Boolean)
|
|
: [];
|
|
|
|
return html`
|
|
<div class="browser-container">
|
|
<div class="toolbar">
|
|
<div class="breadcrumb">
|
|
<span
|
|
class="breadcrumb-item"
|
|
@click=${() => this.navigateToPrefix('')}
|
|
>
|
|
${this.bucketName}
|
|
</span>
|
|
${breadcrumbParts.map((part, index) => {
|
|
const prefix = breadcrumbParts.slice(0, index + 1).join('/') + '/';
|
|
return html`
|
|
<span class="breadcrumb-separator">/</span>
|
|
<span
|
|
class="breadcrumb-item"
|
|
@click=${() => this.navigateToPrefix(prefix)}
|
|
>
|
|
${part}
|
|
</span>
|
|
`;
|
|
})}
|
|
</div>
|
|
|
|
<div class="view-toggle">
|
|
<button
|
|
class="view-btn ${this.viewType === 'columns' ? 'active' : ''}"
|
|
@click=${() => this.setViewType('columns')}
|
|
>
|
|
Columns
|
|
</button>
|
|
<button
|
|
class="view-btn ${this.viewType === 'keys' ? 'active' : ''}"
|
|
@click=${() => this.setViewType('keys')}
|
|
>
|
|
List
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="content">
|
|
<div class="main-view">
|
|
${this.viewType === 'columns'
|
|
? html`
|
|
<tsview-s3-columns
|
|
.bucketName=${this.bucketName}
|
|
.currentPrefix=${this.currentPrefix}
|
|
@key-selected=${this.handleKeySelected}
|
|
@navigate=${this.handleNavigate}
|
|
></tsview-s3-columns>
|
|
`
|
|
: html`
|
|
<tsview-s3-keys
|
|
.bucketName=${this.bucketName}
|
|
.currentPrefix=${this.currentPrefix}
|
|
@key-selected=${this.handleKeySelected}
|
|
@navigate=${this.handleNavigate}
|
|
></tsview-s3-keys>
|
|
`}
|
|
</div>
|
|
|
|
<div class="preview-panel">
|
|
<tsview-s3-preview
|
|
.bucketName=${this.bucketName}
|
|
.objectKey=${this.selectedKey}
|
|
></tsview-s3-preview>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
}
|