Files
objectstorage/ts_web/elements/objst-view-objects.ts

150 lines
4.0 KiB
TypeScript
Raw Normal View History

import * as plugins from '../plugins.js';
import * as appstate from '../appstate.js';
import { createDataProvider } from '../dataprovider.js';
import {
DeesElement,
customElement,
html,
state,
css,
cssManager,
type TemplateResult,
} from '@design.estate/dees-element';
@customElement('objst-view-objects')
export class ObjstViewObjects extends DeesElement {
@state()
accessor bucketsState: appstate.IBucketsState = { buckets: [] };
@state()
accessor selectedBucket: string = '';
private dataProvider = createDataProvider();
constructor() {
super();
const bucketsSub = appstate.bucketsStatePart
.select((s) => s)
.subscribe((bucketsState) => {
this.bucketsState = bucketsState;
});
this.rxSubscriptions.push(bucketsSub);
// Track current bucket from objects state
const objSub = appstate.objectsStatePart
.select((s) => s.currentBucket)
.subscribe((currentBucket) => {
if (currentBucket) {
this.selectedBucket = currentBucket;
}
});
this.rxSubscriptions.push(objSub);
}
async connectedCallback() {
super.connectedCallback();
if (this.bucketsState.buckets.length === 0) {
appstate.bucketsStatePart.dispatchAction(appstate.fetchBucketsAction, null);
}
}
public static styles = [
cssManager.defaultStyles,
css`
:host {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
box-sizing: border-box;
}
.bucket-bar {
display: flex;
align-items: center;
gap: 12px;
padding: 8px 16px;
flex-wrap: wrap;
}
.bucket-bar label {
font-size: 14px;
font-weight: 600;
color: ${cssManager.bdTheme('#333', '#ccc')};
}
.bucket-chip {
padding: 6px 16px;
border-radius: 20px;
font-size: 13px;
cursor: pointer;
border: 1px solid ${cssManager.bdTheme('#ddd', '#444')};
background: ${cssManager.bdTheme('#f5f5f5', '#1a1a2e')};
color: ${cssManager.bdTheme('#333', '#ccc')};
transition: all 0.15s ease;
}
.bucket-chip:hover {
border-color: ${cssManager.bdTheme('#2196f3', '#64b5f6')};
color: ${cssManager.bdTheme('#2196f3', '#64b5f6')};
}
.bucket-chip.active {
background: ${cssManager.bdTheme('#2196f3', '#1565c0')};
color: white;
border-color: ${cssManager.bdTheme('#2196f3', '#1565c0')};
}
.browser-container {
flex: 1;
min-height: 0;
overflow: hidden;
}
.noBucket {
text-align: center;
padding: 64px 0;
color: ${cssManager.bdTheme('#666', '#999')};
font-size: 16px;
}
`,
];
public render(): TemplateResult {
return html`
<div class="bucket-bar">
<label>Bucket:</label>
${this.bucketsState.buckets.map(
(bucket) => html`
<span
class="bucket-chip ${this.selectedBucket === bucket.name ? 'active' : ''}"
@click=${() => this.selectBucket(bucket.name)}
>${bucket.name}</span>
`,
)}
${this.bucketsState.buckets.length === 0
? html`<span style="color: #999; font-size: 13px;">No buckets found</span>`
: ''}
</div>
${this.selectedBucket
? html`
<div class="browser-container">
<dees-s3-browser
.dataProvider=${this.dataProvider}
.bucketName=${this.selectedBucket}
></dees-s3-browser>
</div>
`
: html`
<div class="noBucket">
<p>Select a bucket above to browse objects.</p>
</div>
`}
`;
}
private selectBucket(bucketName: string): void {
this.selectedBucket = bucketName;
// Update objects state for tracking
appstate.objectsStatePart.dispatchAction(appstate.fetchObjectsAction, {
bucketName,
prefix: '',
delimiter: '/',
});
}
}