Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Search results page, layout and pagination #13440

Merged
merged 11 commits into from
Jan 12, 2024
44 changes: 37 additions & 7 deletions static/js/src/cve/cve.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import {

const searchInput = document.querySelector("#q");
const searchForm = document.querySelector("#searchForm");
const cveList = document.querySelector("#cve-list");
const recentCves = document.querySelector("#recent-cves");
const url = new URL(window.location.href);
const urlParams = new URLSearchParams(url.search);
const limitSelect = document.querySelector(".js-limit-select");
const orderSelect = document.querySelector(".js-order-select");
const exportLink = document.querySelector("#js-export-link");
const apiBase = "https://ubuntu.com/security/cves.json";

function handleCveIdInput(value) {
const packageInput = document.querySelector("#package");
Expand Down Expand Up @@ -153,11 +155,39 @@ tooltipIconList.forEach(function (tooltipIcon) {
);
});

function showCVEList() {
if (urlParams.has("status")) {
recentCves.classList.add("u-hide");
cveList.classList.remove("u-hide");
function handleLimitSelect() {
if (urlParams.has("limit")) {
limitSelect.value = urlParams.get("limit");
}

limitSelect.onchange = function (event) {
limitSelect.value = event.target.value;
urlParams.set("limit", limitSelect.value);
url.search = urlParams.toString();
window.location.href = url.href;
};
}
handleLimitSelect();

function handleOrderSelect() {
if (urlParams.has("order")) {
orderSelect.value = urlParams.get("order");
}

showCVEList();
orderSelect.onchange = function (event) {
orderSelect.value = event.target.value;
urlParams.set("order", orderSelect.value);
url.search = urlParams.toString();
window.location.href = url.href;
};
}
handleOrderSelect();

function exportToJSON() {
exportLink.onclick = function (event) {
event.preventDefault();
let apiURL = new URL(url.search, apiBase);
window.location.href = apiURL.href;
};
}
exportToJSON();
78 changes: 78 additions & 0 deletions static/sass/_pattern_cve.scss
Original file line number Diff line number Diff line change
Expand Up @@ -224,4 +224,82 @@

border-bottom-color: #66a61e;
}

.cve-landing {
.p-inline-list {
margin-top: 0.3rem;
}
}

.cve-results {
display: flex;
justify-content: space-between;

.p-text--small-caps {
display: inline-flex;
}

.p-form {
display: flex;
gap: 2.5rem;
}

.p-form__group {
margin-left: auto;
margin-right: 0;
}

.p-form__control {
max-width: fit-content;
min-width: 0;
padding-right: 1rem;
}
}

.cve-card-header {
margin-bottom: 1.1rem;
padding-top: 0.4rem;

h2 {
display: inline;
padding-top: 0;
}

#priority-icon {
float: inline-end;
}
}

.cve-pagination-footer {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}

.cve-pagination-footer-links {
display: flex;
gap: inherit;

a {
margin-top: 0.4rem;
}

@media screen and (max-width: $breakpoint-small - 1) {
flex-direction: column;
gap: 1rem;
}

.p-form__control {
max-width: fit-content;
min-width: 0;
padding-right: 1rem;
}
}

#cve-search-button {
@media screen and (min-width: $breakpoint-small) {
margin-top: 2.6rem;
width: 100%;
}
}
}
80 changes: 80 additions & 0 deletions templates/security/cve/_cve-card.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{% for cve in cves %}
<div class="row">
<div class="col-6 col-medium-4">
<div class="cve-card-header">
<h2 class="p-heading--5">
<a href="/security/{{ cve.id }}">{{ cve.id }}</a>
</h2>
<span id="priority-icon">
{% if cve.priority == 'unknown' %}
<i class="p-icon--placeholder"></i>
{% elif cve.priority == 'negligible' %}
<i class="p-icon--negligible-priority"></i>
{% elif cve.priority == 'low' %}
<i class="p-icon--low-priority"></i>
{% elif cve.priority == 'medium' %}
<i class="p-icon--medium-priority"></i>
{% elif cve.priority == 'high' %}
<i class="p-icon--high-priority"></i>
{% elif cve.priority == 'critical' %}
<i class="p-icon--critical-priority"></i>
{% else %}
<i class="p-icon--placeholder"></i>
{% endif %}
<span>{{ cve.priority.split() | first | capitalize }} priority</span>
</span>
</div>
</div>
<div class="col-3 col-medium-2">
{% set status = cve.summarized_status %}
{% if status.name == "Some fixed" %}
<p>Some fixes available <span class="u-text--muted">{{ status.fixed_count }} of {{ status.total_count }}</span></p>
{% elif status.name == "Needs evaluation" %}
<p>
<i class="p-icon--help"></i> <span>Needs evaluation</span>
</p>
{% elif status.name == "Fixed" %}
<p>
<i class="p-icon--success"></i> <span>Fixed</span>
</p>
{% elif status.name == "Vulnerable" %}
<p>
<i class="p-icon--warning"></i> <span>Vulnerable</span>
</p>
{% elif status.name == "DNE" %}
<p>
<span>Not in release</span>
</p>
{% else %}
{{status}}
{% endif %}
</div>
</div>
<div class="row p-section--shallow">
<div class="col-6 col-medium-4">
<p>{{ cve.description|truncate(235) }}</p>
</div>
<div class="col-3 col-medium-2">
<p class="p-text--small-caps u-text--muted u-no-margin--top">{{ cve.packages | length}} affected packages</p>
<p class="u-text--muted">
{% for package in cve.packages %}
{% if cve.packages | length > 6 %}
{% if loop.index < 5 %}
{{ package.name }},
{% elif loop.index == 5 %}
{{ package.name }}...
{% endif %}
{% else %}
{% if loop.last %}
{{ package.name }}
{% else %}
{{ package.name }},
{% endif %}
{% endif %}
{% endfor %}
</div>
</div>
{% if loop.index < cves | length %}
<hr class="p-rule" />
{% endif %}
{% endfor %}
104 changes: 104 additions & 0 deletions templates/security/cve/_cve-filters.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<div class="p-section--shallow">
<p class="p-text--small-caps">Filters</p>
</div>
<!-- package filter -->
<form id="package-filter">
<label class="p-form__label p-heading--5 p-section--shallow u-no-margin--bottom" for="package"><i class="p-icon--chevron-down"></i> Affected packages</label>
<input type="text" id="affectedPackages" name="affectedPackages" placeholder="Any package" />
</form>
<!-- releases filter -->
<div class="p-section--shallow">
<i class="p-icon--chevron-down"></i><span class="p-heading--5"> Ubuntu releases</span>
<form>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="allMaintainedReleases" class="p-checkbox__input" />
<span class="p-checkbox__label" id="allMaintainedReleases">All maintained releases</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="22.10" class="p-checkbox__input" />
<span class="p-checkbox__label" id="22.10">22.10 kinetic</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="22.04" class="p-checkbox__input" />
<span class="p-checkbox__label" id="22.04">22.04 LTS jammy</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="20.04" class="p-checkbox__input" />
<span class="p-checkbox__label" id="20.04">20.04 LTS focal</span>
</label>
<p class="p-text--small-caps" style="padding-left: 2rem;">Still maintained with<br/> Ubuntu Pro</p>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="18.04" class="p-checkbox__input" />
<span class="p-checkbox__label" id="18.04">18.04 LTS bionic</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="16.04" class="p-checkbox__input" />
<span class="p-checkbox__label" id="16.04">16.04 LTS xenial</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="14.04" class="p-checkbox__input" />
<span class="p-checkbox__label" id="14.04">14.04 LTS trusty</span>
</label>
</form>
<a>Show unmaintained releases</a>
</div>
<!-- ubuntu priority filter -->
<div class="p-section--shallow">
<i class="p-icon--chevron-down"></i><span class="p-heading--5"> Ubuntu priority</span>
<form>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="critical" class="p-checkbox__input" />
<span class="p-checkbox__label" id="critical">Critical</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="high" class="p-checkbox__input" />
<span class="p-checkbox__label" id="high">High</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="medium" class="p-checkbox__input" />
<span class="p-checkbox__label" id="medium">Medium</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="low" class="p-checkbox__input" />
<span class="p-checkbox__label" id="low">Low</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="negligible" class="p-checkbox__input" />
<span class="p-checkbox__label" id="negligible">Negligible</span>
</label>
</form>
<a>What is Ubuntu priority?</a>
</div>
<!-- status filters-->
<div class="p-section--shallow">
<i class="p-icon--chevron-down"></i><span class="p-heading--5"> Ubuntu priority</span>
<form>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="fixed" class="p-checkbox__input" />
<span class="p-checkbox__label" id="fixed">Fixed</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="vulnerable" class="p-checkbox__input" />
<span class="p-checkbox__label" id="vulnerable">Vulnerable</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="ignored" class="p-checkbox__input" />
<span class="p-checkbox__label" id="ignored">Ignored</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="notAffected" class="p-checkbox__input" />
<span class="p-checkbox__label" id="notAffected">Not affected</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="packageNotPresent" class="p-checkbox__input" />
<span class="p-checkbox__label" id="packageNotPresent">Package not present</span>
</label>
<label class="p-checkbox">
<input type="checkbox" aria-labelledby="noData" class="p-checkbox__input" />
<span class="p-checkbox__label" id="noData">No data</span>
</label>
</form>
<a>What do statuses mean?</a>
</div>

