feat(core): rebrand to @lossless.zone/objectstorage
- Rename from @lossless.zone/s3container to @lossless.zone/objectstorage - Replace @push.rocks/smarts3 with @push.rocks/smartstorage - Change env var prefix from S3_ to OBJST_ - Rename S3Container class to ObjectStorageContainer - Update web component prefix from s3c- to objst- - Update UI labels, CLI flags, documentation, and Docker config
This commit is contained in:
201
ts_web/elements/objst-view-overview.ts
Normal file
201
ts_web/elements/objst-view-overview.ts
Normal file
@@ -0,0 +1,201 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import * as appstate from '../appstate.js';
|
||||
import * as shared from './shared/index.js';
|
||||
|
||||
import {
|
||||
DeesElement,
|
||||
customElement,
|
||||
html,
|
||||
state,
|
||||
css,
|
||||
cssManager,
|
||||
type TemplateResult,
|
||||
} from '@design.estate/dees-element';
|
||||
import { type IStatsTile } from '@design.estate/dees-catalog';
|
||||
|
||||
@customElement('objst-view-overview')
|
||||
export class ObjstViewOverview extends DeesElement {
|
||||
@state()
|
||||
accessor serverState: appstate.IServerState = { status: null, connectionInfo: null };
|
||||
|
||||
@state()
|
||||
accessor bucketsState: appstate.IBucketsState = { buckets: [] };
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const serverSub = appstate.serverStatePart
|
||||
.select((s) => s)
|
||||
.subscribe((serverState) => {
|
||||
this.serverState = serverState;
|
||||
});
|
||||
this.rxSubscriptions.push(serverSub);
|
||||
|
||||
const bucketsSub = appstate.bucketsStatePart
|
||||
.select((s) => s)
|
||||
.subscribe((bucketsState) => {
|
||||
this.bucketsState = bucketsState;
|
||||
});
|
||||
this.rxSubscriptions.push(bucketsSub);
|
||||
}
|
||||
|
||||
async connectedCallback() {
|
||||
super.connectedCallback();
|
||||
appstate.serverStatePart.dispatchAction(appstate.fetchServerStatusAction, null);
|
||||
appstate.bucketsStatePart.dispatchAction(appstate.fetchBucketsAction, null);
|
||||
}
|
||||
|
||||
public static styles = [
|
||||
cssManager.defaultStyles,
|
||||
shared.viewHostCss,
|
||||
css`
|
||||
.connectionInfo {
|
||||
margin-top: 32px;
|
||||
padding: 24px;
|
||||
border-radius: 8px;
|
||||
background: ${cssManager.bdTheme('#f5f5f5', '#1a1a2e')};
|
||||
border: 1px solid ${cssManager.bdTheme('#e0e0e0', '#2a2a4a')};
|
||||
}
|
||||
.connectionInfo h2 {
|
||||
margin: 0 0 16px 0;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: ${cssManager.bdTheme('#333', '#ccc')};
|
||||
}
|
||||
.connectionInfo .row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.connectionInfo .label {
|
||||
width: 120px;
|
||||
font-weight: 500;
|
||||
color: ${cssManager.bdTheme('#666', '#999')};
|
||||
}
|
||||
.connectionInfo .value {
|
||||
font-family: monospace;
|
||||
color: ${cssManager.bdTheme('#333', '#e0e0e0')};
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
background: ${cssManager.bdTheme('#e8e8e8', '#252540')};
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
public render(): TemplateResult {
|
||||
const status = this.serverState.status;
|
||||
const connInfo = this.serverState.connectionInfo;
|
||||
|
||||
const statsTiles: IStatsTile[] = [
|
||||
{
|
||||
id: 'status',
|
||||
title: 'Server Status',
|
||||
value: status?.running ? 'Online' : 'Offline',
|
||||
type: 'text',
|
||||
icon: 'lucide:server',
|
||||
color: status?.running ? '#4caf50' : '#f44336',
|
||||
description: status ? `Uptime: ${this.formatUptime(status.uptime)}` : 'Loading...',
|
||||
},
|
||||
{
|
||||
id: 'buckets',
|
||||
title: 'Buckets',
|
||||
value: status?.bucketCount ?? 0,
|
||||
type: 'number',
|
||||
icon: 'lucide:database',
|
||||
color: '#2196f3',
|
||||
},
|
||||
{
|
||||
id: 'objects',
|
||||
title: 'Total Objects',
|
||||
value: status?.totalObjectCount ?? 0,
|
||||
type: 'number',
|
||||
icon: 'lucide:file',
|
||||
color: '#ff9800',
|
||||
},
|
||||
{
|
||||
id: 'storage',
|
||||
title: 'Storage Used',
|
||||
value: status ? this.formatBytes(status.totalStorageBytes) : '0 B',
|
||||
type: 'text',
|
||||
icon: 'lucide:hardDrive',
|
||||
color: '#9c27b0',
|
||||
},
|
||||
{
|
||||
id: 'storagePort',
|
||||
title: 'Storage Port',
|
||||
value: status?.objstPort ?? 9000,
|
||||
type: 'number',
|
||||
icon: 'lucide:network',
|
||||
color: '#00bcd4',
|
||||
},
|
||||
{
|
||||
id: 'region',
|
||||
title: 'Region',
|
||||
value: status?.region ?? 'us-east-1',
|
||||
type: 'text',
|
||||
icon: 'lucide:globe',
|
||||
color: '#607d8b',
|
||||
},
|
||||
];
|
||||
|
||||
return html`
|
||||
<objst-sectionheading>Overview</objst-sectionheading>
|
||||
<dees-statsgrid
|
||||
.tiles=${statsTiles}
|
||||
.gridActions=${[
|
||||
{
|
||||
name: 'Refresh',
|
||||
iconName: 'lucide:refreshCw',
|
||||
action: async () => {
|
||||
await appstate.serverStatePart.dispatchAction(
|
||||
appstate.fetchServerStatusAction,
|
||||
null,
|
||||
);
|
||||
await appstate.bucketsStatePart.dispatchAction(appstate.fetchBucketsAction, null);
|
||||
},
|
||||
},
|
||||
]}
|
||||
></dees-statsgrid>
|
||||
|
||||
${connInfo
|
||||
? html`
|
||||
<div class="connectionInfo">
|
||||
<h2>Connection Info</h2>
|
||||
<div class="row">
|
||||
<span class="label">Endpoint</span>
|
||||
<span class="value">${connInfo.endpoint}:${connInfo.port}</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="label">Protocol</span>
|
||||
<span class="value">${connInfo.useSsl ? 'HTTPS' : 'HTTP'}</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="label">Access Key</span>
|
||||
<span class="value">${connInfo.accessKey}</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="label">Region</span>
|
||||
<span class="value">${connInfo.region}</span>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
: ''}
|
||||
`;
|
||||
}
|
||||
|
||||
private formatUptime(seconds: number): string {
|
||||
const days = Math.floor(seconds / 86400);
|
||||
const hours = Math.floor((seconds % 86400) / 3600);
|
||||
const minutes = Math.floor((seconds % 3600) / 60);
|
||||
if (days > 0) return `${days}d ${hours}h ${minutes}m`;
|
||||
if (hours > 0) return `${hours}h ${minutes}m`;
|
||||
return `${minutes}m`;
|
||||
}
|
||||
|
||||
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]}`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user