Files
catalog/ts_web/elements/sz-demo-view-routes.ts

363 lines
9.3 KiB
TypeScript

import {
DeesElement,
customElement,
html,
css,
cssManager,
state,
type TemplateResult,
} from '@design.estate/dees-element';
import type { DeesAppui } from '@design.estate/dees-catalog';
import type { IRouteConfig } from './sz-route-card.js';
import './index.js';
declare global {
interface HTMLElementTagNameMap {
'sz-demo-view-routes': SzDemoViewRoutes;
}
}
@customElement('sz-demo-view-routes')
export class SzDemoViewRoutes extends DeesElement {
private appui: DeesAppui | null = null;
@state()
private accessor currentTab: 'all' | 'https' | 'email' | 'dns' = 'all';
private demoRoutes: IRouteConfig[] = [
// 1. HTTPS with TLS termination + auto cert
{
id: 'route-1',
name: 'Web Frontend',
description: 'Main website with TLS termination and automatic certificates',
enabled: true,
priority: 10,
tags: ['web', 'https', 'production'],
match: {
ports: 443,
domains: ['serve.zone', 'www.serve.zone'],
protocol: 'http',
},
action: {
type: 'forward',
targets: [{ host: '10.0.0.10', port: 3000 }],
tls: { mode: 'terminate', certificate: 'auto' },
},
},
// 2. HTTP to HTTPS redirect
{
id: 'route-2',
name: 'HTTP Redirect',
description: 'Redirects all HTTP traffic to HTTPS',
enabled: true,
priority: 100,
tags: ['web', 'http', 'redirect'],
match: {
ports: 80,
domains: ['serve.zone', 'www.serve.zone'],
protocol: 'http',
},
action: {
type: 'socket-handler',
},
},
// 3. Email SMTP route
{
id: 'route-3',
name: 'SMTP Inbound',
description: 'Inbound email relay for serve.zone domain',
enabled: true,
tags: ['email', 'smtp', 'production'],
match: {
ports: 25,
domains: 'mail.serve.zone',
},
action: {
type: 'forward',
targets: [{ host: '10.0.1.5', port: 25 }],
tls: { mode: 'terminate', certificate: 'auto' },
},
},
// 4. API gateway with path matching, rate limiting, CORS
{
id: 'route-4',
name: 'API Gateway',
description: 'API gateway with rate limiting, CORS headers, and load balancing',
enabled: true,
priority: 20,
tags: ['web', 'api', 'https', 'production'],
match: {
ports: 443,
domains: 'api.serve.zone',
path: '/v2/*',
protocol: 'http',
},
action: {
type: 'forward',
targets: [
{ host: ['10.0.0.20', '10.0.0.21', '10.0.0.22'], port: 8080 },
],
tls: { mode: 'terminate', certificate: 'auto' },
loadBalancing: { algorithm: 'round-robin' },
},
security: {
rateLimit: { enabled: true, maxRequests: 200, window: 60 },
maxConnections: 5000,
},
headers: {
response: {
'Access-Control-Allow-Origin': '*',
'X-Request-Id': '{{requestId}}',
},
},
},
// 5. WebSocket route
{
id: 'route-5',
name: 'WebSocket Realtime',
description: 'Real-time WebSocket connections for live updates',
enabled: true,
tags: ['web', 'https', 'websocket'],
match: {
ports: 443,
domains: 'ws.serve.zone',
path: '/ws/*',
protocol: 'http',
},
action: {
type: 'forward',
targets: [{ host: '10.0.0.30', port: 9090 }],
tls: { mode: 'terminate', certificate: 'auto' },
websocket: { enabled: true },
},
},
// 6. Wildcard domain route
{
id: 'route-6',
name: 'Tenant Wildcard',
description: 'Multi-tenant wildcard routing for customer subdomains',
enabled: true,
priority: 50,
tags: ['web', 'https', 'multi-tenant'],
match: {
ports: 443,
domains: '*.customers.serve.zone',
protocol: 'http',
},
action: {
type: 'forward',
targets: [{ host: '10.0.0.40', port: 8080 }],
tls: { mode: 'terminate', certificate: 'auto' },
},
security: {
ipAllowList: ['10.0.0.0/8', '172.16.0.0/12'],
},
},
// 7. Load-balanced route with health check
{
id: 'route-7',
name: 'Microservices LB',
description: 'Load-balanced microservices backend with IP-hash affinity',
enabled: true,
tags: ['web', 'https', 'production'],
match: {
ports: [443, 8443],
domains: 'services.serve.zone',
protocol: 'http',
},
action: {
type: 'forward',
targets: [
{ host: ['10.0.2.1', '10.0.2.2', '10.0.2.3', '10.0.2.4'], port: 3000 },
],
tls: { mode: 'terminate-and-reencrypt', certificate: 'auto' },
loadBalancing: { algorithm: 'ip-hash' },
},
},
// 8. DNS-over-HTTPS route
{
id: 'route-8',
name: 'DNS over HTTPS',
description: 'DNS-over-HTTPS resolver endpoint',
enabled: true,
tags: ['dns', 'https'],
match: {
ports: 443,
domains: 'dns.serve.zone',
path: '/dns-query',
protocol: 'http',
},
action: {
type: 'forward',
targets: [{ host: '10.0.3.1', port: 8053 }],
tls: { mode: 'terminate', certificate: 'auto' },
},
},
// 9. NFTables high-performance route
{
id: 'route-9',
name: 'High-Perf TCP Proxy',
description: 'NFTables-accelerated TCP proxy for game servers',
enabled: true,
tags: ['tcp', 'nftables', 'production'],
match: {
ports: [{ from: 27000, to: 27050 }],
protocol: 'tcp',
},
action: {
type: 'forward',
targets: [{ host: '10.0.4.1', port: 'preserve' }],
forwardingEngine: 'nftables',
},
},
// 10. Disabled maintenance route
{
id: 'route-10',
name: 'Legacy Admin Panel',
description: 'Deprecated admin panel — disabled for maintenance',
enabled: false,
tags: ['web', 'https', 'deprecated'],
match: {
ports: 443,
domains: 'admin-old.serve.zone',
protocol: 'http',
},
action: {
type: 'socket-handler',
},
security: {
ipBlockList: ['0.0.0.0/0'],
},
},
];
private get filteredRoutes(): IRouteConfig[] {
if (this.currentTab === 'all') return this.demoRoutes;
if (this.currentTab === 'https') {
return this.demoRoutes.filter((r) =>
r.tags?.some((t) => ['web', 'https', 'http'].includes(t))
);
}
if (this.currentTab === 'email') {
return this.demoRoutes.filter((r) =>
r.tags?.some((t) => ['email', 'smtp'].includes(t))
);
}
if (this.currentTab === 'dns') {
return this.demoRoutes.filter((r) =>
r.tags?.some((t) => ['dns'].includes(t))
);
}
return this.demoRoutes;
}
async onActivate(context: { appui: DeesAppui; viewId: string }) {
this.appui = context.appui;
this.appui.setContentTabs([
{
key: 'All Routes',
action: () => {
this.currentTab = 'all';
this.updateSecondaryMenu();
},
},
{
key: 'HTTP/S',
action: () => {
this.currentTab = 'https';
this.updateSecondaryMenu();
},
},
{
key: 'Email',
action: () => {
this.currentTab = 'email';
this.updateSecondaryMenu();
},
},
{
key: 'DNS',
action: () => {
this.currentTab = 'dns';
this.updateSecondaryMenu();
},
},
]);
this.updateSecondaryMenu();
}
private updateSecondaryMenu() {
if (!this.appui) return;
const total = this.demoRoutes.length;
const active = this.demoRoutes.filter((r) => r.enabled !== false).length;
const forwardCount = this.demoRoutes.filter((r) => r.action.type === 'forward').length;
this.appui.setSecondaryMenu({
heading: 'Routes',
groups: [
{
name: 'Actions',
items: [
{
type: 'action',
key: 'Refresh',
iconName: 'lucide:RefreshCw',
action: () => {
console.log('Refresh routes');
},
},
{
type: 'action',
key: 'Add Route',
iconName: 'lucide:Plus',
action: () => {
console.log('Add route');
},
},
],
},
{
name: 'Statistics',
items: [
{ type: 'header' as const, label: `${total} Total Routes` },
{ type: 'header' as const, label: `${active} Active` },
{ type: 'header' as const, label: `${forwardCount} Forward` },
{ type: 'header' as const, label: `${total - forwardCount} Socket Handler` },
],
},
],
});
}
onDeactivate() {
// Cleanup if needed
}
public static styles = [
cssManager.defaultStyles,
css`
:host {
display: block;
padding: 24px;
height: 100%;
overflow-y: auto;
box-sizing: border-box;
}
`,
];
public render(): TemplateResult {
return html`
<sz-route-list-view
.routes=${this.filteredRoutes}
@route-click=${(e: CustomEvent<IRouteConfig>) => {
console.log('Route clicked:', e.detail.name);
}}
></sz-route-list-view>
`;
}
}