Skip to content

Commit 1ddac61

Browse files
committed
Surface OWASP standards in explorer and analysis UI
1 parent 7b3572b commit 1ddac61

6 files changed

Lines changed: 331 additions & 70 deletions

File tree

application/frontend/src/pages/Explorer/explorer.scss

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,40 @@ main#explorer-content {
2121
color: #0056b3;
2222
}
2323

24-
.search-field {
25-
input {
26-
font-size: 16px;
27-
height: 32px;
28-
width: 320px;
24+
.search-field {
25+
input {
26+
font-size: 16px;
27+
height: 32px;
28+
width: 320px;
2929
margin-bottom: 10px;
3030
border-radius: 3px;
3131
border: 1px solid #858585;
3232
padding: 0 5px;
3333
color: #333333;
34-
background-color: #ffffff;
35-
}
36-
}
34+
background-color: #ffffff;
35+
}
36+
}
37+
38+
.tree-actions {
39+
display: flex;
40+
gap: 10px;
41+
margin-bottom: 14px;
42+
43+
button {
44+
height: 34px;
45+
padding: 0 12px;
46+
border: 1px solid #b1b0b0;
47+
border-radius: 4px;
48+
background: #ffffff;
49+
color: #1a202c;
50+
cursor: pointer;
51+
font-size: 14px;
52+
53+
&:hover {
54+
background: #f4f6f8;
55+
}
56+
}
57+
}
3758

3859
#graphs-menu {
3960
display: flex;
@@ -150,16 +171,20 @@ main#explorer-content {
150171
padding: 1rem;
151172
/* Reduce from 30px to prevent content touching edges */
152173

153-
.search-field {
154-
input {
155-
width: 100%;
156-
/* Expand from fixed 320px - overflows on small screens */
157-
}
158-
}
159-
160-
.item {
161-
margin: 4px 4px 4px 1rem;
162-
/* Reduce from 40px left margin on mobile */
174+
.search-field {
175+
input {
176+
width: 100%;
177+
/* Expand from fixed 320px - overflows on small screens */
178+
}
179+
}
180+
181+
.tree-actions {
182+
flex-wrap: wrap;
183+
}
184+
185+
.item {
186+
margin: 4px 4px 4px 1rem;
187+
/* Reduce from 40px left margin on mobile */
163188
}
164189
}
165-
}
190+
}

application/frontend/src/pages/Explorer/explorer.tsx

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,41 @@ export const Explorer = () => {
5656
return null;
5757
};
5858

59-
const [collapsedItems, setCollapsedItems] = useState<string[]>([]);
60-
const isCollapsed = (id: string) => collapsedItems.includes(id);
61-
const toggleItem = (id: string) => {
62-
if (collapsedItems.includes(id)) {
63-
setCollapsedItems(collapsedItems.filter((itemId) => itemId !== id));
59+
const [collapsedItems, setCollapsedItems] = useState<string[]>([]);
60+
const isCollapsed = (id: string) => collapsedItems.includes(id);
61+
const toggleItem = (id: string) => {
62+
if (collapsedItems.includes(id)) {
63+
setCollapsedItems(collapsedItems.filter((itemId) => itemId !== id));
6464
} else {
6565
setCollapsedItems([...collapsedItems, id]);
66-
}
67-
};
66+
}
67+
};
68+
69+
const collectExpandableIds = (nodes: TreeDocument[] = []): string[] => {
70+
const ids: string[] = [];
71+
72+
const visit = (node: TreeDocument | null) => {
73+
if (!node) {
74+
return;
75+
}
76+
const contains = (node.links || []).filter((link) => link.ltype === TYPE_CONTAINS);
77+
if (contains.length > 0) {
78+
ids.push(node.id);
79+
contains.forEach((child) => visit(child.document));
80+
}
81+
};
82+
83+
nodes.forEach((node) => visit(node));
84+
return ids;
85+
};
86+
87+
const collapseAll = () => {
88+
setCollapsedItems(collectExpandableIds(filteredTree || []));
89+
};
90+
91+
const expandAll = () => {
92+
setCollapsedItems([]);
93+
};
6894

6995
useEffect(() => {
7096
if (dataTree.length) {
@@ -144,14 +170,22 @@ export const Explorer = () => {
144170
.
145171
</p>
146172

147-
<div id="explorer-wrapper">
148-
<div className="search-field">
149-
<input id="filter" type="text" placeholder="Search Explorer..." onKeyUp={update} />
150-
<div id="search-summary"></div>
151-
</div>
152-
<div id="graphs-menu">
153-
<h4 className="menu-title">Explore visually:</h4>
154-
<ul>
173+
<div id="explorer-wrapper">
174+
<div className="search-field">
175+
<input id="filter" type="text" placeholder="Search Explorer..." onKeyUp={update} />
176+
<div id="search-summary"></div>
177+
</div>
178+
<div className="tree-actions">
179+
<button type="button" onClick={expandAll}>
180+
Expand all
181+
</button>
182+
<button type="button" onClick={collapseAll}>
183+
Collapse all
184+
</button>
185+
</div>
186+
<div id="graphs-menu">
187+
<h4 className="menu-title">Explore visually:</h4>
188+
<ul>
155189
<li>
156190
<a href="/explorer/force_graph">Dependency Graph</a>
157191
</li>

application/frontend/src/pages/GapAnalysis/GapAnalysis.scss

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,23 @@ main#gap-analysis {
55
span.name {
66
padding: 0 10px;
77
}
8+
9+
.specialized-cheatsheets {
10+
margin-top: 1.5rem;
11+
12+
h2 {
13+
margin-bottom: 0.4rem;
14+
}
15+
16+
p {
17+
margin-bottom: 0.9rem;
18+
color: #4a5568;
19+
}
20+
21+
table {
22+
border-top: 3px solid #2b6cb0;
23+
}
24+
}
825
}
926

1027
@media (min-width: 0px) and (max-width: 500px) {

0 commit comments

Comments
 (0)