Skip to content

Commit 903477c

Browse files
authored
feat: enhance the global HTML structure (#2103)
Signed-off-by: tdruez <tdruez@aboutcode.org>
1 parent a848cea commit 903477c

36 files changed

Lines changed: 692 additions & 564 deletions

scancodeio/context_processors.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
# ScanCode.io is a free software code scanning tool from nexB Inc. and others.
2121
# Visit https://github.com/aboutcode-org/scancode.io for support and download.
2222

23-
from django.conf import settings
2423

2524
from scancode_config import __version__ as scancode_toolkit_version
2625

@@ -31,5 +30,4 @@ def versions(request):
3130
return {
3231
"SCANCODEIO_VERSION": scancodeio_version.lstrip("v"),
3332
"SCANCODE_TOOLKIT_VERSION": scancode_toolkit_version,
34-
"VULNERABLECODE_URL": settings.VULNERABLECODE_URL,
3533
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
//
3+
// http://nexb.com and https://github.com/aboutcode-org/scancode.io
4+
// The ScanCode.io software is licensed under the Apache License version 2.0.
5+
// Data generated with ScanCode.io is provided as-is without warranties.
6+
// ScanCode is a trademark of nexB Inc.
7+
//
8+
// You may not use this software except in compliance with the License.
9+
// You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
10+
// Unless required by applicable law or agreed to in writing, software distributed
11+
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12+
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13+
// specific language governing permissions and limitations under the License.
14+
//
15+
// Data Generated with ScanCode.io is provided on an "AS IS" BASIS, WITHOUT WARRANTIES
16+
// OR CONDITIONS OF ANY KIND, either express or implied. No content created from
17+
// ScanCode.io should be considered or used as legal advice. Consult an Attorney
18+
// for any legal advice.
19+
//
20+
// ScanCode.io is a free software code scanning tool from nexB Inc. and others.
21+
// Visit https://github.com/aboutcode-org/scancode.io for support and download.
22+
23+
'use strict';
24+
25+
(function() {
26+
const treeContainer = document.getElementById('tree');
27+
const collapseAllButton = document.getElementById('collapseAll');
28+
const expendAllButton = document.getElementById('expendAll');
29+
30+
if (!collapseAllButton) return;
31+
32+
function collapseAllDetails() {
33+
document.querySelectorAll('details').forEach(details => {
34+
details.removeAttribute('open');
35+
});
36+
showAllListItems();
37+
}
38+
39+
function expendAllDetails() {
40+
document.querySelectorAll('details').forEach(details => {
41+
details.setAttribute('open', ''); // Adding 'open' attribute to open the details
42+
});
43+
showAllListItems();
44+
}
45+
46+
collapseAllButton.addEventListener('click', collapseAllDetails);
47+
expendAllButton.addEventListener('click', expendAllDetails);
48+
49+
// Following function are use to limit the display to specific elements.
50+
51+
function expandAncestors(detailsElement) {
52+
let parent = detailsElement.parentElement.closest('details');
53+
while (parent) {
54+
parent.setAttribute('open', '');
55+
parent.parentElement.style.display = '';
56+
parent = parent.parentElement.closest('details');
57+
}
58+
}
59+
60+
function showAllListItems() {
61+
const listItems = treeContainer.querySelectorAll('li');
62+
listItems.forEach(item => {
63+
item.style.display = '';
64+
});
65+
}
66+
67+
function hideAllListItems() {
68+
const listItems = treeContainer.querySelectorAll('li');
69+
listItems.forEach(item => {
70+
item.style.display = 'none';
71+
});
72+
}
73+
74+
function handleItems(attribute, value) {
75+
collapseAllDetails();
76+
hideAllListItems();
77+
78+
const items = document.querySelectorAll(`li[${attribute}="${value}"]`);
79+
items.forEach(item => {
80+
item.style.display = 'block';
81+
expandAncestors(item);
82+
});
83+
}
84+
85+
function handleVulnerableItems() {
86+
handleItems('data-is-vulnerable', 'true');
87+
}
88+
89+
function handleComplianceAlertItems() {
90+
handleItems('data-compliance-alert', 'true');
91+
}
92+
93+
showVulnerableOnlyButton.addEventListener('click', handleVulnerableItems);
94+
showComplianceAlertOnlyButton.addEventListener('click', handleComplianceAlertItems);
95+
})();
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
//
3+
// http://nexb.com and https://github.com/aboutcode-org/scancode.io
4+
// The ScanCode.io software is licensed under the Apache License version 2.0.
5+
// Data generated with ScanCode.io is provided as-is without warranties.
6+
// ScanCode is a trademark of nexB Inc.
7+
//
8+
// You may not use this software except in compliance with the License.
9+
// You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
10+
// Unless required by applicable law or agreed to in writing, software distributed
11+
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12+
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13+
// specific language governing permissions and limitations under the License.
14+
//
15+
// Data Generated with ScanCode.io is provided on an "AS IS" BASIS, WITHOUT WARRANTIES
16+
// OR CONDITIONS OF ANY KIND, either express or implied. No content created from
17+
// ScanCode.io should be considered or used as legal advice. Consult an Attorney
18+
// for any legal advice.
19+
//
20+
// ScanCode.io is a free software code scanning tool from nexB Inc. and others.
21+
// Visit https://github.com/aboutcode-org/scancode.io for support and download.
22+
123
//
224
// Selected parts from https://bulma.io/lib/main.js?v=202104191409
325
//
@@ -58,6 +80,26 @@ function setupCloseModalButtons() {
5880
}
5981
}
6082

83+
// Populate dynamic modals on open.
84+
// - Sets form action from the button's data-url
85+
// - Fills [data-label] elements from matching button data attributes
86+
// Usage: <button class="modal-button" data-target="modal-id" data-url="/path/" data-label="Label">
87+
document.addEventListener("openModal", function(event) {
88+
const modal = document.getElementById(event.detail.modal);
89+
if (!modal) return;
90+
91+
const form = modal.querySelector("form");
92+
if (form && event.detail.$button.dataset.url) {
93+
form.action = event.detail.$button.dataset.url;
94+
}
95+
96+
const labels = modal.querySelectorAll("[data-label]");
97+
labels.forEach(function(label) {
98+
const value = event.detail.$button.dataset[label.dataset.label];
99+
if (value) label.textContent = value;
100+
});
101+
});
102+
61103
// Tabs
62104

63105
function activateTab(tabLink) {
@@ -273,6 +315,14 @@ function removeOverlay() {
273315
if (background) background.remove();
274316
}
275317

318+
// Display a loading overlay on form submission.
319+
// Usage: <form data-submit-overlay>
320+
document.addEventListener("submit", function(event) {
321+
if (event.target.matches("[data-submit-overlay]")) {
322+
displayOverlay();
323+
}
324+
});
325+
276326
// Display and update the `$progress` object on `$form` submitted using XHR
277327
function displayFormUploadProgress($form, $progress, $form_errors, update_title=false) {
278328

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
//
3+
// http://nexb.com and https://github.com/aboutcode-org/scancode.io
4+
// The ScanCode.io software is licensed under the Apache License version 2.0.
5+
// Data generated with ScanCode.io is provided as-is without warranties.
6+
// ScanCode is a trademark of nexB Inc.
7+
//
8+
// You may not use this software except in compliance with the License.
9+
// You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
10+
// Unless required by applicable law or agreed to in writing, software distributed
11+
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12+
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13+
// specific language governing permissions and limitations under the License.
14+
//
15+
// Data Generated with ScanCode.io is provided on an "AS IS" BASIS, WITHOUT WARRANTIES
16+
// OR CONDITIONS OF ANY KIND, either express or implied. No content created from
17+
// ScanCode.io should be considered or used as legal advice. Consult an Attorney
18+
// for any legal advice.
19+
//
20+
// ScanCode.io is a free software code scanning tool from nexB Inc. and others.
21+
// Visit https://github.com/aboutcode-org/scancode.io for support and download.
22+
23+
'use strict';
24+
25+
(function() {
26+
const form = document.querySelector('form');
27+
if (!form) return;
28+
29+
const pipelineSelect = document.getElementById("id_pipeline");
30+
if (!pipelineSelect) return;
31+
32+
// Upload progress overlay on form submit
33+
form.addEventListener('submit', function(event) {
34+
let background = displayOverlay();
35+
36+
// The upload progress is only added when input files are provided.
37+
if (!form["input_files"].files.length) return false;
38+
39+
event.preventDefault();
40+
41+
let progress_bar = document.createElement('progress');
42+
progress_bar.className = 'progress is-success is-medium file-upload';
43+
progress_bar.setAttribute('value', '0');
44+
progress_bar.setAttribute('max', '100');
45+
46+
let progress_container = document.createElement('div');
47+
progress_container.className = 'container is-max-desktop mt-6 px-6';
48+
progress_container.appendChild(progress_bar)
49+
background.appendChild(progress_container);
50+
51+
let form_errors = document.getElementById('form-errors');
52+
displayFormUploadProgress(form, progress_bar, form_errors, true);
53+
});
54+
55+
// Pipeline groups checkboxes
56+
57+
const availableGroupsDataSource = document.getElementById("pipelines_available_groups");
58+
if (!availableGroupsDataSource) return;
59+
60+
const availableGroupsMapping = JSON.parse(availableGroupsDataSource.textContent);
61+
const idSelectedGroups = document.getElementById("id_selected_groups");
62+
63+
function clearSelectedGroups() {
64+
idSelectedGroups.replaceChildren();
65+
}
66+
67+
function buildCheckbox(group) {
68+
const id = `id_${group}`;
69+
const label = document.createElement('label');
70+
label.className = 'checkbox ml-1 mb-1';
71+
label.htmlFor = id;
72+
73+
const span = document.createElement('span');
74+
span.className = 'tag is-warning has-text-weight-bold';
75+
76+
const input = document.createElement('input');
77+
input.type = 'checkbox';
78+
input.name = 'selected_groups';
79+
input.value = group;
80+
input.id = id;
81+
input.className = 'mr-1';
82+
83+
span.appendChild(input);
84+
span.appendChild(document.createTextNode(' ' + group));
85+
86+
label.appendChild(span);
87+
88+
return label;
89+
}
90+
91+
function handlePipelineChange() {
92+
clearSelectedGroups();
93+
94+
const selectedPipelineName = pipelineSelect.value;
95+
if (!selectedPipelineName) return;
96+
97+
const availableGroups = availableGroupsMapping[selectedPipelineName];
98+
if (availableGroups && availableGroups.length > 0) {
99+
const strongElement = document.createElement('strong');
100+
const icon = document.createElement('i');
101+
icon.className = 'fa-solid fa-circle-arrow-right';
102+
strongElement.appendChild(icon);
103+
strongElement.appendChild(document.createTextNode(' Include:'));
104+
idSelectedGroups.appendChild(strongElement);
105+
106+
availableGroups.forEach((group) => {
107+
const checkboxElement = buildCheckbox(group);
108+
idSelectedGroups.appendChild(checkboxElement);
109+
});
110+
}
111+
}
112+
113+
handlePipelineChange();
114+
pipelineSelect.addEventListener("change", handlePipelineChange);
115+
116+
// Auto-detect pipeline from input value
117+
118+
function detectPipelineFromValue(value) {
119+
value = value.trim().toLowerCase();
120+
121+
if (!value) return "";
122+
123+
// Handle Docker reference
124+
if (value.startsWith("docker:")) return "analyze_docker_image";
125+
126+
// Handle Package URL
127+
if (value.startsWith("pkg:")) return "scan_single_package";
128+
129+
// Handle SBOM file formats
130+
if (
131+
value.endsWith(".spdx") ||
132+
value.endsWith(".spdx.json") ||
133+
value.endsWith(".spdx.yml") ||
134+
value.endsWith("bom.json") ||
135+
value.endsWith(".cdx.json") ||
136+
value.endsWith(".cyclonedx.json") ||
137+
value.endsWith("bom.xml") ||
138+
value.endsWith(".cdx.xml") ||
139+
value.endsWith(".cyclonedx.xml")
140+
) return "load_sbom";
141+
142+
// No match
143+
return "";
144+
}
145+
146+
const textarea = document.getElementById("id_input_urls");
147+
const fileInput = document.getElementById("id_input_files");
148+
149+
// Handle textarea input
150+
textarea.addEventListener("input", () => {
151+
const value = textarea.value.trim();
152+
const pipeline = detectPipelineFromValue(value);
153+
pipelineSelect.value = pipeline;
154+
});
155+
156+
// Handle file uploads
157+
fileInput.addEventListener("change", () => {
158+
const files = Array.from(fileInput.files);
159+
160+
// Detect based on first file, multiple input files not supported.
161+
if (files.length === 1) {
162+
const firstFile = files[0].name.toLowerCase();
163+
const pipeline = detectPipelineFromValue(firstFile);
164+
pipelineSelect.value = pipeline;
165+
} else {
166+
pipelineSelect.value = "";
167+
}
168+
});
169+
170+
})();

0 commit comments

Comments
 (0)