feat(web-ui): reorganize network and security views into tabbed subviews with route-aware navigation
This commit is contained in:
114
ts_web/elements/security/ops-view-security.ts
Normal file
114
ts_web/elements/security/ops-view-security.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
import * as appstate from '../../appstate.js';
|
||||
import { appRouter } from '../../router.js';
|
||||
import { viewHostCss } from '../shared/css.js';
|
||||
|
||||
import {
|
||||
DeesElement,
|
||||
customElement,
|
||||
html,
|
||||
state,
|
||||
css,
|
||||
cssManager,
|
||||
type TemplateResult,
|
||||
} from '@design.estate/dees-element';
|
||||
|
||||
// Side-effect imports register the subview custom elements
|
||||
import './ops-view-security-overview.js';
|
||||
import './ops-view-security-blocked.js';
|
||||
import './ops-view-security-authentication.js';
|
||||
import './ops-view-security-emailsecurity.js';
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'ops-view-security': OpsViewSecurity;
|
||||
}
|
||||
}
|
||||
|
||||
type TSecurityTab = 'overview' | 'blocked' | 'authentication' | 'emailsecurity';
|
||||
|
||||
@customElement('ops-view-security')
|
||||
export class OpsViewSecurity extends DeesElement {
|
||||
@state()
|
||||
accessor selectedTab: TSecurityTab = 'overview';
|
||||
|
||||
private tabLabelMap: Record<TSecurityTab, string> = {
|
||||
'overview': 'Overview',
|
||||
'blocked': 'Blocked IPs',
|
||||
'authentication': 'Authentication',
|
||||
'emailsecurity': 'Email Security',
|
||||
};
|
||||
|
||||
private labelToTab: Record<string, TSecurityTab> = {
|
||||
'Overview': 'overview',
|
||||
'Blocked IPs': 'blocked',
|
||||
'Authentication': 'authentication',
|
||||
'Email Security': 'emailsecurity',
|
||||
};
|
||||
|
||||
private static isSecurityTab(s: string | null): s is TSecurityTab {
|
||||
return s === 'overview' || s === 'blocked' || s === 'authentication' || s === 'emailsecurity';
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
// Read initial subview from state (URL-driven)
|
||||
const initialState = appstate.uiStatePart.getState()!;
|
||||
if (OpsViewSecurity.isSecurityTab(initialState.activeSubview)) {
|
||||
this.selectedTab = initialState.activeSubview;
|
||||
}
|
||||
// Subscribe to future changes (back/forward navigation, direct URL entry)
|
||||
const sub = appstate.uiStatePart.select((s) => s.activeSubview).subscribe((sub) => {
|
||||
if (OpsViewSecurity.isSecurityTab(sub) && sub !== this.selectedTab) {
|
||||
this.selectedTab = sub;
|
||||
}
|
||||
});
|
||||
this.rxSubscriptions.push(sub);
|
||||
}
|
||||
|
||||
async firstUpdated() {
|
||||
const toggle = this.shadowRoot!.querySelector('dees-input-multitoggle') as any;
|
||||
if (toggle) {
|
||||
const sub = toggle.changeSubject.subscribe(() => {
|
||||
const tab = this.labelToTab[toggle.selectedOption];
|
||||
if (tab && tab !== this.selectedTab) {
|
||||
// Push URL → router updates state → subscription updates selectedTab
|
||||
appRouter.navigateToView('security', tab);
|
||||
}
|
||||
});
|
||||
this.rxSubscriptions.push(sub);
|
||||
}
|
||||
}
|
||||
|
||||
public static styles = [
|
||||
cssManager.defaultStyles,
|
||||
viewHostCss,
|
||||
css`
|
||||
dees-input-multitoggle {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
public render(): TemplateResult {
|
||||
return html`
|
||||
<dees-heading level="2">Security</dees-heading>
|
||||
|
||||
<dees-input-multitoggle
|
||||
.type=${'single'}
|
||||
.options=${['Overview', 'Blocked IPs', 'Authentication', 'Email Security']}
|
||||
.selectedOption=${this.tabLabelMap[this.selectedTab]}
|
||||
></dees-input-multitoggle>
|
||||
|
||||
${this.renderTabContent()}
|
||||
`;
|
||||
}
|
||||
|
||||
private renderTabContent(): TemplateResult {
|
||||
switch (this.selectedTab) {
|
||||
case 'overview': return html`<ops-view-security-overview></ops-view-security-overview>`;
|
||||
case 'blocked': return html`<ops-view-security-blocked></ops-view-security-blocked>`;
|
||||
case 'authentication': return html`<ops-view-security-authentication></ops-view-security-authentication>`;
|
||||
case 'emailsecurity': return html`<ops-view-security-emailsecurity></ops-view-security-emailsecurity>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user