import * as plugins from '../plugins.js'; import * as appstate from '../appstate.js'; import * as shared from './shared/index.js'; import { appRouter } from '../router.js'; import { DeesElement, customElement, html, state, css, cssManager, type TemplateResult, } from '@design.estate/dees-element'; import { DeesModal } from '@design.estate/dees-catalog'; @customElement('objst-view-buckets') export class ObjstViewBuckets extends DeesElement { @state() accessor bucketsState: appstate.IBucketsState = { buckets: [] }; constructor() { super(); const sub = appstate.bucketsStatePart .select((s) => s) .subscribe((bucketsState) => { this.bucketsState = bucketsState; }); this.rxSubscriptions.push(sub); } async connectedCallback() { super.connectedCallback(); appstate.bucketsStatePart.dispatchAction(appstate.fetchBucketsAction, null); } public static styles = [ cssManager.defaultStyles, shared.viewHostCss, ]; public render(): TemplateResult { return html` Buckets ({ name: item.name, objects: String(item.objectCount), size: this.formatBytes(item.totalSizeBytes), created: new Date(item.creationDate).toLocaleDateString(), })} .dataActions=${[ { name: 'Create Bucket', iconName: 'lucide:plus', type: ['header'] as any[], actionFunc: async () => { await this.showCreateBucketModal(); }, }, { name: 'Browse', iconName: 'lucide:folderOpen', type: ['inRow'] as any[], actionFunc: async (args: any) => { await appstate.objectsStatePart.dispatchAction(appstate.fetchObjectsAction, { bucketName: args.item.name, prefix: '', delimiter: '/', }); appRouter.navigateToView('browser'); }, }, { name: 'Policy', iconName: 'lucide:shield', type: ['inRow'] as any[], actionFunc: async (args: any) => { await this.showPolicyModal(args.item.name); }, }, { name: 'Delete', iconName: 'lucide:trash2', type: ['inRow', 'contextmenu'] as any[], actionFunc: async (args: any) => { await this.showDeleteBucketModal(args.item.name); }, }, ]} > `; } private async showCreateBucketModal(): Promise { await DeesModal.createAndShow({ heading: 'Create Bucket', content: html` `, menuOptions: [ { name: 'Cancel', action: async (modal: any) => { modal.destroy(); }, }, { name: 'Create', action: async (modal: any) => { const form = modal.shadowRoot.querySelector('dees-form') as any; const data = await form.collectFormData(); if (data.bucketName) { await appstate.bucketsStatePart.dispatchAction(appstate.createBucketAction, { bucketName: data.bucketName, }); } modal.destroy(); }, }, ], }); } private async showDeleteBucketModal(bucketName: string): Promise { await DeesModal.createAndShow({ heading: 'Delete Bucket', content: html`

Are you sure you want to delete bucket ${bucketName}? This action cannot be undone.

`, menuOptions: [ { name: 'Cancel', action: async (modal: any) => { modal.destroy(); }, }, { name: 'Delete', action: async (modal: any) => { await appstate.bucketsStatePart.dispatchAction(appstate.deleteBucketAction, { bucketName, }); modal.destroy(); }, }, ], }); } private async showPolicyModal(bucketName: string): Promise { const data = await appstate.getBucketNamedPolicies(bucketName); let modalRef: any = null; const renderContent = ( attached: typeof data.attachedPolicies, available: typeof data.availablePolicies, ) => html`

Attached Policies (${attached.length})

${attached.length > 0 ? attached.map((policy) => html`
${policy.name} ${policy.description ? html`${policy.description}` : ''}
`) : html`

No policies attached to this bucket.

`}

Available Policies (${available.length})

${available.length > 0 ? available.map((policy) => html`
${policy.name} ${policy.description ? html`${policy.description}` : ''}
`) : html`

${attached.length > 0 ? 'All policies are already attached.' : 'No policies defined yet. Create policies in the Policies view.' }

`}
`; modalRef = await DeesModal.createAndShow({ heading: `Policies for: ${bucketName}`, content: renderContent(data.attachedPolicies, data.availablePolicies), menuOptions: [ { name: 'Done', action: async (modal: any) => { modal.destroy(); } }, ], }); } private formatBytes(bytes: number): string { if (bytes === 0) return '0 B'; const units = ['B', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(1024)); return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${units[i]}`; } }