WIP: Refactored all scripts from footer.js into components. Removed footer.js. Exports jQuery ($) to a window global for use by other scripts. Scripts bundled into footer.js didn't reliably load after jQuery.

pull/6079/head
Jason Stirnaman 2025-05-12 15:58:12 -05:00
parent db4048f9e3
commit ccf74df759
16 changed files with 138 additions and 109 deletions

View File

@ -0,0 +1,6 @@
import SearchInteractions from '../utils/search-interactions';
export default function SidebarSearch({ component }) {
const searchInput = component.querySelector('.sidebar--search-field');
SearchInteractions({ searchInput });
}

View File

@ -6,6 +6,9 @@
assets/js/cookies.js. assets/js/cookies.js.
*/ */
import $ from 'jquery';
import * as LocalStorageAPI from './local-storage.js';
// Get notification ID // Get notification ID
function getCalloutID(el) { function getCalloutID(el) {
return $(el).attr('id'); return $(el).attr('id');
@ -13,26 +16,19 @@ function getCalloutID (el) {
// Hide a callout and update the cookie with the viewed callout // Hide a callout and update the cookie with the viewed callout
function hideCallout(calloutID) { function hideCallout(calloutID) {
if (!window.LocalStorageAPI.notificationIsRead(calloutID)) { if (!LocalStorageAPI.notificationIsRead(calloutID)) {
window.LocalStorageAPI.setNotificationAsRead(calloutID, 'callout'); LocalStorageAPI.setNotificationAsRead(calloutID, 'callout');
$(`#${calloutID}`).fadeOut(200); $(`#${calloutID}`).fadeOut(200);
} }
} }
// Show the url feature callouts on page load // Show the url feature callouts on page load
$(document).ready(function () { export default function FeatureCallout({ component }) {
$('.feature-callout').each(function () { const calloutID = getCalloutID($(component));
const calloutID = getCalloutID($(this));
if (!window.LocalStorageAPI.notificationIsRead(calloutID, 'callout')) { if (LocalStorageAPI.notificationIsRead(calloutID, 'callout')) {
$(`#${calloutID}.feature-callout`) $(`#${calloutID}.feature-callout`)
.fadeIn(300) .fadeIn(300)
.removeClass('start-position'); .removeClass('start-position');
} }
}); }
});
// Hide the InfluxDB URL selector callout
// $('button.url-trigger, #influxdb-url-selector .close').click(function () {
// hideCallout('influxdb-url-selector');
// });

View File

@ -11,17 +11,14 @@ function getPlatform() {
} }
} }
const platform = getPlatform() function addOSClass(osClass, { $component }) {
$component.addClass(osClass)
function addOSClass(osClass) {
$('.keybinding').addClass(osClass)
} }
function updateKeyBindings() { function updateKeyBindings({ $component }) {
$('.keybinding').each(function() { var osx = $component.data("osx")
var osx = $(this).data("osx") var linux = $component.data("linux")
var linux = $(this).data("linux") var win = $component.data("win")
var win = $(this).data("win")
if (platform === "other") { if (platform === "other") {
if (win != linux) { if (win != linux) {
@ -30,12 +27,16 @@ function updateKeyBindings() {
var keybind = '<code>' + linux + '</code> for Linux and Windows and <code class="osx">' + osx + '</code> for macOS'; var keybind = '<code>' + linux + '</code> for Linux and Windows and <code class="osx">' + osx + '</code> for macOS';
} }
} else { } else {
var keybind = '<code>' + $(this).data(platform) + '</code>' var keybind = '<code>' + $component.data(platform) + '</code>'
} }
$(this).html(keybind) $component.html(keybind)
})
} }
addOSClass(platform) export default function KeyBinding({ component }) {
updateKeyBindings() // Initialize keybindings
const platform = getPlatform();
const $component = $(component);
addOSClass(platform, { $component });
updateKeyBindings({ $component });
}

View File

@ -3,8 +3,8 @@ function countTag(tag) {
return $(".visible[data-tags*='" + tag + "']").length return $(".visible[data-tags*='" + tag + "']").length
} }
function getFilterCounts() { function getFilterCounts($labels) {
$('#list-filters label').each(function() { $labels.each(function() {
var tagName = $('input', this).attr('name').replace(/[\W/]+/, "-"); var tagName = $('input', this).attr('name').replace(/[\W/]+/, "-");
var tagCount = countTag(tagName); var tagCount = countTag(tagName);
$(this).attr('data-count', '(' + tagCount + ')'); $(this).attr('data-count', '(' + tagCount + ')');
@ -16,18 +16,21 @@ function getFilterCounts() {
}) })
} }
// Get initial filter count on page load export default function ListFilters({ component }) {
getFilterCounts() const $labels = $(component).find('label');
const $inputs = $(component).find('input');
$("#list-filters input").click(function() { getFilterCounts($labels);
$inputs.click(function() {
// List of tags to hide // List of tags to hide
var tagArray = $("#list-filters input:checkbox:checked").map(function(){ var tagArray = $(component).find("input:checkbox:checked").map(function(){
return $(this).attr('name').replace(/[\W]+/, "-"); return $(this).attr('name').replace(/[\W]+/, "-");
}).get(); }).get();
// List of tags to restore // List of tags to restore
var restoreArray = $("#list-filters input:checkbox:not(:checked)").map(function(){ var restoreArray = $(component).find("input:checkbox:not(:checked)").map(function(){
return $(this).attr('name').replace(/[\W]+/, "-"); return $(this).attr('name').replace(/[\W]+/, "-");
}).get(); }).get();
@ -46,5 +49,6 @@ $("#list-filters input").click(function() {
} }
// Refresh filter count // Refresh filter count
getFilterCounts() getFilterCounts($labels);
}); });
}