<button class="p-button">Clear all filters</button>
46 changes: 46 additions & 0 deletions templates/security/cve/_cve-footer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<section class="p-section">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was already reviewed and the only change is that I moved it into a partial to make the base page a bit more readable, so no need to review this one

<div class="row--25-75 is-split-on-medium">
<hr class="p-rule"/>
<div class="col">
<h2>Resources</h2>
</div>
<div class="col">
<div class="row">
<div class="col-3">
<h3 class="p-heading--5">Join the discussion</h3>
</div>
<div class="col-6">
<ul class="p-list--divided">
<li class="p-list__item"><a href="https://lists.ubuntu.com/mailman/listinfo/ubuntu-hardened" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Contextual footer link', 'eventAction' : 'Ubuntu security updates mailing list', 'eventLabel' : 'Join the discussion', 'eventValue' : undefined });">Ubuntu security mailing list</a></li>
<li class="p-list__item"><a href="https://lists.ubuntu.com/mailman/listinfo/ubuntu-security-announce" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Contextual footer link', 'eventAction' : 'Security announcements mailing list', 'eventLabel' : 'Join the discussion', 'eventValue' : undefined });">Security announcements mailing list</a></li>
</ul>
</div>
</div>
<hr class="p-rule"/>
<div class="row p-section--shallow">
<div class="col-3">
<h3 class="p-heading--5">Ubuntu Pro</h3>
</div>
<div class="col-6">
<p>10-year security coverage for Ubuntu <br aria-hidden="true"> and 23,000 open-source applications and toolchains.</p>
<a class="p-button" href="/pro">Get Ubuntu Pro</a>
</div>
</div>
<hr class="p-rule"/>
<div class="row">
<div class="col-3">
<h3 class="p-heading--5">From our blog</h3>
</div>
<div class="col-6">
<ul class="p-list--divided">
<li class="p-list__item"><a href="/blog/securing-multiple-ubuntu-instances-while-maximising-uptime">Ubuntu Explained: How to ensure security and stability in cloud instances—part 3</a></li>
<li class="p-list__item"><a href="/blog/ubuntu-updates-best-practices-for-updating-your-instance">Ubuntu Explained: How to ensure security and stability in cloud instances—part 2</a></li>
<li class="p-list__item"><a href="/blog/running-openssl-1-1-1-after-eol-with-ubuntu-pro">Running OpenSSL 1.1.1 after EOL? Stay secure with Ubuntu Pro.</a></li>
<li class="p-list__item"><a href="/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces">Restricted unprivileged user namespaces are coming to Ubuntu 23.10</a></li>
<li class="p-list__item"><a href="/blog/securing-open-source-software-dependencies-in-the-public-cloud">Securing open source software dependencies in the public cloud</a></li>
</ul>
</div>
</div>
</div>
</div>
</section>
Loading
Loading