BREAKING CHANGE(deps): upgrade major dependencies, migrate action.target to action.targets (array), adapt to SmartRequest API changes, and add RADIUS server support

This commit is contained in:
2026-02-02 00:36:19 +00:00
parent badabe753a
commit 1a108fa8b7
26 changed files with 1808 additions and 582 deletions

View File

@@ -1,5 +1,6 @@
import * as plugins from '../plugins.js';
import * as appstate from '../appstate.js';
import { appRouter } from '../router.js';
import {
DeesElement,
@@ -84,17 +85,55 @@ export class OpsDashboard extends DeesElement {
.select((stateArg) => stateArg)
.subscribe((uiState) => {
this.uiState = uiState;
// Sync appdash view when state changes (e.g., from URL navigation)
this.syncAppdashView(uiState.activeView);
});
this.rxSubscriptions.push(uiSubscription);
}
/**
* Sync the dees-simple-appdash view selection with the current state.
* This is needed when the URL changes and we need to update the UI.
*/
private syncAppdashView(viewName: string): void {
const appDash = this.shadowRoot?.querySelector('dees-simple-appdash') as any;
if (!appDash) return;
const targetTab = this.viewTabs.find(t => t.name.toLowerCase() === viewName);
if (!targetTab) return;
// Check if we need to switch (avoid unnecessary updates)
if (appDash.selectedView === targetTab) return;
// Update the selected view programmatically
appDash.selectedView = targetTab;
// Update the displayed content
const content = appDash.shadowRoot?.querySelector('.appcontent');
if (content) {
if (appDash.currentView) {
appDash.currentView.remove();
}
const view = new targetTab.element();
content.appendChild(view);
appDash.currentView = view;
}
}
public static styles = [
cssManager.defaultStyles,
css`
:host {
display: block;
width: 100%;
height: 100vh;
overflow: hidden;
}
.maincontainer {
position: relative;
width: 100vw;
height: 100vh;
width: 100%;
height: 100%;
}
`,
];
@@ -126,24 +165,31 @@ export class OpsDashboard extends DeesElement {
const appDash = this.shadowRoot.querySelector('dees-simple-appdash');
if (appDash) {
appDash.addEventListener('view-select', (e: CustomEvent) => {
const viewName = e.detail.view.name;
appstate.uiStatePart.dispatchAction(appstate.setActiveViewAction, viewName.toLowerCase());
const viewName = e.detail.view.name.toLowerCase();
// Use router for navigation instead of direct state update
appRouter.navigateToView(viewName);
});
// Handle logout event
appDash.addEventListener('logout', async () => {
await appstate.loginStatePart.dispatchAction(appstate.logoutAction, null);
});
}
// Handle initial state
// Handle initial state - check if we have a stored session that's still valid
const loginState = appstate.loginStatePart.getState();
// Check initial login state
if (loginState.identity) {
this.loginState = loginState;
await simpleLogin.switchToSlottedContent();
await appstate.statsStatePart.dispatchAction(appstate.fetchAllStatsAction, null);
await appstate.configStatePart.dispatchAction(appstate.fetchConfigurationAction, null);
if (loginState.identity?.jwt) {
// Verify JWT hasn't expired
if (loginState.identity.expiresAt > Date.now()) {
// JWT still valid, restore logged-in state
this.loginState = loginState;
await simpleLogin.switchToSlottedContent();
await appstate.statsStatePart.dispatchAction(appstate.fetchAllStatsAction, null);
await appstate.configStatePart.dispatchAction(appstate.fetchConfigurationAction, null);
} else {
// JWT expired, clear the stored state
await appstate.loginStatePart.dispatchAction(appstate.logoutAction, null);
}
}
}

View File

@@ -155,11 +155,10 @@ export class OpsViewConfig extends DeesElement {
<span>Changes to configuration will take effect immediately. Please be careful when editing production settings.</span>
</div>
${this.renderConfigSection('server', 'Server Configuration', this.configState.config.server)}
${this.renderConfigSection('email', 'Email Configuration', this.configState.config.email)}
${this.renderConfigSection('dns', 'DNS Configuration', this.configState.config.dns)}
${this.renderConfigSection('security', 'Security Configuration', this.configState.config.security)}
${this.renderConfigSection('storage', 'Storage Configuration', this.configState.config.storage)}
${this.renderConfigSection('email', 'Email Configuration', this.configState.config?.email)}
${this.renderConfigSection('dns', 'DNS Configuration', this.configState.config?.dns)}
${this.renderConfigSection('proxy', 'Proxy Configuration', this.configState.config?.proxy)}
${this.renderConfigSection('security', 'Security Configuration', this.configState.config?.security)}
` : html`
<div class="errorMessage">No configuration loaded</div>
`}

File diff suppressed because it is too large Load Diff