View File

@ -3,6 +3,9 @@
// If you need to pass parameters from the calling Hugo page, you can import them here like so: // If you need to pass parameters from the calling Hugo page, you can import them here like so:
// import * as pageParams from '@params'; // import * as pageParams from '@params';
// Import dependencies that we still need to load in the global scope
import $ from 'jquery';
/** Import modules that are not components. /** Import modules that are not components.
* TODO: Refactor these into single-purpose component modules. * TODO: Refactor these into single-purpose component modules.
*/ */
@ -29,8 +32,13 @@ import * as v3Wayfinding from './v3-wayfinding.js';
import AskAITrigger from './ask-ai-trigger.js'; import AskAITrigger from './ask-ai-trigger.js';
import CodePlaceholder from './code-placeholders.js'; import CodePlaceholder from './code-placeholders.js';
import { CustomTimeTrigger } from './custom-timestamps.js'; import { CustomTimeTrigger } from './custom-timestamps.js';
import FeatureCallout from './feature-callouts.js';
import FluxInfluxDBVersionsTrigger from './flux-influxdb-versions.js'; import FluxInfluxDBVersionsTrigger from './flux-influxdb-versions.js';
import KeyBinding from './keybindings.js';
import ListFilters from './list-filters.js';
import ProductSelector from './version-selector.js';
import { SearchButton } from './search-button.js'; import { SearchButton } from './search-button.js';
import SidebarSearch from './components/sidebar-search.js';
import { SidebarToggle } from './sidebar-toggle.js'; import { SidebarToggle } from './sidebar-toggle.js';
import Theme from './theme.js'; import Theme from './theme.js';
import ThemeSwitch from './theme-switch.js'; import ThemeSwitch from './theme-switch.js';
@ -49,8 +57,13 @@ const componentRegistry = {
'ask-ai-trigger': AskAITrigger, 'ask-ai-trigger': AskAITrigger,
'code-placeholder': CodePlaceholder, 'code-placeholder': CodePlaceholder,
'custom-time-trigger': CustomTimeTrigger, 'custom-time-trigger': CustomTimeTrigger,
'feature-callout': FeatureCallout,
'flux-influxdb-versions-trigger': FluxInfluxDBVersionsTrigger, 'flux-influxdb-versions-trigger': FluxInfluxDBVersionsTrigger,
'keybinding': KeyBinding,
'list-filters': ListFilters,
'product-selector': ProductSelector,
'search-button': SearchButton, 'search-button': SearchButton,
'sidebar-search': SidebarSearch,
'sidebar-toggle': SidebarToggle, 'sidebar-toggle': SidebarToggle,
'theme': Theme, 'theme': Theme,
'theme-switch': ThemeSwitch 'theme-switch': ThemeSwitch
@ -72,6 +85,11 @@ function initGlobals() {
window.influxdatadocs.toggleModal = modals.toggleModal; window.influxdatadocs.toggleModal = modals.toggleModal;
window.influxdatadocs.componentRegistry = componentRegistry; window.influxdatadocs.componentRegistry = componentRegistry;
// Re-export jQuery to global namespace for legacy scripts
if (typeof window.jQuery === 'undefined') {
window.jQuery = window.$ = $;
}
return window.influxdatadocs; return window.influxdatadocs;
} }

View File

