115 lines
3.5 KiB
TypeScript
115 lines
3.5 KiB
TypeScript
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>`;
|
|
}
|
|
}
|
|
}
|