Compare commits

...

2 Commits

Author SHA1 Message Date
2bc2475878 v13.2.0
Some checks failed
Docker (tags) / security (push) Failing after 0s
Docker (tags) / test (push) Has been skipped
Docker (tags) / release (push) Has been skipped
Docker (tags) / metadata (push) Has been skipped
2026-04-08 07:11:21 +00:00
37eab7c7b1 feat(ops-ui): add column filters to operations tables across admin views 2026-04-08 07:11:21 +00:00
13 changed files with 22 additions and 3 deletions

View File

@@ -1,5 +1,11 @@
# Changelog
## 2026-04-08 - 13.2.0 - feat(ops-ui)
add column filters to operations tables across admin views
- Enable table column filters for API tokens, certificates, network requests, top IPs, backends, network targets, remote ingress edges, security views, source profiles, target profiles, and VPN clients.
- Improves filtering and exploration of operational data throughout the admin interface without changing backend behavior.
## 2026-04-08 - 13.1.3 - fix(certificate-handler)
preserve wildcard coverage during forced certificate renewals and propagate renewed certs to sibling domains

View File

@@ -1,7 +1,7 @@
{
"name": "@serve.zone/dcrouter",
"private": false,
"version": "13.1.3",
"version": "13.2.0",
"description": "A multifaceted routing service handling mail and SMS delivery functions.",
"type": "module",
"exports": {

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@serve.zone/dcrouter',
version: '13.1.3',
version: '13.2.0',
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
}

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@serve.zone/dcrouter',
version: '13.1.3',
version: '13.2.0',
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
}

View File

@@ -109,6 +109,7 @@ export class OpsViewApiTokens extends DeesElement {
.data=${apiTokens}
.dataName=${'token'}
.searchable=${true}
.showColumnFilters=${true}
.displayFunction=${(token: interfaces.data.IApiTokenInfo) => ({
name: token.name,
scopes: this.renderScopePills(token.scopes),

View File

@@ -228,6 +228,7 @@ export class OpsViewCertificates extends DeesElement {
return html`
<dees-table
.data=${this.certState.certificates}
.showColumnFilters=${true}
.displayFunction=${(cert: interfaces.requests.ICertificateInfo) => ({
Domain: cert.domain,
Routes: this.renderRoutePills(cert.routeNames),

View File

@@ -323,6 +323,7 @@ export class OpsViewNetwork extends DeesElement {
<!-- Requests Table -->
<dees-table
.data=${this.networkRequests}
.showColumnFilters=${true}
.displayFunction=${(req: INetworkRequest) => ({
Time: new Date(req.timestamp).toLocaleTimeString(),
Protocol: html`<span class="protocolBadge ${req.protocol}">${req.protocol.toUpperCase()}</span>`,
@@ -603,6 +604,7 @@ export class OpsViewNetwork extends DeesElement {
return html`
<dees-table
.data=${this.networkState.topIPs}
.showColumnFilters=${true}
.displayFunction=${(ipData: { ip: string; count: number }) => {
const bw = bandwidthByIP.get(ipData.ip);
return {
@@ -630,6 +632,7 @@ export class OpsViewNetwork extends DeesElement {
return html`
<dees-table
.data=${backends}
.showColumnFilters=${true}
.displayFunction=${(item: interfaces.data.IBackendInfo) => {
const totalErrors = item.connectErrors + item.handshakeErrors + item.requestErrors;
const protocolClass = item.protocol.toLowerCase().replace(/[^a-z0-9]/g, '');

View File

@@ -71,6 +71,7 @@ export class OpsViewNetworkTargets extends DeesElement {
.heading1=${'Network Targets'}
.heading2=${'Reusable host:port destinations for routes'}
.data=${targets}
.showColumnFilters=${true}
.displayFunction=${(target: interfaces.data.INetworkTarget) => ({
Name: target.name,
Host: Array.isArray(target.host) ? target.host.join(', ') : target.host,

View File

@@ -220,6 +220,7 @@ export class OpsViewRemoteIngress extends DeesElement {
.heading1=${'Edge Nodes'}
.heading2=${'Manage remote ingress edge registrations'}
.data=${this.riState.edges}
.showColumnFilters=${true}
.displayFunction=${(edge: interfaces.data.IRemoteIngress) => ({
name: edge.name,
status: this.getEdgeStatusHtml(edge),

View File

@@ -206,6 +206,7 @@ export class OpsViewSecurity extends DeesElement {
.heading1=${'Security Events'}
.heading2=${'Last 24 hours'}
.data=${this.getSecurityEvents(metrics)}
.showColumnFilters=${true}
.displayFunction=${(item) => ({
'Time': new Date(item.timestamp).toLocaleTimeString(),
'Event': item.event,
@@ -241,6 +242,7 @@ export class OpsViewSecurity extends DeesElement {
.heading1=${'Blocked IP Addresses'}
.heading2=${'IPs blocked due to suspicious activity'}
.data=${blockedIPs.map((ip) => ({ ip }))}
.showColumnFilters=${true}
.displayFunction=${(item) => ({
'IP Address': item.ip,
'Reason': 'Suspicious activity',
@@ -314,6 +316,7 @@ export class OpsViewSecurity extends DeesElement {
.heading1=${'Login History'}
.heading2=${'Recent authentication attempts'}
.data=${loginHistory}
.showColumnFilters=${true}
.displayFunction=${(item) => ({
'Time': new Date(item.timestamp).toLocaleString(),
'Username': item.username,

View File

@@ -71,6 +71,7 @@ export class OpsViewSourceProfiles extends DeesElement {
.heading1=${'Source Profiles'}
.heading2=${'Reusable source configurations for routes'}
.data=${profiles}
.showColumnFilters=${true}
.displayFunction=${(profile: interfaces.data.ISourceProfile) => ({
Name: profile.name,
Description: profile.description || '-',

View File

@@ -84,6 +84,7 @@ export class OpsViewTargetProfiles extends DeesElement {
.heading1=${'Target Profiles'}
.heading2=${'Define what resources VPN clients can access'}
.data=${profiles}
.showColumnFilters=${true}
.displayFunction=${(profile: interfaces.data.ITargetProfile) => ({
Name: profile.name,
Description: profile.description || '-',

View File

@@ -305,6 +305,7 @@ export class OpsViewVpn extends DeesElement {
.heading1=${'VPN Clients'}
.heading2=${'Manage WireGuard and SmartVPN client registrations'}
.data=${clients}
.showColumnFilters=${true}
.displayFunction=${(client: interfaces.data.IVpnClient) => {
const conn = this.getConnectedInfo(client);
let statusHtml;