Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions scancodeio/context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
# ScanCode.io is a free software code scanning tool from nexB Inc. and others.
# Visit https://github.com/aboutcode-org/scancode.io for support and download.

from django.conf import settings

from scancode_config import __version__ as scancode_toolkit_version

Expand All @@ -31,5 +30,4 @@ def versions(request):
return {
"SCANCODEIO_VERSION": scancodeio_version.lstrip("v"),
"SCANCODE_TOOLKIT_VERSION": scancode_toolkit_version,
"VULNERABLECODE_URL": settings.VULNERABLECODE_URL,
}
File renamed without changes.
95 changes: 95 additions & 0 deletions scancodeio/static/js/dependency_tree.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// SPDX-License-Identifier: Apache-2.0
//
// http://nexb.com and https://github.com/aboutcode-org/scancode.io
// The ScanCode.io software is licensed under the Apache License version 2.0.
// Data generated with ScanCode.io is provided as-is without warranties.
// ScanCode is a trademark of nexB Inc.
//
// You may not use this software except in compliance with the License.
// You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// Data Generated with ScanCode.io is provided on an "AS IS" BASIS, WITHOUT WARRANTIES
// OR CONDITIONS OF ANY KIND, either express or implied. No content created from
// ScanCode.io should be considered or used as legal advice. Consult an Attorney
// for any legal advice.
//
// ScanCode.io is a free software code scanning tool from nexB Inc. and others.
// Visit https://github.com/aboutcode-org/scancode.io for support and download.

'use strict';

(function() {
const treeContainer = document.getElementById('tree');
const collapseAllButton = document.getElementById('collapseAll');
const expendAllButton = document.getElementById('expendAll');

if (!collapseAllButton) return;

function collapseAllDetails() {
document.querySelectorAll('details').forEach(details => {
details.removeAttribute('open');
});
showAllListItems();
}

function expendAllDetails() {
document.querySelectorAll('details').forEach(details => {
details.setAttribute('open', ''); // Adding 'open' attribute to open the details
});
showAllListItems();
}

collapseAllButton.addEventListener('click', collapseAllDetails);
expendAllButton.addEventListener('click', expendAllDetails);

// Following function are use to limit the display to specific elements.

function expandAncestors(detailsElement) {
let parent = detailsElement.parentElement.closest('details');
while (parent) {
parent.setAttribute('open', '');
parent.parentElement.style.display = '';
parent = parent.parentElement.closest('details');
}
}

function showAllListItems() {
const listItems = treeContainer.querySelectorAll('li');
listItems.forEach(item => {
item.style.display = '';
});
}

function hideAllListItems() {
const listItems = treeContainer.querySelectorAll('li');
listItems.forEach(item => {
item.style.display = 'none';
});
}

function handleItems(attribute, value) {
collapseAllDetails();
hideAllListItems();

const items = document.querySelectorAll(`li[${attribute}="${value}"]`);
items.forEach(item => {
item.style.display = 'block';
expandAncestors(item);
});
}

function handleVulnerableItems() {
handleItems('data-is-vulnerable', 'true');
}

function handleComplianceAlertItems() {
handleItems('data-compliance-alert', 'true');
}

showVulnerableOnlyButton.addEventListener('click', handleVulnerableItems);
showComplianceAlertOnlyButton.addEventListener('click', handleComplianceAlertItems);
})();
50 changes: 50 additions & 0 deletions scancodeio/static/main.js → scancodeio/static/js/main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
// SPDX-License-Identifier: Apache-2.0
//
// http://nexb.com and https://github.com/aboutcode-org/scancode.io
// The ScanCode.io software is licensed under the Apache License version 2.0.
// Data generated with ScanCode.io is provided as-is without warranties.
// ScanCode is a trademark of nexB Inc.
//
// You may not use this software except in compliance with the License.
// You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// Data Generated with ScanCode.io is provided on an "AS IS" BASIS, WITHOUT WARRANTIES
// OR CONDITIONS OF ANY KIND, either express or implied. No content created from
// ScanCode.io should be considered or used as legal advice. Consult an Attorney
// for any legal advice.
//
// ScanCode.io is a free software code scanning tool from nexB Inc. and others.
// Visit https://github.com/aboutcode-org/scancode.io for support and download.

//
// Selected parts from https://bulma.io/lib/main.js?v=202104191409
//
Expand Down Expand Up @@ -58,6 +80,26 @@ function setupCloseModalButtons() {
}
}

// Populate dynamic modals on open.
// - Sets form action from the button's data-url
// - Fills [data-label] elements from matching button data attributes
// Usage: <button class="modal-button" data-target="modal-id" data-url="/path/" data-label="Label">
document.addEventListener("openModal", function(event) {
const modal = document.getElementById(event.detail.modal);
if (!modal) return;

const form = modal.querySelector("form");
if (form && event.detail.$button.dataset.url) {
form.action = event.detail.$button.dataset.url;
}

const labels = modal.querySelectorAll("[data-label]");
labels.forEach(function(label) {
const value = event.detail.$button.dataset[label.dataset.label];
if (value) label.textContent = value;
});
});

// Tabs