@ -1,10 +0,0 @@
// Fade content wrapper when focusing on search input
$('#algolia-search-input').focus(function() {
$('.content-wrapper').fadeTo(300, .35);
})
// Hide search dropdown when leaving search input
$('#algolia-search-input').blur(function() {
$('.content-wrapper').fadeTo(200, 1);
$('.ds-dropdown-menu').hide();
})

View File

@ -0,0 +1,22 @@
export default function SearchInteractions({ searchInput }) {
const contentWrapper = document.querySelector('.content-wrapper');
const dropdownMenu = document.querySelector('.ds-dropdown-menu');
// Fade content wrapper when focusing on search input
searchInput.addEventListener('focus', () => {
// Using CSS transitions instead of jQuery's fadeTo for better performance
contentWrapper.style.opacity = '0.35';
contentWrapper.style.transition = 'opacity 300ms';
});
// Hide search dropdown when leaving search input
searchInput.addEventListener('blur', () => {
contentWrapper.style.opacity = '1';
contentWrapper.style.transition = 'opacity 200ms';
// Hide dropdown menu
if (dropdownMenu) {
dropdownMenu.style.display = 'none';
}
});
}

View File

@ -1,6 +1,7 @@
export default function ProductSelector({ component }) {
// Select the product dropdown and dropdown items // Select the product dropdown and dropdown items
const productDropdown = document.querySelector("#product-dropdown"); const productDropdown = component.querySelector("#product-dropdown");
const dropdownItems = document.querySelector("#dropdown-items"); const dropdownItems = component.querySelector("#dropdown-items");
// Expand the menu on click // Expand the menu on click
if (productDropdown) { if (productDropdown) {
@ -17,3 +18,4 @@ document.addEventListener("click", function(e) {
dropdownItems.classList.remove("open"); dropdownItems.classList.remove("open");
} }
}); });
}

View File

@ -19,7 +19,7 @@
<div class="home-content"> <div class="home-content">
<div class="section search"> <div class="section search">
<div class="sidebar--search"> <div class="sidebar--search" data-component="sidebar-search">
<input class="sidebar--search-field" <input class="sidebar--search-field"
id="algolia-search-input" id="algolia-search-input"
type="text" type="text"

View File

@ -13,7 +13,7 @@
{{ $urlCalloutText := $scratch.Get "urlCalloutText" }} {{ $urlCalloutText := $scratch.Get "urlCalloutText" }}
<!-- {{ if or $isOSS $isCloud $isHome }} <!-- {{ if or $isOSS $isCloud $isHome }}
<div class="feature-callout start-position" id="callout-url-selector"> <div class="feature-callout start-position" id="callout-url-selector" data-component="feature-callout">
<p>{{ $urlCalloutText }} <a href="#" class="close"><span class="icon-remove"></span></a></p> <p>{{ $urlCalloutText }} <a href="#" class="close"><span class="icon-remove"></span></a></p>
</div> </div>
{{ end }} --> {{ end }} -->

View File

@ -1,14 +1,6 @@
{{ $jquery := resources.Get "js/jquery-3.5.0.min.js" }}
{{ $versionSelector := resources.Get "js/version-selector.js" }}
{{ $searchInteractions := resources.Get "js/search-interactions.js" }}
{{ $listFilters := resources.Get "js/list-filters.js" }}
{{ $featureCallouts := resources.Get "js/feature-callouts.js" }}
{{ $keybindings := resources.Get "js/keybindings.js" }}
{{ $fluxGroupKeys := resources.Get "js/flux-group-keys.js" }} {{ $fluxGroupKeys := resources.Get "js/flux-group-keys.js" }}
{{ $dateTime := resources.Get "js/datetime.js" }} {{ $dateTime := resources.Get "js/datetime.js" }}
{{ $homepageInteractions := resources.Get "js/home-interactions.js" }}
{{ $releaseTOC := resources.Get "/js/release-toc.js" }} {{ $releaseTOC := resources.Get "/js/release-toc.js" }}
{{ $footerjs := slice $jquery $versionSelector $searchInteractions $listFilters $featureCallouts $keybindings $homepageInteractions | resources.Concat "js/footer.bundle.js" | resources.Fingerprint }}
{{ $fluxGroupKeyjs := $fluxGroupKeys | resources.Fingerprint }} {{ $fluxGroupKeyjs := $fluxGroupKeys | resources.Fingerprint }}
{{ $dateTimejs := $dateTime | resources.Fingerprint }} {{ $dateTimejs := $dateTime | resources.Fingerprint }}
{{ $releaseTOCjs := $releaseTOC | resources.Fingerprint }} {{ $releaseTOCjs := $releaseTOC | resources.Fingerprint }}
@ -22,6 +14,7 @@
] ]
</script> </script>
{{ if .Page.HasShortcode "diagram" }} {{ if .Page.HasShortcode "diagram" }}
<!-- Load mermaid.js for diagrams --> <!-- Load mermaid.js for diagrams -->
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
@ -52,6 +45,3 @@
{{ if .Page.HasShortcode "release-toc" }} {{ if .Page.HasShortcode "release-toc" }}
<script type="text/javascript" src="{{ $releaseTOCjs.RelPermalink }}"></script> <script type="text/javascript" src="{{ $releaseTOCjs.RelPermalink }}"></script>
{{ end }} {{ end }}
<!-- Load footer.js -->
<script type="text/javascript" src="{{ $footerjs.RelPermalink }}"></script>

