Skip to content

Commit

Permalink
Merge pull request #72 from tebayoso/review_banner
Browse files Browse the repository at this point in the history
Banner update & tags modifications UX
  • Loading branch information
mattaereal authored Sep 30, 2024
2 parents 4bca290 + 4cfd7de commit 8e08f62
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 41 deletions.
148 changes: 110 additions & 38 deletions theme/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -108,23 +108,47 @@
}
.announcement-stripe {
background-color: #ff00004f;
font-weight: bold;
color: #fff;
padding: 10px;
position: relative;
text-align: center;
margin: 0 auto;
width: 100%;
z-index: 1000;
}
.announcement-stripe p {
margin: 0;
}
@media (max-width: 768px) {
.announcement-stripe p {
display: flex;
flex-direction: column;
}
.announcement-stripe p span {
display: block;
}
}
/* Add this new style for the sidebar */
#sidebar {
z-index: 1001; /* Higher z-index than the announcement stripe */
}
</style>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<div class="announcement-stripe">
<p>This is a WIP. We're looking for volunteers. See <a href="https://github.com/security-alliance/frameworks/issues">Issues</a> to know how to collaborate.</p>
<p>
<span>This is a work in progress and not a release. We're looking for volunteers.</span>
<span>See <a href="https://github.com/security-alliance/frameworks/issues">Issues</a> to know how to collaborate.</span>
</p>
</div>
<!-- Provide site root to javascript -->
<script>
var path_to_root = "{{ path_to_root }}";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
</script>

