diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..83eb48b3 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,109 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@biomejs/biome': + specifier: 2.4.3 + version: 2.4.3 + +packages: + + '@biomejs/biome@2.4.3': + resolution: {integrity: sha512-cBrjf6PNF6yfL8+kcNl85AjiK2YHNsbU0EvDOwiZjBPbMbQ5QcgVGFpjD0O52p8nec5O8NYw7PKw3xUR7fPAkQ==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@2.4.3': + resolution: {integrity: sha512-eOafSFlI/CF4id2tlwq9CVHgeEqvTL5SrhWff6ZORp6S3NL65zdsR3ugybItkgF8Pf4D9GSgtbB6sE3UNgOM9w==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@2.4.3': + resolution: {integrity: sha512-V2+av4ilbWcBMNufTtMMXVW00nPwyIjI5qf7n9wSvUaZ+tt0EvMGk46g9sAFDJBEDOzSyoRXiSP6pCvKTOEbPA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@2.4.3': + resolution: {integrity: sha512-QuFzvsGo8BA4Xm7jGX5idkw6BqFblcCPySMTvq0AhGYnhUej5VJIDJbmTKfHqwjHepZiC4fA+T5i6wmiZolZNw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@biomejs/cli-linux-arm64@2.4.3': + resolution: {integrity: sha512-0m+O0x9FgK99FAwDK+fiDtjs2wnqq7bvfj17KJVeCkTwT/liI+Q9njJG7lwXK0iSJVXeFNRIxukpVI3SifMYAA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@biomejs/cli-linux-x64-musl@2.4.3': + resolution: {integrity: sha512-qEc0OCpj/uytruQ4wLM0yWNJLZy0Up8H1Er5MW3SrstqM6J2d4XqdNA86xzCy8MQCHpoVZ3lFye3GBlIL4/ljw==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@biomejs/cli-linux-x64@2.4.3': + resolution: {integrity: sha512-NVqh0saIU0u5OfOp/0jFdlKRE59+XyMvWmtx0f6Nm/2OpdxBl04coRIftBbY9d1gfu+23JVv4CItAqPYrjYh5w==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@biomejs/cli-win32-arm64@2.4.3': + resolution: {integrity: sha512-gRO96vrIARilv/Cp2ZnmNNL5LSZg3RO75GPp13hsLO3N4YVpE7saaMDp2bcyV48y2N2Pbit1brkGVGta0yd6VQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.4.3': + resolution: {integrity: sha512-vSm/vOJe06pf14aGHfHl3Ar91Nlx4YYmohElDJ+17UbRwe99n987S/MhAlQOkONqf1utJor04ChkCPmKb8SWdw==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + +snapshots: + + '@biomejs/biome@2.4.3': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.4.3 + '@biomejs/cli-darwin-x64': 2.4.3 + '@biomejs/cli-linux-arm64': 2.4.3 + '@biomejs/cli-linux-arm64-musl': 2.4.3 + '@biomejs/cli-linux-x64': 2.4.3 + '@biomejs/cli-linux-x64-musl': 2.4.3 + '@biomejs/cli-win32-arm64': 2.4.3 + '@biomejs/cli-win32-x64': 2.4.3 + + '@biomejs/cli-darwin-arm64@2.4.3': + optional: true + + '@biomejs/cli-darwin-x64@2.4.3': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.4.3': + optional: true + + '@biomejs/cli-linux-arm64@2.4.3': + optional: true + + '@biomejs/cli-linux-x64-musl@2.4.3': + optional: true + + '@biomejs/cli-linux-x64@2.4.3': + optional: true + + '@biomejs/cli-win32-arm64@2.4.3': + optional: true + + '@biomejs/cli-win32-x64@2.4.3': + optional: true diff --git a/src/filigree/static/js/app.js b/src/filigree/static/js/app.js index b4ecd615..af441385 100644 --- a/src/filigree/static/js/app.js +++ b/src/filigree/static/js/app.js @@ -11,6 +11,7 @@ // --- Module imports --- +import { computeHealthScore, computeImpactScores } from "./analytics.js"; import { fetchAllData, fetchDashboardConfig, fetchFileSchema, fetchProjects } from "./api.js"; import { applyFilters, @@ -21,15 +22,15 @@ import { callbacks as filtersCallbacks, loadPreset, loadProjectFilterSettings, + onDoneTimeBoundChange, populatePresets, - savePreset, populateTypeFilter, + savePreset, toggleBlocked, toggleCardSelect, toggleMultiSelect, toggleReady, toggleStatusPill, - onDoneTimeBoundChange, trackChanges, updateTypeFilterUI, } from "./filters.js"; @@ -48,9 +49,9 @@ import { batchSetPriority, closeSettingsMenu, copyIssueId, + endTour, escHtml, escJsSingleAttr, - endTour, reloadServer, showCreateForm, showToast, @@ -82,22 +83,40 @@ import { showAddBlocker, updateIssue, } from "./views/detail.js"; -import { computeHealthScore, computeImpactScores } from "./analytics.js"; +import { + clearScanSourceFilter, + closeFileDetail, + closeFinding, + createIssueFromFinding, + filesPageNext, + filesPagePrev, + filterFindings, + filterTimeline, + loadFiles, + loadMoreFindings, + loadMoreTimeline, + openFileDetail, + selectFinding, + showLinkIssueModal, + sortFiles, + submitLinkIssue, + switchFileTab, +} from "./views/files.js"; import { callbacks as graphCallbacks, graphFit, - renderGraph, refreshCriticalPathState, + renderGraph, setCriticalPathStateFromPath, showHealthBreakdown, toggleCriticalPath, } from "./views/graph.js"; import { - renderGraphSidebar, - graphSidebarSelectAll, + attachSidebarListeners, graphSidebarClearAll, + graphSidebarSelectAll, rebuildTreeIndex, - attachSidebarListeners, + renderGraphSidebar, callbacks as sidebarCallbacks, } from "./views/graphSidebar.js"; import { @@ -112,31 +131,7 @@ import { showStaleIssues, updateStaleBadge, } from "./views/metrics.js"; -import { - loadPlanView, - loadWorkflow, - loadWorkflowInModal, - showWorkflowModal, -} from "./views/workflow.js"; -import { - closeFinding, - clearScanSourceFilter, - closeFileDetail, - createIssueFromFinding, - filesPageNext, - filesPagePrev, - filterFindings, - filterTimeline, - loadFiles, - loadMoreFindings, - loadMoreTimeline, - openFileDetail, - selectFinding, - showLinkIssueModal, - sortFiles, - submitLinkIssue, - switchFileTab, -} from "./views/files.js"; +import { loadReady } from "./views/ready.js"; import { collapseAllReleaseTree, loadReleases, @@ -145,7 +140,12 @@ import { toggleReleaseExpand, toggleReleaseTreeNode, } from "./views/releases.js"; -import { loadReady } from "./views/ready.js"; +import { + loadPlanView, + loadWorkflow, + loadWorkflowInModal, + showWorkflowModal, +} from "./views/workflow.js"; // --------------------------------------------------------------------------- // Core data fetching (lives here because it touches every module) diff --git a/src/filigree/static/js/views/detail.js b/src/filigree/static/js/views/detail.js index de6377e5..773879d6 100644 --- a/src/filigree/static/js/views/detail.js +++ b/src/filigree/static/js/views/detail.js @@ -116,7 +116,7 @@ export async function openDetail(issueId) { `` + `${escHtml(det.title.slice(0, 40))}` + `${escHtml(det.status || "")}` + - `` + `` ); }) .join(""); diff --git a/src/filigree/static/js/views/files.js b/src/filigree/static/js/views/files.js index de6602eb..bb906072 100644 --- a/src/filigree/static/js/views/files.js +++ b/src/filigree/static/js/views/files.js @@ -176,7 +176,7 @@ export async function loadFiles() { '' + escHtml(state.filesScanSource) + "" + - '' + + '' + "" : ""; @@ -346,7 +346,7 @@ function renderFileDetail(data) { // Header let html = '
' + - '' + + '' + `${escHtml(f.path)}` + "
"; diff --git a/src/filigree/static/js/views/graph.js b/src/filigree/static/js/views/graph.js index 557d5422..56a7a9a8 100644 --- a/src/filigree/static/js/views/graph.js +++ b/src/filigree/static/js/views/graph.js @@ -4,7 +4,7 @@ import { fetchCriticalPath } from "../api.js"; import { CATEGORY_COLORS, state, THEME_COLORS } from "../state.js"; -import { resolveGraphScope, handleGhostClick } from "./graphSidebar.js"; +import { handleGhostClick, resolveGraphScope } from "./graphSidebar.js"; // --- Callbacks for functions not yet available at import time --- @@ -319,7 +319,7 @@ export function renderGraph() { const filteredIds = new Set(filteredNodes.map((n) => n.id)); const search = document.getElementById("filterSearch")?.value?.toLowerCase().trim() || ""; - let cyNodes = filteredNodes.map((n) => { + const cyNodes = filteredNodes.map((n) => { const title = n.title || n.id; const isGhost = ghostIds.has(n.id); const matchesSearch = @@ -340,7 +340,7 @@ export function renderGraph() { }; }); - let cyEdges = scopeEdges + const cyEdges = scopeEdges .filter((e) => filteredIds.has(e.source) && filteredIds.has(e.target)) .map((e) => ({ data: { @@ -407,8 +407,7 @@ export function renderGraph() { state.cy.destroy(); const canReusePositions = - cyNodes.length > 0 && - cyNodes.every((n) => Object.prototype.hasOwnProperty.call(previousPositions, n.data.id)); + cyNodes.length > 0 && cyNodes.every((n) => Object.hasOwn(previousPositions, n.data.id)); const graphMinZoom = computeGraphMinZoom(cyNodes.length); state.cy = cytoscape({ container, @@ -495,7 +494,7 @@ export function showHealthBreakdown() { panel.innerHTML = '
' + `System Health: ${b.score}/100` + - '
' + + '' + ["blocked", "freshness", "ready", "balance"] .map((k) => { const f = b[k]; diff --git a/src/filigree/static/js/views/health.js b/src/filigree/static/js/views/health.js index 533cd906..ab4275f2 100644 --- a/src/filigree/static/js/views/health.js +++ b/src/filigree/static/js/views/health.js @@ -2,7 +2,7 @@ // Code Health view — hotspots, severity donut, scan coverage, recent scans. // --------------------------------------------------------------------------- -import { fetchFiles, fetchFileStats, fetchHotspots, fetchScanRuns } from "../api.js"; +import { fetchFileStats, fetchFiles, fetchHotspots, fetchScanRuns } from "../api.js"; import { SEVERITY_COLORS, state } from "../state.js"; import { escHtml, escJsSingleAttr, relativeTime } from "../ui.js"; diff --git a/src/filigree/static/js/views/ready.js b/src/filigree/static/js/views/ready.js index 809ef119..cf3f12b3 100644 --- a/src/filigree/static/js/views/ready.js +++ b/src/filigree/static/js/views/ready.js @@ -3,8 +3,8 @@ // --------------------------------------------------------------------------- import { fetchReady } from "../api.js"; -import { escHtml, escJsSingleAttr } from "../ui.js"; import { callbacks } from "../router.js"; +import { escHtml, escJsSingleAttr } from "../ui.js"; const PRIORITY_LABELS = ["P0", "P1", "P2", "P3", "P4"]; const PRIORITY_COLORS = [ diff --git a/src/filigree/static/js/views/releases.js b/src/filigree/static/js/views/releases.js index 373bdc94..9fd033fb 100644 --- a/src/filigree/static/js/views/releases.js +++ b/src/filigree/static/js/views/releases.js @@ -7,12 +7,12 @@ import { escHtml, escJsSingleAttr } from "../ui.js"; // --- Module-level state --- -let expandedReleaseIds = new Set(); -let releaseTreeCache = new Map(); -let expandedNodeIds = new Set(); +const expandedReleaseIds = new Set(); +const releaseTreeCache = new Map(); +const expandedNodeIds = new Set(); let showReleased = false; -let loadingReleaseIds = new Set(); -let errorReleaseIds = new Set(); +const loadingReleaseIds = new Set(); +const errorReleaseIds = new Set(); let _pendingFocusTarget = null; export function scrollToReleaseCard(cardId) { diff --git a/src/filigree/static/js/views/workflow.js b/src/filigree/static/js/views/workflow.js index f6b75834..02d46e49 100644 --- a/src/filigree/static/js/views/workflow.js +++ b/src/filigree/static/js/views/workflow.js @@ -189,7 +189,7 @@ export function showWorkflowModal(type) { '' + "" + - '' + + '' + "" + '
' + ""; diff --git a/tests/api/test_graph_api.py b/tests/api/test_graph_api.py index 37bb11e4..65f5cb08 100644 --- a/tests/api/test_graph_api.py +++ b/tests/api/test_graph_api.py @@ -76,7 +76,7 @@ def test_hover_traversal_uses_outgoers_not_full_edge_scan(self) -> None: def test_topology_change_reuses_positions_only_when_all_nodes_have_positions(self) -> None: graph_js = (STATIC_DIR / "js" / "views" / "graph.js").read_text() assert "const canReusePositions =" in graph_js - assert "cyNodes.every((n) => Object.prototype.hasOwnProperty.call(previousPositions, n.data.id))" in graph_js + assert "cyNodes.every((n) => Object.hasOwn(previousPositions, n.data.id))" in graph_js assert "positions: (node) => previousPositions[node.id()]," in graph_js assert "previousPositions[node.id()] || { x: 0, y: 0 }" not in graph_js