function activateTab(tabLink) {
Expand Down Expand Up @@ -273,6 +315,14 @@ function removeOverlay() {
if (background) background.remove();
}

// Display a loading overlay on form submission.
// Usage: <form data-submit-overlay>
document.addEventListener("submit", function(event) {
if (event.target.matches("[data-submit-overlay]")) {
displayOverlay();
}
});

// Display and update the `$progress` object on `$form` submitted using XHR
function displayFormUploadProgress($form, $progress, $form_errors, update_title=false) {

Expand Down
170 changes: 170 additions & 0 deletions scancodeio/static/js/project_form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
// SPDX-License-Identifier: Apache-2.0
//
// http://nexb.com and https://github.com/aboutcode-org/scancode.io
// The ScanCode.io software is licensed under the Apache License version 2.0.
// Data generated with ScanCode.io is provided as-is without warranties.
// ScanCode is a trademark of nexB Inc.
//
// You may not use this software except in compliance with the License.
// You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// Data Generated with ScanCode.io is provided on an "AS IS" BASIS, WITHOUT WARRANTIES
// OR CONDITIONS OF ANY KIND, either express or implied. No content created from
// ScanCode.io should be considered or used as legal advice. Consult an Attorney
// for any legal advice.
//
// ScanCode.io is a free software code scanning tool from nexB Inc. and others.
// Visit https://github.com/aboutcode-org/scancode.io for support and download.

'use strict';

(function() {
const form = document.querySelector('form');
if (!form) return;

const pipelineSelect = document.getElementById("id_pipeline");
if (!pipelineSelect) return;

// Upload progress overlay on form submit
form.addEventListener('submit', function(event) {
let background = displayOverlay();

// The upload progress is only added when input files are provided.
if (!form["input_files"].files.length) return false;

event.preventDefault();

let progress_bar = document.createElement('progress');
progress_bar.className = 'progress is-success is-medium file-upload';
progress_bar.setAttribute('value', '0');
progress_bar.setAttribute('max', '100');

let progress_container = document.createElement('div');
progress_container.className = 'container is-max-desktop mt-6 px-6';
progress_container.appendChild(progress_bar)
background.appendChild(progress_container);

let form_errors = document.getElementById('form-errors');
displayFormUploadProgress(form, progress_bar, form_errors, true);
});

// Pipeline groups checkboxes

const availableGroupsDataSource = document.getElementById("pipelines_available_groups");
if (!availableGroupsDataSource) return;

const availableGroupsMapping = JSON.parse(availableGroupsDataSource.textContent);
const idSelectedGroups = document.getElementById("id_selected_groups");

function clearSelectedGroups() {
idSelectedGroups.replaceChildren();
}

function buildCheckbox(group) {
const id = `id_${group}`;
const label = document.createElement('label');
label.className = 'checkbox ml-1 mb-1';
label.htmlFor = id;

const span = document.createElement('span');
span.className = 'tag is-warning has-text-weight-bold';

const input = document.createElement('input');
input.type = 'checkbox';
input.name = 'selected_groups';
input.value = group;
input.id = id;
input.className = 'mr-1';

span.appendChild(input);
span.appendChild(document.createTextNode(' ' + group));

label.appendChild(span);

return label;
}

function handlePipelineChange() {
clearSelectedGroups();

const selectedPipelineName = pipelineSelect.value;
if (!selectedPipelineName) return;

const availableGroups = availableGroupsMapping[selectedPipelineName];
if (availableGroups && availableGroups.length > 0) {
const strongElement = document.createElement('strong');
const icon = document.createElement('i');
icon.className = 'fa-solid fa-circle-arrow-right';
strongElement.appendChild(icon);
strongElement.appendChild(document.createTextNode(' Include:'));
idSelectedGroups.appendChild(strongElement);

availableGroups.forEach((group) => {
const checkboxElement = buildCheckbox(group);
idSelectedGroups.appendChild(checkboxElement);
});
}
}

handlePipelineChange();
pipelineSelect.addEventListener("change", handlePipelineChange);

// Auto-detect pipeline from input value

function detectPipelineFromValue(value) {
value = value.trim().toLowerCase();

if (!value) return "";

// Handle Docker reference
if (value.startsWith("docker:")) return "analyze_docker_image";

// Handle Package URL
if (value.startsWith("pkg:")) return "scan_single_package";

// Handle SBOM file formats
if (
value.endsWith(".spdx") ||
value.endsWith(".spdx.json") ||
value.endsWith(".spdx.yml") ||
value.endsWith("bom.json") ||
value.endsWith(".cdx.json") ||
value.endsWith(".cyclonedx.json") ||
value.endsWith("bom.xml") ||
value.endsWith(".cdx.xml") ||
value.endsWith(".cyclonedx.xml")
) return "load_sbom";

// No match
return "";
}

const textarea = document.getElementById("id_input_urls");
const fileInput = document.getElementById("id_input_files");

// Handle textarea input
textarea.addEventListener("input", () => {
const value = textarea.value.trim();
const pipeline = detectPipelineFromValue(value);
pipelineSelect.value = pipeline;
});

// Handle file uploads
fileInput.addEventListener("change", () => {
const files = Array.from(fileInput.files);

// Detect based on first file, multiple input files not supported.
if (files.length === 1) {
const firstFile = files[0].name.toLowerCase();
const pipeline = detectPipelineFromValue(firstFile);
pipelineSelect.value = pipeline;
} else {
pipelineSelect.value = "";
}
});

})();
Loading
Loading