Files
Model-Optimizer/docs/source/_static/announcements.js
Chenhan D. Yu ddca53b4bf docs: add announcements landing page (#1971)
## Summary
- Add a JS/static announcements landing page for GitHub Pages
- Keep existing Sphinx docs available under the `api/` subpath
- Add PR-authored announcement posts with tags, search/filtering, image
support, and a DSpark vs Domino sample post

Jira: https://jirasw.nvidia.com/browse/OMNIML-5476

## Verification
- `python3 docs/build_site.py --output docs/build/html`
- Local preview checked at `http://127.0.0.1:8088/`

## Publishing approval
User explicitly approved publishing the `dspark-vs-domino` sample post
and copied image assets from `modelopt-site` to public GitHub in
`NVIDIA/Model-Optimizer`.

## Notes
- Full `uv run nox -s docs` was attempted locally, but dependency
setup/download did not complete in a reasonable time; CI should provide
the authoritative full docs build and PR Pages preview.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added an interactive announcements hub to the documentation homepage
with date sorting, tag filtering, search, pagination, and empty-state
messaging.
* Improved announcement presentation with consistent cards, metadata,
typography, and interactive controls.

* **Documentation**
* Added announcements covering the GitHub Pages announcement hub and a
DSpark versus Domino comparison.
* Added guidance for authoring, reviewing, and discovering future
announcements.
* Updated documentation navigation to feature announcements while
keeping other sections accessible.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Chenhan Yu <chenhany@nvidia.com>
2026-08-13 21:04:54 +00:00

89 lines
2.7 KiB
JavaScript

document.addEventListener('DOMContentLoaded', () => {
const search = document.querySelector('#announcement-search');
const cards = Array.from(document.querySelectorAll('.announcement-card')).sort((left, right) => {
return (right.dataset.date || '').localeCompare(left.dataset.date || '');
});
const tags = Array.from(document.querySelectorAll('.announcement-tag'));
const empty = document.querySelector('#announcement-empty');
const pager = document.querySelector('#announcement-pager');
const prev = document.querySelector('#announcement-prev');
const next = document.querySelector('#announcement-next');
const status = document.querySelector('#announcement-page-status');
const pageSize = 5;
cards.forEach((card) => card.parentNode.appendChild(card));
let activeTag = 'all';
let currentPage = 1;
if (!search || cards.length === 0) {
return;
}
const matchingCards = () => {
const query = search.value.trim().toLowerCase();
return cards.filter((card) => {
const haystack =
[ card.dataset.title, card.dataset.summary, card.dataset.tags ].join(' ').toLowerCase();
const tagMatch =
activeTag === 'all' || (card.dataset.tags || '').split(' ').includes(activeTag);
const searchMatch = !query || haystack.includes(query);
return tagMatch && searchMatch;
});
};
const update = () => {
const matches = matchingCards();
const pageCount = Math.max(1, Math.ceil(matches.length / pageSize));
currentPage = Math.min(currentPage, pageCount);
const start = (currentPage - 1) * pageSize;
const pageCards = new Set(matches.slice(start, start + pageSize));
cards.forEach((card) => { card.hidden = !pageCards.has(card); });
if (empty) {
empty.hidden = matches.length !== 0;
}
if (pager && prev && next && status) {
pager.hidden = matches.length <= pageSize;
prev.disabled = currentPage <= 1;
next.disabled = currentPage >= pageCount;
status.textContent = `Page ${currentPage} of ${pageCount}`;
}
};
tags.forEach((button) => {
button.addEventListener('click', () => {
activeTag = button.dataset.tag || 'all';
currentPage = 1;
tags.forEach((tag) => {
const selected = tag === button;
tag.classList.toggle('is-active', selected);
tag.setAttribute('aria-pressed', selected ? 'true' : 'false');
});
update();
});
});
search.addEventListener('input', () => {
currentPage = 1;
update();
});
if (prev) {
prev.addEventListener('click', () => {
currentPage -= 1;
update();
});
}
if (next) {
next.addEventListener('click', () => {
currentPage += 1;
update();
});
}
update();
});