Expand Down Expand Up @@ -181,8 +205,10 @@
<img src="{{ path_to_root }}logo.svg" alt="Logo">
</div>
<div id="selected-pages" class="selected-pages">
<h2>Selected Pages</h2>
Filter pages by tag to create a selection.
<div class="selected-pages-header" style="display: flex; align-items: center; justify-content: space-between; height: 50px;">
<h2 style="margin: 0;">Selected Pages</h2>
<button id="clear-selected-pages" type="button" title="Clear selected pages" aria-label="Clear selected pages" style="height: 100%;">x Clear</button>
</div>
<ul id="selected-pages-list"></ul>
</div>
{{#toc}}{{/toc}}
Expand Down Expand Up @@ -213,10 +239,12 @@
</script>

<div id="page-wrapper" class="page-wrapper">

<div class="page">
{{> header}}
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar-hover-placeholder">

</div>

<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
Expand Down Expand Up @@ -245,7 +273,7 @@
<i class="fa fa-tags"></i>
</button>
<div id="tags-dropdown" class="tags-dropdown hidden">
<input type="text" id="tag-search" placeholder="Search tags..." aria-label="Search tags">
<input type="text" id="tag-search" placeholder="Search tags..." aria-label="Search tags" style="width: 90%; padding: 5px;">
<div id="tags-list" class="tags-list" aria-label="Tags" role="listbox" aria-multiselectable="true">

</div>
Expand Down Expand Up @@ -430,8 +458,7 @@
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
fetch('{{ path_to_root }}theme/tagscolors.json')
fetch(path_to_root + 'theme/tagscolors.json')
.then(response => response.json())
.then(data=>
{
Expand All @@ -452,11 +479,10 @@
});
})
fetch('{{ path_to_root }}theme/tagsindex.json')
fetch(path_to_root + 'theme/tagsindex.json')
.then(response => response.json())
.then(data => {
window.tagsData = data;
console.log('Tags data loaded:', window.tagsData);
const tags = Object.keys(data);
const tagsList = document.getElementById('tags-list');
Expand All @@ -466,7 +492,7 @@
const isChecked = localStorage.getItem(`tag_${tag}`) === 'true';
li.innerHTML = `
<label>
<input type="checkbox" value="${tag}" ${isChecked ? 'checked' : ''}>
<input class="tag-checkbox" type="checkbox" value="${tag}" ${isChecked ? 'checked' : ''}>
${tag}
</label>
`;
Expand Down Expand Up @@ -509,60 +535,106 @@
});
}
tagsList.addEventListener('change', function(event) {
if (event.target.type === 'checkbox') {
const selectedTag = event.target.value;
const isChecked = event.target.checked;
localStorage.setItem(`tag_${selectedTag}`, isChecked);
console.log(`Tag ${selectedTag} is ${isChecked ? 'selected' : 'deselected'}`);
highlightSidebarLinks();
updateSelectedPages();
}
});
highlightSidebarLinks();
updateSelectedPages();
})
.catch(error => {
console.error('Error loading or parsing tagsindex.json:', error);
});
function updateSelectedPages() {
const selectedPagesList = document.getElementById('selected-pages-list');
const selectedPagesContainer = document.getElementById('selected-pages');
selectedPagesList.innerHTML = '';
const selectedTags = Object.keys(localStorage)
.filter(key => key.startsWith('tag_') && localStorage.getItem(key) === 'true')
.map(key => key.replace('tag_', ''));
if (selectedTags.length === 0) {
selectedPagesContainer.style.display = 'none';
return;
}
selectedPagesContainer.style.display = 'block';
const selectedPages = new Set();
selectedTags.forEach(tag => {
const pages = window.tagsData[tag] || [];
pages.forEach(page => selectedPages.add(page));
});
selectedPages.forEach(page => {
const li = document.createElement('li');
let pageTitle = window.tagsData[page]?.title || page;
const pageTree = {};
// Format the title
selectedPages.forEach(page => {
const parts = page.split('/');
const section = parts[0].charAt(0).toUpperCase() + parts[0].slice(1);
if (parts[1] === 'index.html') {
pageTitle = section;
} else {
const title = parts[1].replace('.html', '').split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
pageTitle = `${section} - ${title}`;
const section = parts[0];
const fileName = parts[1];
if (!pageTree[section]) {
pageTree[section] = [];
}
const absoluteUrl = new URL(page, window.location.origin).href;
li.innerHTML = `<a href="${absoluteUrl}">${pageTitle}</a>`;
selectedPagesList.appendChild(li);
if (fileName !== 'index.html') {
pageTree[section].push(fileName);
}
});
}
tagsList.addEventListener('change', function(event) {
if (event.target.type === 'checkbox') {
const selectedTag = event.target.value;
const isChecked = event.target.checked;
localStorage.setItem(`tag_${selectedTag}`, isChecked);
console.log(`Tag ${selectedTag} is ${isChecked ? 'selected' : 'deselected'}`);
highlightSidebarLinks();
updateSelectedPages();
for (const [section, pages] of Object.entries(pageTree)) {
const sectionLi = document.createElement('li');
const sectionTitle = section.charAt(0).toUpperCase() + section.slice(1);
sectionLi.innerHTML = `<strong>${sectionTitle}</strong>`;
if (pages.length > 0) {
const subList = document.createElement('ul');
subList.style.paddingLeft = '20px';
pages.forEach(fileName => {
const pageLi = document.createElement('li');
const title = fileName.replace('.html', '').split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
const absoluteUrl = new URL(`${section}/${fileName}`, window.location.origin).href;
pageLi.innerHTML = `<a href="${absoluteUrl}">${title}</a>`;
subList.appendChild(pageLi);
});
sectionLi.appendChild(subList);
}
selectedPagesList.appendChild(sectionLi);
}
});
}
// Initial highlighting and selected pages update based on stored tag selections
highlightSidebarLinks();
updateSelectedPages();
});
const tagsToggle = document.getElementById('tags-toggle');
const tagsDropdown = document.getElementById('tags-dropdown');
const tagSearch = document.getElementById('tag-search');
const tagsList = document.getElementById('tags-list');
const clearSelectedPagesButton = document.getElementById('clear-selected-pages');
clearSelectedPagesButton.addEventListener('click', function() {
localStorage.clear();
const sidebarLinks = document.querySelectorAll('#sidebar a');
sidebarLinks.forEach(link => {
link.style.backgroundColor = '';
});
const tagCheckboxes = document.querySelectorAll('.tag-checkbox');
tagCheckboxes.forEach(checkbox => {
checkbox.checked = false;
});
updateSelectedPages();
});
function createTagElement(tag) {
const li = document.createElement('li');
Expand Down
1 change: 1 addition & 0 deletions theme/tagscolors.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
"SRE": "#388395",
"Legal & Compliance": "#153157",
"Cloud": "#5e30a3",
"HR": "#25ad0e",
"Finance": "#83ddb1"
}
71 changes: 68 additions & 3 deletions theme/tagsindex.json
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@
"monitoring/index.html",
"monitoring/guidelines.html",
"monitoring/thresholds.html",
"operational-security/g-suite-security.html",
"operational-security/standard-operating-environment.html",
"privacy/index.html",
"privacy/data-removal-services.html",
Expand Down Expand Up @@ -239,17 +240,63 @@
],
"Devops": [
"devsecops/index.html",
"devsecops/code-signing.html",
"devsecops/continuous-integration-continuous-deployment.html",
"devsecops/integrated-development-environments.html",
"devsecops/repository-hardening.html",
"devsecops/security-testing.html",
"encryption/index.html",
"encryption/cloud-data-encryption.html",
"external-security-reviews/index.html",
"external-security-reviews/preparation.html",
"front-end-web-app/index.html",
"front-end-web-app/common-vulnerabilities.html",
"governance/compliance-regulatory-requirements.html",
"iam/access-management-best-practises.html",
"iam/role-based-access-control.html",
"iam/secure-authentication.html",
"incident-management/index.html",
"incident-management/lessons-learned.html",
"infrastructure/index.html",
"infrastructure/asset-inventory.html",
"infrastructure/cloud.html",
"security-automation/index.html"
"infrastructure/ddos-protection.html",
"infrastructure/network-security.html",
"infrastructure/operating-system-security.html",
"operational-security/index.html",
"operational-security/g-suite-security.html",
"operational-security/standard-operating-environment.html",
"privacy/index.html",
"secure-software-development/index.html",
"secure-software-development/secure-code-repositories-version-control.html",
"security-automation/index.html",
"security-automation/compliance-checks.html",
"security-automation/infrastructure-as-code.html",
"security-automation/threat-detection-response.html",
"security-testing/index.html",
"supply-chain/index.html",
"threat-modeling/identity-mitigate-threats.html",
"vulnerability-disclosure/index.html"
],
"SRE": [
"devsecops/index.html",
"devsecops/continuous-integration-continuous-deployment.html",
"devsecops/security-testing.html",
"incident-management/index.html",
"incident-management/lessons-learned.html",
"infrastructure/index.html",
"infrastructure/asset-inventory.html",
"infrastructure/cloud.html",
"security-automation/index.html"
"infrastructure/ddos-protection.html",
"infrastructure/network-security.html",
"infrastructure/operating-system-security.html",
"operational-security/index.html",
"operational-security/standard-operating-environment.html",
"security-automation/index.html",
"security-automation/compliance-checks.html",
"security-automation/infrastructure-as-code.html",
"security-automation/threat-detection-response.html",
"security-testing/index.html"
],
"Legal & Compliance": [
"external-security-reviews/security-policies-procedures.html",
Expand All @@ -259,9 +306,27 @@
"governance/security-metrics-kpis.html"
],
"Cloud": [
"encryption/index.html",
"encryption/cloud-data-encryption.html",
"infrastructure/index.html",
"infrastructure/cloud.html",
"security-automation/index.html"
"infrastructure/ddos-protection.html",
"infrastructure/network-security.html",
"security-automation/index.html",
"security-automation/compliance-checks.html",
"security-automation/infrastructure-as-code.html"
],
"HR": [
"awareness/index.html",
"awareness/security-training.html",
"external-security-reviews/security-policies-procedures.html",
"governance/compliance-regulatory-requirements.html",
"iam/access-management-best-practises.html",
"iam/role-based-access-control.html",
"iam/secure-authentication.html",
"operational-security/g-suite-security.html",
"user-team-security/security-aware-culture.html",
"user-team-security/security-training.html"
],
"Finance": [
"key-management/hardware-wallets.html"
Expand Down

0 comments on commit 8e08f62

Please sign in to comment.