diff --git a/changelog.md b/changelog.md index 257bf7b..e885311 100644 --- a/changelog.md +++ b/changelog.md @@ -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 diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index da1b32c..55904c8 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -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.' } diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index da1b32c..55904c8 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -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.' } diff --git a/ts_web/elements/ops-view-apitokens.ts b/ts_web/elements/ops-view-apitokens.ts index 6802347..f2e715a 100644 --- a/ts_web/elements/ops-view-apitokens.ts +++ b/ts_web/elements/ops-view-apitokens.ts @@ -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), diff --git a/ts_web/elements/ops-view-certificates.ts b/ts_web/elements/ops-view-certificates.ts index 295baa5..80e401b 100644 --- a/ts_web/elements/ops-view-certificates.ts +++ b/ts_web/elements/ops-view-certificates.ts @@ -228,6 +228,7 @@ export class OpsViewCertificates extends DeesElement { return html` ({ Domain: cert.domain, Routes: this.renderRoutePills(cert.routeNames), diff --git a/ts_web/elements/ops-view-network.ts b/ts_web/elements/ops-view-network.ts index 976a98e..8765a77 100644 --- a/ts_web/elements/ops-view-network.ts +++ b/ts_web/elements/ops-view-network.ts @@ -323,6 +323,7 @@ export class OpsViewNetwork extends DeesElement { ({ Time: new Date(req.timestamp).toLocaleTimeString(), Protocol: html`${req.protocol.toUpperCase()}`, @@ -603,6 +604,7 @@ export class OpsViewNetwork extends DeesElement { return html` { const bw = bandwidthByIP.get(ipData.ip); return { @@ -630,6 +632,7 @@ export class OpsViewNetwork extends DeesElement { return html` { const totalErrors = item.connectErrors + item.handshakeErrors + item.requestErrors; const protocolClass = item.protocol.toLowerCase().replace(/[^a-z0-9]/g, ''); diff --git a/ts_web/elements/ops-view-networktargets.ts b/ts_web/elements/ops-view-networktargets.ts index 662b032..2b1f206 100644 --- a/ts_web/elements/ops-view-networktargets.ts +++ b/ts_web/elements/ops-view-networktargets.ts @@ -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, diff --git a/ts_web/elements/ops-view-remoteingress.ts b/ts_web/elements/ops-view-remoteingress.ts index 450b230..db08d84 100644 --- a/ts_web/elements/ops-view-remoteingress.ts +++ b/ts_web/elements/ops-view-remoteingress.ts @@ -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), diff --git a/ts_web/elements/ops-view-security.ts b/ts_web/elements/ops-view-security.ts index 03a6620..a16a4c2 100644 --- a/ts_web/elements/ops-view-security.ts +++ b/ts_web/elements/ops-view-security.ts @@ -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, diff --git a/ts_web/elements/ops-view-sourceprofiles.ts b/ts_web/elements/ops-view-sourceprofiles.ts index cd20c80..f9693eb 100644 --- a/ts_web/elements/ops-view-sourceprofiles.ts +++ b/ts_web/elements/ops-view-sourceprofiles.ts @@ -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 || '-', diff --git a/ts_web/elements/ops-view-targetprofiles.ts b/ts_web/elements/ops-view-targetprofiles.ts index 48513a6..ad21b3c 100644 --- a/ts_web/elements/ops-view-targetprofiles.ts +++ b/ts_web/elements/ops-view-targetprofiles.ts @@ -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 || '-', diff --git a/ts_web/elements/ops-view-vpn.ts b/ts_web/elements/ops-view-vpn.ts index f5ada74..98658ea 100644 --- a/ts_web/elements/ops-view-vpn.ts +++ b/ts_web/elements/ops-view-vpn.ts @@ -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;