Files
dcrouter/ts_web/elements/ops-dashboard.ts
Juergen Kunz facae93e4b feat: Implement dees-statsgrid in DCRouter UI for enhanced stats visualization
- Added new readme.statsgrid.md outlining the implementation plan for dees-statsgrid component.
- Replaced custom stats cards in ops-view-overview.ts and ops-view-network.ts with dees-statsgrid for better visualization.
- Introduced consistent color scheme for success, warning, error, and info states.
- Enhanced interactive features including click actions, context menus, and real-time updates.
- Developed ops-view-emails.ts for email management with features like composing, searching, and viewing emails.
- Integrated mock data generation for emails and network requests to facilitate testing.
- Added responsive design elements and improved UI consistency across components.
2025-06-12 08:04:30 +00:00

170 lines
5.0 KiB
TypeScript

import * as plugins from '../plugins.js';
import * as appstate from '../appstate.js';
import {
DeesElement,
css,
cssManager,
customElement,
html,
state,
type TemplateResult
} from '@design.estate/dees-element';
// Import view components
import { OpsViewOverview } from './ops-view-overview.js';
import { OpsViewNetwork } from './ops-view-network.js';
import { OpsViewEmails } from './ops-view-emails.js';
import { OpsViewLogs } from './ops-view-logs.js';
import { OpsViewConfig } from './ops-view-config.js';
import { OpsViewSecurity } from './ops-view-security.js';
@customElement('ops-dashboard')
export class OpsDashboard extends DeesElement {
@state() private loginState: appstate.ILoginState = {
identity: null,
isLoggedIn: false,
};
@state() private uiState: appstate.IUiState = {
activeView: 'dashboard',
sidebarCollapsed: false,
autoRefresh: true,
refreshInterval: 30000,
theme: 'light',
};
constructor() {
super();
document.title = 'DCRouter OpsServer';
// Subscribe to login state
const loginSubscription = appstate.loginStatePart
.select((stateArg) => stateArg)
.subscribe((loginState) => {
this.loginState = loginState;
// Trigger data fetch when logged in
if (loginState.isLoggedIn) {
appstate.statsStatePart.dispatchAction(appstate.fetchAllStatsAction, null);
appstate.configStatePart.dispatchAction(appstate.fetchConfigurationAction, null);
}
});
this.rxSubscriptions.push(loginSubscription);
// Subscribe to UI state
const uiSubscription = appstate.uiStatePart
.select((stateArg) => stateArg)
.subscribe((uiState) => {
this.uiState = uiState;
});
this.rxSubscriptions.push(uiSubscription);
}
public static styles = [
cssManager.defaultStyles,
css`
.maincontainer {
position: relative;
width: 100vw;
height: 100vh;
}
`,
];
public render(): TemplateResult {
return html`
<div class="maincontainer">
<dees-simple-login
name="DCRouter OpsServer"
>
<dees-simple-appdash
name="DCRouter OpsServer"
.viewTabs=${[
{
name: 'Overview',
element: OpsViewOverview,
},
{
name: 'Network',
element: OpsViewNetwork,
},
{
name: 'Emails',
element: OpsViewEmails,
},
{
name: 'Logs',
element: OpsViewLogs,
},
{
name: 'Configuration',
element: OpsViewConfig,
},
{
name: 'Security',
element: OpsViewSecurity,
},
]}
.userMenuItems=${[
{
name: 'Logout',
action: async () => {
await appstate.loginStatePart.dispatchAction(appstate.logoutAction, null);
},
},
]}
>
</dees-simple-appdash>
</dees-simple-login>
</div>
`;
}
public async firstUpdated() {
const simpleLogin = this.shadowRoot.querySelector('dees-simple-login');
simpleLogin.addEventListener('login', (e: CustomEvent) => {
console.log(e.detail);
this.login(e.detail.data.username, e.detail.data.password);
});
// Handle initial state
const loginState = appstate.loginStatePart.getState();
console.log('Initial login state:', loginState);
if (loginState.identity) {
this.loginState = loginState;
await simpleLogin.switchToSlottedContent();
await appstate.statsStatePart.dispatchAction(appstate.fetchAllStatsAction, null);
await appstate.configStatePart.dispatchAction(appstate.fetchConfigurationAction, null);
}
}
private async login(username: string, password: string) {
const domtools = await this.domtoolsPromise;
console.log(`Attempting to login...`);
const simpleLogin = this.shadowRoot.querySelector('dees-simple-login');
const form = simpleLogin.shadowRoot.querySelector('dees-form');
form.setStatus('pending', 'Logging in...');
const state = await appstate.loginStatePart.dispatchAction(appstate.loginAction, {
username,
password,
});
if (state.identity) {
console.log('Login successful');
this.loginState = state;
form.setStatus('success', 'Logged in!');
await simpleLogin.switchToSlottedContent();
await appstate.statsStatePart.dispatchAction(appstate.fetchAllStatsAction, null);
await appstate.configStatePart.dispatchAction(appstate.fetchConfigurationAction, null);
} else {
form.setStatus('error', 'Login failed!');
await domtools.convenience.smartdelay.delayFor(2000);
form.reset();
}
}
private async logout() {
await appstate.loginStatePart.dispatchAction(appstate.logoutAction, null);
}
}