View File

@ -12,7 +12,7 @@
{{ end -}} {{ end -}}
{{ $products := .Site.Data.products }} {{ $products := .Site.Data.products }}
{{ $influxdb_urls := .Site.Data.influxdb_urls }} {{ $influxdb_urls := .Site.Data.influxdb_urls }}
<!-- Build main.js --> <!-- Build index.js -->
{{ with resources.Get "js/index.js" }} {{ with resources.Get "js/index.js" }}
{{ $opts := dict {{ $opts := dict
"minify" hugo.IsProduction "minify" hugo.IsProduction
@ -23,10 +23,10 @@
{{ with . | js.Build $opts }} {{ with . | js.Build $opts }}
{{ if hugo.IsProduction }} {{ if hugo.IsProduction }}
{{ with . | fingerprint }} {{ with . | fingerprint }}
<script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script> <script defer src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script>
{{ end }} {{ end }}
{{ else }} {{ else }}
<script src="{{ .RelPermalink }}"></script> <script defer src="{{ .RelPermalink }}"></script>
{{ end }} {{ end }}
{{ end }} {{ end }}
{{ end }} {{ end }}

View File

@ -49,7 +49,7 @@
<aside class="sidebar"> <aside class="sidebar">
{{ partial "sidebar/sidebar-toggle.html" (dict "state" "Close") }} {{ partial "sidebar/sidebar-toggle.html" (dict "state" "Close") }}
<div class="search-and-nav-toggle"> <div class="search-and-nav-toggle">
<div class="sidebar--search"> <div class="sidebar--search" data-component="sidebar-search">
<input class="sidebar--search-field" <input class="sidebar--search-field"
id="algolia-search-input" id="algolia-search-input"
type="text" type="text"

View File

@ -43,7 +43,7 @@ Identify products by their product path. Dictionary schema:
{{ $templateDefaults := dict "context" . "productInfo" $productInfo "altLinks" $altLinks "pageRoot" $pageRoot "useRootProductLink" $useRootProductLink }} {{ $templateDefaults := dict "context" . "productInfo" $productInfo "altLinks" $altLinks "pageRoot" $pageRoot "useRootProductLink" $useRootProductLink }}
<div class="product-list"> <div class="product-list" data-component="product-selector">
<div id="product-dropdown"> <div id="product-dropdown">
<p class="selected">{{ index (index $productInfo $pageRoot) 0 | default "Select product" }}</p> <p class="selected">{{ index (index $productInfo $pageRoot) 0 | default "Select product" }}</p>
</div> </div>

View File

@ -5,4 +5,4 @@
{{- $mac := .Get "mac" | default $default -}} {{- $mac := .Get "mac" | default $default -}}
{{- $win := .Get "win" | default $default -}} {{- $win := .Get "win" | default $default -}}
{{- $linux := .Get "linux" | default $default -}} {{- $linux := .Get "linux" | default $default -}}
<span class="keybinding" data-osx="{{ $mac }}" data-win="{{ $win }}" data-linux="{{ $linux }}"><code>{{ $default }}</code></span> <span class="keybinding" data-osx="{{ $mac }}" data-win="{{ $win }}" data-linux="{{ $linux }}" data-component="keybinding"><code>{{ $default }}</code></span>

View File

@ -1,6 +1,6 @@
{{ $source := .Get 0 | default "telegraf"}} {{ $source := .Get 0 | default "telegraf"}}
<div id="list-filters"> <div id="list-filters" data-component="list-filters">
{{ range ( index .Site.Data.list_filters $source) }} {{ range ( index .Site.Data.list_filters $source) }}
{{ $numValues := len .values }} {{ $numValues := len .values }}