@serve.zone/catalog 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/index.d.ts +6 -0
- package/dist_ts_web/elements/index.js +9 -1
- package/dist_ts_web/elements/sz-config-overview.d.ts +14 -0
- package/dist_ts_web/elements/sz-config-overview.js +141 -0
- package/dist_ts_web/elements/sz-config-section.d.ts +31 -0
- package/dist_ts_web/elements/sz-config-section.js +591 -0
- package/dist_ts_web/elements/sz-demo-view-config.d.ts +11 -0
- package/dist_ts_web/elements/sz-demo-view-config.js +193 -0
- package/dist_ts_web/elements/sz-demo-view-routes.d.ts +22 -0
- package/dist_ts_web/elements/sz-demo-view-routes.js +388 -0
- package/dist_ts_web/elements/sz-route-card.d.ts +78 -0
- package/dist_ts_web/elements/sz-route-card.js +648 -0
- package/dist_ts_web/elements/sz-route-list-view.d.ts +21 -0
- package/dist_ts_web/elements/sz-route-list-view.js +372 -0
- package/dist_ts_web/pages/sz-demo-app-shell.js +8 -2
- package/dist_watch/bundle.js +2074 -152
- package/dist_watch/bundle.js.map +4 -4
- package/package.json +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/index.ts +10 -0
- package/ts_web/elements/sz-config-overview.ts +92 -0
- package/ts_web/elements/sz-config-section.ts +531 -0
- package/ts_web/elements/sz-demo-view-config.ts +164 -0
- package/ts_web/elements/sz-demo-view-routes.ts +362 -0
- package/ts_web/elements/sz-route-card.ts +667 -0
- package/ts_web/elements/sz-route-list-view.ts +326 -0
- package/ts_web/pages/sz-demo-app-shell.ts +7 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DeesElement,
|
|
3
|
+
customElement,
|
|
4
|
+
html,
|
|
5
|
+
css,
|
|
6
|
+
cssManager,
|
|
7
|
+
type TemplateResult,
|
|
8
|
+
} from '@design.estate/dees-element';
|
|
9
|
+
import type { IConfigField } from './sz-config-section.js';
|
|
10
|
+
import './index.js';
|
|
11
|
+
|
|
12
|
+
declare global {
|
|
13
|
+
interface HTMLElementTagNameMap {
|
|
14
|
+
'sz-demo-view-config': SzDemoViewConfig;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@customElement('sz-demo-view-config')
|
|
19
|
+
export class SzDemoViewConfig extends DeesElement {
|
|
20
|
+
public static styles = [
|
|
21
|
+
cssManager.defaultStyles,
|
|
22
|
+
css`
|
|
23
|
+
:host {
|
|
24
|
+
display: block;
|
|
25
|
+
padding: 24px;
|
|
26
|
+
height: 100%;
|
|
27
|
+
overflow-y: auto;
|
|
28
|
+
box-sizing: border-box;
|
|
29
|
+
}
|
|
30
|
+
`,
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
public render(): TemplateResult {
|
|
34
|
+
const systemFields: IConfigField[] = [
|
|
35
|
+
{ key: 'Base Directory', value: '/home/user/.serve.zone/dcrouter' },
|
|
36
|
+
{ key: 'Data Directory', value: '/home/user/.serve.zone/dcrouter/data' },
|
|
37
|
+
{ key: 'Public IP', value: '203.0.113.50' },
|
|
38
|
+
{ key: 'Proxy IPs', value: ['203.0.113.10', '203.0.113.11'], type: 'pills' },
|
|
39
|
+
{ key: 'Uptime', value: '3d 14h 22m' },
|
|
40
|
+
{ key: 'Storage Backend', value: 'filesystem', type: 'badge' },
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const proxyFields: IConfigField[] = [
|
|
44
|
+
{ key: 'Route Count', value: 12 },
|
|
45
|
+
{ key: 'ACME Enabled', value: true, type: 'boolean' },
|
|
46
|
+
{ key: 'Account Email', value: 'admin@serve.zone' },
|
|
47
|
+
{ key: 'Use Production', value: true, type: 'boolean' },
|
|
48
|
+
{ key: 'Auto Renew', value: true, type: 'boolean' },
|
|
49
|
+
{ key: 'Renew Threshold', value: '30 days' },
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const emailFields: IConfigField[] = [
|
|
53
|
+
{ key: 'Ports', value: ['25', '465', '587'], type: 'pills' },
|
|
54
|
+
{ key: 'Hostname', value: 'mail.serve.zone' },
|
|
55
|
+
{ key: 'Domains', value: ['serve.zone', 'mail.serve.zone'], type: 'pills' },
|
|
56
|
+
{ key: 'Email Routes', value: 5 },
|
|
57
|
+
{ key: 'Received Path', value: '/data/emails' },
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
const dnsFields: IConfigField[] = [
|
|
61
|
+
{ key: 'Port', value: 53 },
|
|
62
|
+
{ key: 'NS Domains', value: ['ns1.serve.zone', 'ns2.serve.zone'], type: 'pills' },
|
|
63
|
+
{ key: 'Scopes', value: ['serve.zone', 'example.com'], type: 'pills' },
|
|
64
|
+
{ key: 'Record Count', value: 24 },
|
|
65
|
+
{ key: 'DNS Challenge', value: true, type: 'boolean' },
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
const tlsFields: IConfigField[] = [
|
|
69
|
+
{ key: 'Contact Email', value: 'admin@serve.zone' },
|
|
70
|
+
{ key: 'Domain', value: 'serve.zone' },
|
|
71
|
+
{ key: 'Source', value: 'acme', type: 'badge' },
|
|
72
|
+
{ key: 'Certificate Path', value: null },
|
|
73
|
+
{ key: 'Key Path', value: null },
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
const cacheFields: IConfigField[] = [
|
|
77
|
+
{ key: 'Storage Path', value: '/home/user/.serve.zone/dcrouter/tsmdb' },
|
|
78
|
+
{ key: 'DB Name', value: 'dcrouter' },
|
|
79
|
+
{ key: 'Default TTL', value: '30 days' },
|
|
80
|
+
{ key: 'Cleanup Interval', value: '1 hour' },
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
const radiusFields: IConfigField[] = [
|
|
84
|
+
{ key: 'Auth Port', value: null },
|
|
85
|
+
{ key: 'Accounting Port', value: null },
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
const remoteIngressFields: IConfigField[] = [
|
|
89
|
+
{ key: 'Tunnel Port', value: 8443 },
|
|
90
|
+
{ key: 'Hub Domain', value: 'hub.serve.zone' },
|
|
91
|
+
{ key: 'TLS Configured', value: true, type: 'boolean' },
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
return html`
|
|
95
|
+
<sz-config-overview
|
|
96
|
+
infoText="This view displays the current running configuration. DcRouter is configured through code or remote management."
|
|
97
|
+
>
|
|
98
|
+
<sz-config-section
|
|
99
|
+
title="System"
|
|
100
|
+
subtitle="Base paths and infrastructure"
|
|
101
|
+
icon="lucide:server"
|
|
102
|
+
status="enabled"
|
|
103
|
+
.fields=${systemFields}
|
|
104
|
+
></sz-config-section>
|
|
105
|
+
|
|
106
|
+
<sz-config-section
|
|
107
|
+
title="SmartProxy"
|
|
108
|
+
subtitle="HTTP/HTTPS and TCP/SNI reverse proxy"
|
|
109
|
+
icon="lucide:network"
|
|
110
|
+
status="enabled"
|
|
111
|
+
.fields=${proxyFields}
|
|
112
|
+
></sz-config-section>
|
|
113
|
+
|
|
114
|
+
<sz-config-section
|
|
115
|
+
title="Email Server"
|
|
116
|
+
subtitle="SMTP email handling with smartmta"
|
|
117
|
+
icon="lucide:mail"
|
|
118
|
+
status="enabled"
|
|
119
|
+
.fields=${emailFields}
|
|
120
|
+
></sz-config-section>
|
|
121
|
+
|
|
122
|
+
<sz-config-section
|
|
123
|
+
title="DNS Server"
|
|
124
|
+
subtitle="Authoritative DNS with smartdns"
|
|
125
|
+
icon="lucide:globe"
|
|
126
|
+
status="enabled"
|
|
127
|
+
.fields=${dnsFields}
|
|
128
|
+
></sz-config-section>
|
|
129
|
+
|
|
130
|
+
<sz-config-section
|
|
131
|
+
title="TLS / Certificates"
|
|
132
|
+
subtitle="Certificate management and ACME"
|
|
133
|
+
icon="lucide:shield-check"
|
|
134
|
+
status="enabled"
|
|
135
|
+
.fields=${tlsFields}
|
|
136
|
+
></sz-config-section>
|
|
137
|
+
|
|
138
|
+
<sz-config-section
|
|
139
|
+
title="Cache Database"
|
|
140
|
+
subtitle="Persistent caching with smartdata"
|
|
141
|
+
icon="lucide:database"
|
|
142
|
+
status="enabled"
|
|
143
|
+
.fields=${cacheFields}
|
|
144
|
+
></sz-config-section>
|
|
145
|
+
|
|
146
|
+
<sz-config-section
|
|
147
|
+
title="RADIUS Server"
|
|
148
|
+
subtitle="Network authentication and VLAN assignment"
|
|
149
|
+
icon="lucide:wifi"
|
|
150
|
+
status="not-configured"
|
|
151
|
+
.fields=${radiusFields}
|
|
152
|
+
></sz-config-section>
|
|
153
|
+
|
|
154
|
+
<sz-config-section
|
|
155
|
+
title="Remote Ingress"
|
|
156
|
+
subtitle="Edge tunnel nodes"
|
|
157
|
+
icon="lucide:cloud"
|
|
158
|
+
status="enabled"
|
|
159
|
+
.fields=${remoteIngressFields}
|
|
160
|
+
></sz-config-section>
|
|
161
|
+
</sz-config-overview>
|
|
162
|
+
`;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DeesElement,
|
|
3
|
+
customElement,
|
|
4
|
+
html,
|
|
5
|
+
css,
|
|
6
|
+
cssManager,
|
|
7
|
+
state,
|
|
8
|
+
type TemplateResult,
|
|
9
|
+
} from '@design.estate/dees-element';
|
|
10
|
+
import type { DeesAppui } from '@design.estate/dees-catalog';
|
|
11
|
+
import type { IRouteConfig } from './sz-route-card.js';
|
|
12
|
+
import './index.js';
|
|
13
|
+
|
|
14
|
+
declare global {
|
|
15
|
+
interface HTMLElementTagNameMap {
|
|
16
|
+
'sz-demo-view-routes': SzDemoViewRoutes;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@customElement('sz-demo-view-routes')
|
|
21
|
+
export class SzDemoViewRoutes extends DeesElement {
|
|
22
|
+
private appui: DeesAppui | null = null;
|
|
23
|
+
|
|
24
|
+
@state()
|
|
25
|
+
private accessor currentTab: 'all' | 'https' | 'email' | 'dns' = 'all';
|
|
26
|
+
|
|
27
|
+
private demoRoutes: IRouteConfig[] = [
|
|
28
|
+
// 1. HTTPS with TLS termination + auto cert
|
|
29
|
+
{
|
|
30
|
+
id: 'route-1',
|
|
31
|
+
name: 'Web Frontend',
|
|
32
|
+
description: 'Main website with TLS termination and automatic certificates',
|
|
33
|
+
enabled: true,
|
|
34
|
+
priority: 10,
|
|
35
|
+
tags: ['web', 'https', 'production'],
|
|
36
|
+
match: {
|
|
37
|
+
ports: 443,
|
|
38
|
+
domains: ['serve.zone', 'www.serve.zone'],
|
|
39
|
+
protocol: 'http',
|
|
40
|
+
},
|
|
41
|
+
action: {
|
|
42
|
+
type: 'forward',
|
|
43
|
+
targets: [{ host: '10.0.0.10', port: 3000 }],
|
|
44
|
+
tls: { mode: 'terminate', certificate: 'auto' },
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
// 2. HTTP to HTTPS redirect
|
|
48
|
+
{
|
|
49
|
+
id: 'route-2',
|
|
50
|
+
name: 'HTTP Redirect',
|
|
51
|
+
description: 'Redirects all HTTP traffic to HTTPS',
|
|
52
|
+
enabled: true,
|
|
53
|
+
priority: 100,
|
|
54
|
+
tags: ['web', 'http', 'redirect'],
|
|
55
|
+
match: {
|
|
56
|
+
ports: 80,
|
|
57
|
+
domains: ['serve.zone', 'www.serve.zone'],
|
|
58
|
+
protocol: 'http',
|
|
59
|
+
},
|
|
60
|
+
action: {
|
|
61
|
+
type: 'socket-handler',
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
// 3. Email SMTP route
|
|
65
|
+
{
|
|
66
|
+
id: 'route-3',
|
|
67
|
+
name: 'SMTP Inbound',
|
|
68
|
+
description: 'Inbound email relay for serve.zone domain',
|
|
69
|
+
enabled: true,
|
|
70
|
+
tags: ['email', 'smtp', 'production'],
|
|
71
|
+
match: {
|
|
72
|
+
ports: 25,
|
|
73
|
+
domains: 'mail.serve.zone',
|
|
74
|
+
},
|
|
75
|
+
action: {
|
|
76
|
+
type: 'forward',
|
|
77
|
+
targets: [{ host: '10.0.1.5', port: 25 }],
|
|
78
|
+
tls: { mode: 'terminate', certificate: 'auto' },
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
// 4. API gateway with path matching, rate limiting, CORS
|
|
82
|
+
{
|
|
83
|
+
id: 'route-4',
|
|
84
|
+
name: 'API Gateway',
|
|
85
|
+
description: 'API gateway with rate limiting, CORS headers, and load balancing',
|
|
86
|
+
enabled: true,
|
|
87
|
+
priority: 20,
|
|
88
|
+
tags: ['web', 'api', 'https', 'production'],
|
|
89
|
+
match: {
|
|
90
|
+
ports: 443,
|
|
91
|
+
domains: 'api.serve.zone',
|
|
92
|
+
path: '/v2/*',
|
|
93
|
+
protocol: 'http',
|
|
94
|
+
},
|
|
95
|
+
action: {
|
|
96
|
+
type: 'forward',
|
|
97
|
+
targets: [
|
|
98
|
+
{ host: ['10.0.0.20', '10.0.0.21', '10.0.0.22'], port: 8080 },
|
|
99
|
+
],
|
|
100
|
+
tls: { mode: 'terminate', certificate: 'auto' },
|
|
101
|
+
loadBalancing: { algorithm: 'round-robin' },
|
|
102
|
+
},
|
|
103
|
+
security: {
|
|
104
|
+
rateLimit: { enabled: true, maxRequests: 200, window: 60 },
|
|
105
|
+
maxConnections: 5000,
|
|
106
|
+
},
|
|
107
|
+
headers: {
|
|
108
|
+
response: {
|
|
109
|
+
'Access-Control-Allow-Origin': '*',
|
|
110
|
+
'X-Request-Id': '{{requestId}}',
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
// 5. WebSocket route
|
|
115
|
+
{
|
|
116
|
+
id: 'route-5',
|
|
117
|
+
name: 'WebSocket Realtime',
|
|
118
|
+
description: 'Real-time WebSocket connections for live updates',
|
|
119
|
+
enabled: true,
|
|
120
|
+
tags: ['web', 'https', 'websocket'],
|
|
121
|
+
match: {
|
|
122
|
+
ports: 443,
|
|
123
|
+
domains: 'ws.serve.zone',
|
|
124
|
+
path: '/ws/*',
|
|
125
|
+
protocol: 'http',
|
|
126
|
+
},
|
|
127
|
+
action: {
|
|
128
|
+
type: 'forward',
|
|
129
|
+
targets: [{ host: '10.0.0.30', port: 9090 }],
|
|
130
|
+
tls: { mode: 'terminate', certificate: 'auto' },
|
|
131
|
+
websocket: { enabled: true },
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
// 6. Wildcard domain route
|
|
135
|
+
{
|
|
136
|
+
id: 'route-6',
|
|
137
|
+
name: 'Tenant Wildcard',
|
|
138
|
+
description: 'Multi-tenant wildcard routing for customer subdomains',
|
|
139
|
+
enabled: true,
|
|
140
|
+
priority: 50,
|
|
141
|
+
tags: ['web', 'https', 'multi-tenant'],
|
|
142
|
+
match: {
|
|
143
|
+
ports: 443,
|
|
144
|
+
domains: '*.customers.serve.zone',
|
|
145
|
+
protocol: 'http',
|
|
146
|
+
},
|
|
147
|
+
action: {
|
|
148
|
+
type: 'forward',
|
|
149
|
+
targets: [{ host: '10.0.0.40', port: 8080 }],
|
|
150
|
+
tls: { mode: 'terminate', certificate: 'auto' },
|
|
151
|
+
},
|
|
152
|
+
security: {
|
|
153
|
+
ipAllowList: ['10.0.0.0/8', '172.16.0.0/12'],
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
// 7. Load-balanced route with health check
|
|
157
|
+
{
|
|
158
|
+
id: 'route-7',
|
|
159
|
+
name: 'Microservices LB',
|
|
160
|
+
description: 'Load-balanced microservices backend with IP-hash affinity',
|
|
161
|
+
enabled: true,
|
|
162
|
+
tags: ['web', 'https', 'production'],
|
|
163
|
+
match: {
|
|
164
|
+
ports: [443, 8443],
|
|
165
|
+
domains: 'services.serve.zone',
|
|
166
|
+
protocol: 'http',
|
|
167
|
+
},
|
|
168
|
+
action: {
|
|
169
|
+
type: 'forward',
|
|
170
|
+
targets: [
|
|
171
|
+
{ host: ['10.0.2.1', '10.0.2.2', '10.0.2.3', '10.0.2.4'], port: 3000 },
|
|
172
|
+
],
|
|
173
|
+
tls: { mode: 'terminate-and-reencrypt', certificate: 'auto' },
|
|
174
|
+
loadBalancing: { algorithm: 'ip-hash' },
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
// 8. DNS-over-HTTPS route
|
|
178
|
+
{
|
|
179
|
+
id: 'route-8',
|
|
180
|
+
name: 'DNS over HTTPS',
|
|
181
|
+
description: 'DNS-over-HTTPS resolver endpoint',
|
|
182
|
+
enabled: true,
|
|
183
|
+
tags: ['dns', 'https'],
|
|
184
|
+
match: {
|
|
185
|
+
ports: 443,
|
|
186
|
+
domains: 'dns.serve.zone',
|
|
187
|
+
path: '/dns-query',
|
|
188
|
+
protocol: 'http',
|
|
189
|
+
},
|
|
190
|
+
action: {
|
|
191
|
+
type: 'forward',
|
|
192
|
+
targets: [{ host: '10.0.3.1', port: 8053 }],
|
|
193
|
+
tls: { mode: 'terminate', certificate: 'auto' },
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
// 9. NFTables high-performance route
|
|
197
|
+
{
|
|
198
|
+
id: 'route-9',
|
|
199
|
+
name: 'High-Perf TCP Proxy',
|
|
200
|
+
description: 'NFTables-accelerated TCP proxy for game servers',
|
|
201
|
+
enabled: true,
|
|
202
|
+
tags: ['tcp', 'nftables', 'production'],
|
|
203
|
+
match: {
|
|
204
|
+
ports: [{ from: 27000, to: 27050 }],
|
|
205
|
+
protocol: 'tcp',
|
|
206
|
+
},
|
|
207
|
+
action: {
|
|
208
|
+
type: 'forward',
|
|
209
|
+
targets: [{ host: '10.0.4.1', port: 'preserve' }],
|
|
210
|
+
forwardingEngine: 'nftables',
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
// 10. Disabled maintenance route
|
|
214
|
+
{
|
|
215
|
+
id: 'route-10',
|
|
216
|
+
name: 'Legacy Admin Panel',
|
|
217
|
+
description: 'Deprecated admin panel — disabled for maintenance',
|
|
218
|
+
enabled: false,
|
|
219
|
+
tags: ['web', 'https', 'deprecated'],
|
|
220
|
+
match: {
|
|
221
|
+
ports: 443,
|
|
222
|
+
domains: 'admin-old.serve.zone',
|
|
223
|
+
protocol: 'http',
|
|
224
|
+
},
|
|
225
|
+
action: {
|
|
226
|
+
type: 'socket-handler',
|
|
227
|
+
},
|
|
228
|
+
security: {
|
|
229
|
+
ipBlockList: ['0.0.0.0/0'],
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
];
|
|
233
|
+
|
|
234
|
+
private get filteredRoutes(): IRouteConfig[] {
|
|
235
|
+
if (this.currentTab === 'all') return this.demoRoutes;
|
|
236
|
+
if (this.currentTab === 'https') {
|
|
237
|
+
return this.demoRoutes.filter((r) =>
|
|
238
|
+
r.tags?.some((t) => ['web', 'https', 'http'].includes(t))
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
if (this.currentTab === 'email') {
|
|
242
|
+
return this.demoRoutes.filter((r) =>
|
|
243
|
+
r.tags?.some((t) => ['email', 'smtp'].includes(t))
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
if (this.currentTab === 'dns') {
|
|
247
|
+
return this.demoRoutes.filter((r) =>
|
|
248
|
+
r.tags?.some((t) => ['dns'].includes(t))
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
return this.demoRoutes;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async onActivate(context: { appui: DeesAppui; viewId: string }) {
|
|
255
|
+
this.appui = context.appui;
|
|
256
|
+
|
|
257
|
+
this.appui.setContentTabs([
|
|
258
|
+
{
|
|
259
|
+
key: 'All Routes',
|
|
260
|
+
action: () => {
|
|
261
|
+
this.currentTab = 'all';
|
|
262
|
+
this.updateSecondaryMenu();
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
key: 'HTTP/S',
|
|
267
|
+
action: () => {
|
|
268
|
+
this.currentTab = 'https';
|
|
269
|
+
this.updateSecondaryMenu();
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
key: 'Email',
|
|
274
|
+
action: () => {
|
|
275
|
+
this.currentTab = 'email';
|
|
276
|
+
this.updateSecondaryMenu();
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
key: 'DNS',
|
|
281
|
+
action: () => {
|
|
282
|
+
this.currentTab = 'dns';
|
|
283
|
+
this.updateSecondaryMenu();
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
]);
|
|
287
|
+
|
|
288
|
+
this.updateSecondaryMenu();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
private updateSecondaryMenu() {
|
|
292
|
+
if (!this.appui) return;
|
|
293
|
+
|
|
294
|
+
const total = this.demoRoutes.length;
|
|
295
|
+
const active = this.demoRoutes.filter((r) => r.enabled !== false).length;
|
|
296
|
+
const forwardCount = this.demoRoutes.filter((r) => r.action.type === 'forward').length;
|
|
297
|
+
|
|
298
|
+
this.appui.setSecondaryMenu({
|
|
299
|
+
heading: 'Routes',
|
|
300
|
+
groups: [
|
|
301
|
+
{
|
|
302
|
+
name: 'Actions',
|
|
303
|
+
items: [
|
|
304
|
+
{
|
|
305
|
+
type: 'action',
|
|
306
|
+
key: 'Refresh',
|
|
307
|
+
iconName: 'lucide:RefreshCw',
|
|
308
|
+
action: () => {
|
|
309
|
+
console.log('Refresh routes');
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
type: 'action',
|
|
314
|
+
key: 'Add Route',
|
|
315
|
+
iconName: 'lucide:Plus',
|
|
316
|
+
action: () => {
|
|
317
|
+
console.log('Add route');
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
],
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
name: 'Statistics',
|
|
324
|
+
items: [
|
|
325
|
+
{ type: 'header' as const, label: `${total} Total Routes` },
|
|
326
|
+
{ type: 'header' as const, label: `${active} Active` },
|
|
327
|
+
{ type: 'header' as const, label: `${forwardCount} Forward` },
|
|
328
|
+
{ type: 'header' as const, label: `${total - forwardCount} Socket Handler` },
|
|
329
|
+
],
|
|
330
|
+
},
|
|
331
|
+
],
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
onDeactivate() {
|
|
336
|
+
// Cleanup if needed
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
public static styles = [
|
|
340
|
+
cssManager.defaultStyles,
|
|
341
|
+
css`
|
|
342
|
+
:host {
|
|
343
|
+
display: block;
|
|
344
|
+
padding: 24px;
|
|
345
|
+
height: 100%;
|
|
346
|
+
overflow-y: auto;
|
|
347
|
+
box-sizing: border-box;
|
|
348
|
+
}
|
|
349
|
+
`,
|
|
350
|
+
];
|
|
351
|
+
|
|
352
|
+
public render(): TemplateResult {
|
|
353
|
+
return html`
|
|
354
|
+
<sz-route-list-view
|
|
355
|
+
.routes=${this.filteredRoutes}
|
|
356
|
+
@route-click=${(e: CustomEvent<IRouteConfig>) => {
|
|
357
|
+
console.log('Route clicked:', e.detail.name);
|
|
358
|
+
}}
|
|
359
|
+
></sz-route-list-view>
|
|
360
|
+
`;
|
|
361
|
+
}
|
|
362
|
+
}
|