mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 15:51:30 +00:00
feat(gui): add discovery triage, network scan management, and approval workflow pages (M24)
Three new GUI surfaces closing the backend-to-frontend gap for V2: - Discovery triage page: summary stats bar, DataTable with claim/dismiss actions, status/agent filters, collapsible scan history panel - Network scan target management: CRUD with create modal, enable/disable toggle, Scan Now button, last scan results display - Jobs page approval workflow: Approve/Reject buttons for AwaitingApproval jobs, rejection reason modal, pending approval banner with count, AwaitingApproval/AwaitingCSR added to status filter dropdown Also adds 13 new frontend tests, 4 API types, 12 API client functions, 2 sidebar nav items, 2 routes, and discovery status badge styles. Docs updated: README, architecture, quickstart, demo-advanced, CLAUDE.md, roadmap. Version bumped to v2.0.4. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+48
-1
@@ -1,4 +1,4 @@
|
||||
import type { Certificate, CertificateVersion, Agent, Job, Notification, AuditEvent, PolicyRule, PolicyViolation, Issuer, Target, CertificateProfile, Owner, Team, AgentGroup, PaginatedResponse, DashboardSummary, CertificateStatusCount, ExpirationBucket, JobTrendDataPoint, IssuanceRateDataPoint, MetricsResponse } from './types';
|
||||
import type { Certificate, CertificateVersion, Agent, Job, Notification, AuditEvent, PolicyRule, PolicyViolation, Issuer, Target, CertificateProfile, Owner, Team, AgentGroup, PaginatedResponse, DashboardSummary, CertificateStatusCount, ExpirationBucket, JobTrendDataPoint, IssuanceRateDataPoint, MetricsResponse, DiscoveredCertificate, DiscoveryScan, DiscoverySummary, NetworkScanTarget } from './types';
|
||||
|
||||
const BASE = '/api/v1';
|
||||
|
||||
@@ -258,6 +258,53 @@ export const approveRenewal = (jobId: string) =>
|
||||
export const rejectRenewal = (jobId: string, reason: string) =>
|
||||
fetchJSON<{ message: string }>(`${BASE}/jobs/${jobId}/reject`, { method: 'POST', body: JSON.stringify({ reason }) });
|
||||
|
||||
// Discovery
|
||||
export const getDiscoveredCertificates = (params: Record<string, string> = {}) => {
|
||||
const qs = new URLSearchParams({ page: '1', per_page: '50', ...params }).toString();
|
||||
return fetchJSON<PaginatedResponse<DiscoveredCertificate>>(`${BASE}/discovered-certificates?${qs}`);
|
||||
};
|
||||
|
||||
export const getDiscoveredCertificate = (id: string) =>
|
||||
fetchJSON<DiscoveredCertificate>(`${BASE}/discovered-certificates/${id}`);
|
||||
|
||||
export const claimDiscoveredCertificate = (id: string, managedCertificateId: string) =>
|
||||
fetchJSON<{ message: string }>(`${BASE}/discovered-certificates/${id}/claim`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ managed_certificate_id: managedCertificateId }),
|
||||
});
|
||||
|
||||
export const dismissDiscoveredCertificate = (id: string) =>
|
||||
fetchJSON<{ message: string }>(`${BASE}/discovered-certificates/${id}/dismiss`, { method: 'POST' });
|
||||
|
||||
export const getDiscoveryScans = (params: Record<string, string> = {}) => {
|
||||
const qs = new URLSearchParams({ page: '1', per_page: '50', ...params }).toString();
|
||||
return fetchJSON<PaginatedResponse<DiscoveryScan>>(`${BASE}/discovery-scans?${qs}`);
|
||||
};
|
||||
|
||||
export const getDiscoverySummary = () =>
|
||||
fetchJSON<DiscoverySummary>(`${BASE}/discovery-summary`);
|
||||
|
||||
// Network Scan Targets
|
||||
export const getNetworkScanTargets = (params: Record<string, string> = {}) => {
|
||||
const qs = new URLSearchParams({ page: '1', per_page: '50', ...params }).toString();
|
||||
return fetchJSON<PaginatedResponse<NetworkScanTarget>>(`${BASE}/network-scan-targets?${qs}`);
|
||||
};
|
||||
|
||||
export const getNetworkScanTarget = (id: string) =>
|
||||
fetchJSON<NetworkScanTarget>(`${BASE}/network-scan-targets/${id}`);
|
||||
|
||||
export const createNetworkScanTarget = (data: Partial<NetworkScanTarget>) =>
|
||||
fetchJSON<NetworkScanTarget>(`${BASE}/network-scan-targets`, { method: 'POST', body: JSON.stringify(data) });
|
||||
|
||||
export const updateNetworkScanTarget = (id: string, data: Partial<NetworkScanTarget>) =>
|
||||
fetchJSON<NetworkScanTarget>(`${BASE}/network-scan-targets/${id}`, { method: 'PUT', body: JSON.stringify(data) });
|
||||
|
||||
export const deleteNetworkScanTarget = (id: string) =>
|
||||
fetchJSON<{ message: string }>(`${BASE}/network-scan-targets/${id}`, { method: 'DELETE' });
|
||||
|
||||
export const triggerNetworkScan = (id: string) =>
|
||||
fetchJSON<{ message: string }>(`${BASE}/network-scan-targets/${id}/scan`, { method: 'POST' });
|
||||
|
||||
// Stats
|
||||
export const getDashboardSummary = () =>
|
||||
fetchJSON<DashboardSummary>(`${BASE}/stats/summary`);
|
||||
|
||||
Reference in New Issue
Block a user