Merge pull request #6079 from influxdata/chore-js-refactor-footer-scripts-modules
Chore: JavaScript: refactor footer scripts moduleschore-js-refactor-footer-scripts-modules
parent
47cb2ce617
commit
4973026adf
|
@ -1,4 +1,4 @@
|
|||
version: 2
|
||||
version: 2.1
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
|
@ -41,7 +41,7 @@ jobs:
|
|||
- /home/circleci/bin
|
||||
- run:
|
||||
name: Hugo Build
|
||||
command: npx hugo --logLevel info --minify --destination workspace/public
|
||||
command: npx hugo --config config/production/config.yml --logLevel info --minify --gc --destination workspace/public
|
||||
- persist_to_workspace:
|
||||
root: workspace
|
||||
paths:
|
||||
|
@ -68,7 +68,6 @@ jobs:
|
|||
when: on_success
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build:
|
||||
jobs:
|
||||
- build
|
||||
|
|
|
@ -1679,7 +1679,7 @@ The shortcode takes a regular expression for matching placeholder names.
|
|||
Use the `code-placeholder-key` shortcode to format the placeholder names in
|
||||
text that describes the placeholder--for example:
|
||||
|
||||
```
|
||||
```markdown
|
||||
{{% code-placeholders "DATABASE_NAME|USERNAME|PASSWORD_OR_TOKEN|API_TOKEN|exampleuser@influxdata.com" %}}
|
||||
```sh
|
||||
curl --request POST http://localhost:8086/write?db=DATABASE_NAME \
|
||||
|
@ -1703,3 +1703,64 @@ InfluxDB API documentation when documentation is deployed.
|
|||
Redoc generates HTML documentation using the InfluxDB `swagger.yml`.
|
||||
For more information about generating InfluxDB API documentation, see the
|
||||
[API Documentation README](https://github.com/influxdata/docs-v2/tree/master/api-docs#readme).
|
||||
|
||||
## JavaScript in the documentation UI
|
||||
|
||||
The InfluxData documentation UI uses JavaScript with ES6+ syntax and
|
||||
`assets/js/main.js` as the entry point to import modules from
|
||||
`assets/js`.
|
||||
Only `assets/js/main.js` should be imported in HTML files.
|
||||
|
||||
`assets/js/main.js` registers components and initializes them on page load.
|
||||
|
||||
If you're adding UI functionality that requires JavaScript, follow these steps:
|
||||
|
||||
1. In your HTML file, add a `data-component` attribute to the element that
|
||||
should be initialized by your JavaScript code. For example:
|
||||
|
||||
```html
|
||||
<div data-component="my-component"></div>
|
||||
```
|
||||
|
||||
2. Following the component pattern, create a single-purpose JavaScript module
|
||||
(`assets/js/components/my-component.js`)
|
||||
that exports a single function that receives the component element and initializes it.
|
||||
3. In `assets/js/main.js`, import the module and register the component to ensure
|
||||
the component is initialized on page load.
|
||||
|
||||
### Debugging JavaScript
|
||||
|
||||
To debug JavaScript code used in the InfluxData documentation UI:
|
||||
|
||||
1. In your JavaScript module, import debug helpers from `assets/js/utils/debug-helpers.js`.
|
||||
These helpers provide breakpoints and console logging as a workaround for
|
||||
Hugo's lack of source map support in the asset pipeline.
|
||||
2. Insert debug statements by calling the helper functions in your code--for example:
|
||||
|
||||
```js
|
||||
import { debugLog, debugBreak, debugInspect } from './utils/debug-helpers.js';
|
||||
|
||||
const data = debugInspect(someData, 'Data');
|
||||
debugLog('Processing data', 'myFunction');
|
||||
|
||||
function processData() {
|
||||
// Add a breakpoint that works with DevTools
|
||||
debugBreak();
|
||||
|
||||
// Your existing code...
|
||||
}
|
||||
```
|
||||
|
||||
3. Start Hugo in development mode--for example:
|
||||
|
||||
```bash
|
||||
yarn hugo server
|
||||
```
|
||||
|
||||
4. In VS Code, go to Run > Start Debugging, and select the "Debug Docs (console-based)" configuration.
|
||||
|
||||
Your system uses the configuration in `launch.json` to launch the site in Chrome
|
||||
and attach the debugger to the Developer Tools console.
|
||||
|
||||
Make sure to remove the debug statements before merging your changes.
|
||||
The debug helpers are designed to be used in development and should not be used in production.
|
||||
|
|
|
@ -21,6 +21,7 @@ node_modules
|
|||
test-results.xml
|
||||
/influxdb3cli-build-scripts/content
|
||||
.vscode/*
|
||||
!.vscode/launch.json
|
||||
.idea
|
||||
**/config.toml
|
||||
package-lock.json
|
||||
|
|
|
@ -3,3 +3,4 @@
|
|||
**/.svn
|
||||
**/.hg
|
||||
**/node_modules
|
||||
assets/jsconfig.json
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug Docs (console-based)",
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"url": "http://localhost:1313",
|
||||
"webRoot": "${workspaceFolder}",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"sourceMaps": false,
|
||||
"trace": true,
|
||||
"smartStep": false
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1667,7 +1667,7 @@ The shortcode takes a regular expression for matching placeholder names.
|
|||
Use the `code-placeholder-key` shortcode to format the placeholder names in
|
||||
text that describes the placeholder--for example:
|
||||
|
||||
```
|
||||
```markdown
|
||||
{{% code-placeholders "DATABASE_NAME|USERNAME|PASSWORD_OR_TOKEN|API_TOKEN|exampleuser@influxdata.com" %}}
|
||||
```sh
|
||||
curl --request POST http://localhost:8086/write?db=DATABASE_NAME \
|
||||
|
@ -1691,3 +1691,64 @@ InfluxDB API documentation when documentation is deployed.
|
|||
Redoc generates HTML documentation using the InfluxDB `swagger.yml`.
|
||||
For more information about generating InfluxDB API documentation, see the
|
||||
[API Documentation README](https://github.com/influxdata/docs-v2/tree/master/api-docs#readme).
|
||||
|
||||
## JavaScript in the documentation UI
|
||||
|
||||
The InfluxData documentation UI uses JavaScript with ES6+ syntax and
|
||||
`assets/js/main.js` as the entry point to import modules from
|
||||
`assets/js`.
|
||||
Only `assets/js/main.js` should be imported in HTML files.
|
||||
|
||||
`assets/js/main.js` registers components and initializes them on page load.
|
||||
|
||||
If you're adding UI functionality that requires JavaScript, follow these steps:
|
||||
|
||||
1. In your HTML file, add a `data-component` attribute to the element that
|
||||
should be initialized by your JavaScript code. For example:
|
||||
|
||||
```html
|
||||
<div data-component="my-component"></div>
|
||||
```
|
||||
|
||||
2. Following the component pattern, create a single-purpose JavaScript module
|
||||
(`assets/js/components/my-component.js`)
|
||||
that exports a single function that receives the component element and initializes it.
|
||||
3. In `assets/js/main.js`, import the module and register the component to ensure
|
||||
the component is initialized on page load.
|
||||
|
||||
### Debugging JavaScript
|
||||
|
||||
To debug JavaScript code used in the InfluxData documentation UI:
|
||||
|
||||
1. In your JavaScript module, import debug helpers from `assets/js/utils/debug-helpers.js`.
|
||||
These helpers provide breakpoints and console logging as a workaround for
|
||||
Hugo's lack of source map support in the asset pipeline.
|
||||
2. Insert debug statements by calling the helper functions in your code--for example:
|
||||
|
||||
```js
|
||||
import { debugLog, debugBreak, debugInspect } from './utils/debug-helpers.js';
|
||||
|
||||
const data = debugInspect(someData, 'Data');
|
||||
debugLog('Processing data', 'myFunction');
|
||||
|
||||
function processData() {
|
||||
// Add a breakpoint that works with DevTools
|
||||
debugBreak();
|
||||
|
||||
// Your existing code...
|
||||
}
|
||||
```
|
||||
|
||||
3. Start Hugo in development mode--for example:
|
||||
|
||||
```bash
|
||||
yarn hugo server
|
||||
```
|
||||
|
||||
4. In VS Code, go to Run > Start Debugging, and select the "Debug Docs (console-based)" configuration.
|
||||
|
||||
Your system uses the configuration in `launch.json` to launch the site in Chrome
|
||||
and attach the debugger to the Developer Tools console.
|
||||
|
||||
Make sure to remove the debug statements before merging your changes.
|
||||
The debug helpers are designed to be used in development and should not be used in production.
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
// Memoize the mermaid module import
|
||||
let mermaidPromise = null;
|
||||
|
||||
export default function Diagram({ component }) {
|
||||
// Import mermaid.js module (memoized)
|
||||
if (!mermaidPromise) {
|
||||
mermaidPromise = import('mermaid');
|
||||
}
|
||||
mermaidPromise.then(({ default: mermaid }) => {
|
||||
// Configure mermaid with InfluxData theming
|
||||
mermaid.initialize({
|
||||
startOnLoad: false, // We'll manually call run()
|
||||
theme: document.body.classList.contains('dark-theme') ? 'dark' : 'default',
|
||||
themeVariables: {
|
||||
fontFamily: 'Proxima Nova',
|
||||
fontSize: '16px',
|
||||
lineColor: '#22ADF6',
|
||||
primaryColor: '#22ADF6',
|
||||
primaryTextColor: '#545454',
|
||||
secondaryColor: '#05CE78',
|
||||
tertiaryColor: '#f4f5f5',
|
||||
},
|
||||
securityLevel: 'loose', // Required for interactive diagrams
|
||||
logLevel: 'error'
|
||||
});
|
||||
|
||||
// Process the specific diagram component
|
||||
try {
|
||||
mermaid.run({ nodes: [component] });
|
||||
} catch (error) {
|
||||
console.error('Mermaid diagram rendering error:', error);
|
||||
}
|
||||
|
||||
// Store reference to mermaid for theme switching
|
||||
if (!window.mermaidInstances) {
|
||||
window.mermaidInstances = new Map();
|
||||
}
|
||||
window.mermaidInstances.set(component, mermaid);
|
||||
}).catch(error => {
|
||||
console.error('Failed to load Mermaid library:', error);
|
||||
});
|
||||
|
||||
// Listen for theme changes to refresh diagrams
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
if (mutation.attributeName === 'class' &&
|
||||
document.body.classList.contains('dark-theme') !== window.isDarkTheme) {
|
||||
window.isDarkTheme = document.body.classList.contains('dark-theme');
|
||||
|
||||
// Reload this specific diagram with new theme
|
||||
if (window.mermaidInstances?.has(component)) {
|
||||
const mermaid = window.mermaidInstances.get(component);
|
||||
mermaid.initialize({
|
||||
theme: window.isDarkTheme ? 'dark' : 'default'
|
||||
});
|
||||
mermaid.run({ nodes: [component] });
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Watch for theme changes on body element
|
||||
observer.observe(document.body, { attributes: true });
|
||||
|
||||
// Return cleanup function to be called when component is destroyed
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
if (window.mermaidInstances?.has(component)) {
|
||||
window.mermaidInstances.delete(component);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
/**
|
||||
* DocSearch component for InfluxData documentation
|
||||
* Handles asynchronous loading and initialization of Algolia DocSearch
|
||||
*/
|
||||
const debug = false; // Set to true for debugging output
|
||||
|
||||
export default function DocSearch({ component }) {
|
||||
// Store configuration from component data attributes
|
||||
const config = {
|
||||
apiKey: component.getAttribute('data-api-key'),
|
||||
appId: component.getAttribute('data-app-id'),
|
||||
indexName: component.getAttribute('data-index-name'),
|
||||
inputSelector: component.getAttribute('data-input-selector'),
|
||||
searchTag: component.getAttribute('data-search-tag'),
|
||||
includeFlux: component.getAttribute('data-include-flux') === 'true',
|
||||
includeResources:
|
||||
component.getAttribute('data-include-resources') === 'true',
|
||||
debug: component.getAttribute('data-debug') === 'true',
|
||||
};
|
||||
|
||||
// Initialize global object to track DocSearch state
|
||||
window.InfluxDocs = window.InfluxDocs || {};
|
||||
window.InfluxDocs.search = {
|
||||
initialized: false,
|
||||
options: config,
|
||||
};
|
||||
|
||||
// Load DocSearch asynchronously
|
||||
function loadDocSearch() {
|
||||
if (debug) {
|
||||
console.log('Loading DocSearch script...');
|
||||
}
|
||||
const script = document.createElement('script');
|
||||
script.src =
|
||||
'https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js';
|
||||
script.async = true;
|
||||
script.onload = initializeDocSearch;
|
||||
document.body.appendChild(script);
|
||||
}
|
||||
|
||||
// Initialize DocSearch after script loads
|
||||
function initializeDocSearch() {
|
||||
if (debug) {
|
||||
console.log('Initializing DocSearch...');
|
||||
}
|
||||
const multiVersion = ['influxdb'];
|
||||
|
||||
// Use object-based lookups instead of conditionals for version and product names
|
||||
// These can be replaced with data from productData in the future
|
||||
|
||||
// Version display name mappings
|
||||
const versionDisplayNames = {
|
||||
cloud: 'Cloud (TSM)',
|
||||
core: 'Core',
|
||||
enterprise: 'Enterprise',
|
||||
'cloud-serverless': 'Cloud Serverless',
|
||||
'cloud-dedicated': 'Cloud Dedicated',
|
||||
clustered: 'Clustered',
|
||||
explorer: 'Explorer',
|
||||
};
|
||||
|
||||
// Product display name mappings
|
||||
const productDisplayNames = {
|
||||
influxdb: 'InfluxDB',
|
||||
influxdb3: 'InfluxDB 3',
|
||||
explorer: 'InfluxDB 3 Explorer',
|
||||
enterprise_influxdb: 'InfluxDB Enterprise',
|
||||
flux: 'Flux',
|
||||
telegraf: 'Telegraf',
|
||||
chronograf: 'Chronograf',
|
||||
kapacitor: 'Kapacitor',
|
||||
platform: 'InfluxData Platform',
|
||||
resources: 'Additional Resources',
|
||||
};
|
||||
|
||||
// Initialize DocSearch with configuration
|
||||
window.docsearch({
|
||||
apiKey: config.apiKey,
|
||||
appId: config.appId,
|
||||
indexName: config.indexName,
|
||||
inputSelector: config.inputSelector,
|
||||
debug: config.debug,
|
||||
transformData: function (hits) {
|
||||
// Format version using object lookup instead of if-else chain
|
||||
function fmtVersion(version, productKey) {
|
||||
if (version == null) {
|
||||
return '';
|
||||
} else if (versionDisplayNames[version]) {
|
||||
return versionDisplayNames[version];
|
||||
} else if (multiVersion.includes(productKey)) {
|
||||
return version;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
hits.map((hit) => {
|
||||
const pathData = new URL(hit.url).pathname
|
||||
.split('/')
|
||||
.filter((n) => n);
|
||||
const product = productDisplayNames[pathData[0]] || pathData[0];
|
||||
const version = fmtVersion(pathData[1], pathData[0]);
|
||||
|
||||
hit.product = product;
|
||||
hit.version = version;
|
||||
hit.hierarchy.lvl0 =
|
||||
hit.hierarchy.lvl0 +
|
||||
` <span class=\"search-product-version\">${product} ${version}</span>`;
|
||||
hit._highlightResult.hierarchy.lvl0.value =
|
||||
hit._highlightResult.hierarchy.lvl0.value +
|
||||
` <span class=\"search-product-version\">${product} ${version}</span>`;
|
||||
});
|
||||
return hits;
|
||||
},
|
||||
algoliaOptions: {
|
||||
hitsPerPage: 10,
|
||||
facetFilters: buildFacetFilters(config),
|
||||
},
|
||||
autocompleteOptions: {
|
||||
templates: {
|
||||
header:
|
||||
'<div class="search-all-content"><a href="https:\/\/support.influxdata.com" target="_blank">Search all InfluxData content <span class="icon-arrow-up-right"></span></a>',
|
||||
empty:
|
||||
'<div class="search-no-results"><p>Not finding what you\'re looking for?</p> <a href="https:\/\/support.influxdata.com" target="_blank">Search all InfluxData content <span class="icon-arrow-up-right"></span></a></div>',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Mark DocSearch as initialized
|
||||
window.InfluxDocs.search.initialized = true;
|
||||
|
||||
// Dispatch event for other components to know DocSearch is ready
|
||||
window.dispatchEvent(new CustomEvent('docsearch-initialized'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to build facet filters based on config
|
||||
* - Uses nested arrays for AND conditions
|
||||
* - Includes space after colon in filter expressions
|
||||
*/
|
||||
function buildFacetFilters(config) {
|
||||
if (!config.searchTag) {
|
||||
return ['latest:true'];
|
||||
} else if (config.includeFlux) {
|
||||
// Return a nested array to match original template structure
|
||||
// Note the space after each colon
|
||||
return [
|
||||
[
|
||||
'searchTag: ' + config.searchTag,
|
||||
'flux:true',
|
||||
'resources: ' + config.includeResources,
|
||||
],
|
||||
];
|
||||
} else {
|
||||
// Return a nested array to match original template structure
|
||||
// Note the space after each colon
|
||||
return [
|
||||
[
|
||||
'searchTag: ' + config.searchTag,
|
||||
'resources: ' + config.includeResources,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Load DocSearch when page is idle or after a slight delay
|
||||
if ('requestIdleCallback' in window) {
|
||||
requestIdleCallback(loadDocSearch);
|
||||
} else {
|
||||
setTimeout(loadDocSearch, 500);
|
||||
}
|
||||
|
||||
// Return cleanup function
|
||||
return function cleanup() {
|
||||
// Clean up any event listeners if needed
|
||||
if (debug) {
|
||||
console.log('DocSearch component cleanup');
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
import SearchInteractions from '../utils/search-interactions';
|
||||
|
||||
export default function SidebarSearch({ component }) {
|
||||
const searchInput = component.querySelector('.sidebar--search-field');
|
||||
SearchInteractions({ searchInput });
|
||||
}
|
|
@ -1,30 +1,54 @@
|
|||
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
||||
var date = new Date()
|
||||
var currentTimestamp = date.toISOString().replace(/^(.*)(\.\d+)(Z)/, '$1$3') // 2023-01-01T12:34:56Z
|
||||
var currentTime = date.toISOString().replace(/(^.*T)(.*)(Z)/, '$2') + '084216' // 12:34:56.000084216
|
||||
import $ from 'jquery';
|
||||
|
||||
function currentDate(offset=0, trimTime=false) {
|
||||
outputDate = new Date(date)
|
||||
outputDate.setDate(outputDate.getDate() + offset)
|
||||
var date = new Date();
|
||||
var currentTimestamp = date.toISOString().replace(/^(.*)(\.\d+)(Z)/, '$1$3'); // 2023-01-01T12:34:56Z
|
||||
|
||||
// Microsecond offset appended to the current time string for formatting purposes
|
||||
const MICROSECOND_OFFSET = '084216';
|
||||
|
||||
var currentTime =
|
||||
date.toISOString().replace(/(^.*T)(.*)(Z)/, '$2') + MICROSECOND_OFFSET; // 12:34:56.000084216
|
||||
function currentDate(offset = 0, trimTime = false) {
|
||||
let outputDate = new Date(date);
|
||||
outputDate.setDate(outputDate.getDate() + offset);
|
||||
|
||||
if (trimTime) {
|
||||
return outputDate.toISOString().replace(/T.*$/, '') // 2023-01-01
|
||||
return outputDate.toISOString().replace(/T.*$/, ''); // 2023-01-01
|
||||
} else {
|
||||
return outputDate.toISOString().replace(/T.*$/, 'T00:00:00Z') // 2023-01-01T00:00:00Z
|
||||
return outputDate.toISOString().replace(/T.*$/, 'T00:00:00Z'); // 2023-01-01T00:00:00Z
|
||||
}
|
||||
}
|
||||
|
||||
function enterpriseEOLDate() {
|
||||
var inTwoYears = date.setFullYear(date.getFullYear() + 2)
|
||||
earliestEOL = new Date(inTwoYears)
|
||||
return `${monthNames[earliestEOL.getMonth()]} ${earliestEOL.getDate()}, ${earliestEOL.getFullYear()}`
|
||||
const monthNames = [
|
||||
'January',
|
||||
'February',
|
||||
'March',
|
||||
'April',
|
||||
'May',
|
||||
'June',
|
||||
'July',
|
||||
'August',
|
||||
'September',
|
||||
'October',
|
||||
'November',
|
||||
'December',
|
||||
];
|
||||
var inTwoYears = new Date(date);
|
||||
inTwoYears.setFullYear(inTwoYears.getFullYear() + 2);
|
||||
let earliestEOL = new Date(inTwoYears);
|
||||
return `${monthNames[earliestEOL.getMonth()]} ${earliestEOL.getDate()}, ${earliestEOL.getFullYear()}`;
|
||||
}
|
||||
|
||||
$('span.current-timestamp').text(currentTimestamp)
|
||||
$('span.current-time').text(currentTime)
|
||||
$('span.enterprise-eol-date').text(enterpriseEOLDate)
|
||||
$('span.current-date').each(function() {
|
||||
var dayOffset = parseInt($(this).attr("offset"))
|
||||
var trimTime = $(this).attr("trim-time") === "true"
|
||||
$(this).text(currentDate(dayOffset, trimTime))
|
||||
})
|
||||
function initialize() {
|
||||
$('span.current-timestamp').text(currentTimestamp);
|
||||
$('span.current-time').text(currentTime);
|
||||
$('span.enterprise-eol-date').text(enterpriseEOLDate);
|
||||
$('span.current-date').each(function () {
|
||||
var dayOffset = parseInt($(this).attr('offset'));
|
||||
var trimTime = $(this).attr('trim-time') === 'true';
|
||||
$(this).text(currentDate(dayOffset, trimTime));
|
||||
});
|
||||
}
|
||||
|
||||
export { initialize };
|
||||
|
|
|
@ -2,37 +2,24 @@
|
|||
This feature is designed to callout new features added to the documentation
|
||||
CSS is required for the callout bubble to determine look and position, but the
|
||||
element must have the `callout` class and a unique id.
|
||||
Callouts are treated as notifications and use the notification cookie API in
|
||||
assets/js/cookies.js.
|
||||
Callouts are treated as notifications and use the LocalStorage notification API.
|
||||
*/
|
||||
|
||||
import $ from 'jquery';
|
||||
import * as LocalStorageAPI from './local-storage.js';
|
||||
|
||||
// Get notification ID
|
||||
function getCalloutID (el) {
|
||||
function getCalloutID(el) {
|
||||
return $(el).attr('id');
|
||||
}
|
||||
|
||||
// Hide a callout and update the cookie with the viewed callout
|
||||
function hideCallout (calloutID) {
|
||||
if (!window.LocalStorageAPI.notificationIsRead(calloutID)) {
|
||||
window.LocalStorageAPI.setNotificationAsRead(calloutID, 'callout');
|
||||
$(`#${calloutID}`).fadeOut(200);
|
||||
// Show the url feature callouts on page load
|
||||
export default function FeatureCallout({ component }) {
|
||||
const calloutID = getCalloutID($(component));
|
||||
|
||||
if (!LocalStorageAPI.notificationIsRead(calloutID, 'callout')) {
|
||||
$(`#${calloutID}.feature-callout`)
|
||||
.fadeIn(300)
|
||||
.removeClass('start-position');
|
||||
}
|
||||
}
|
||||
|
||||
// Show the url feature callouts on page load
|
||||
$(document).ready(function () {
|
||||
$('.feature-callout').each(function () {
|
||||
const calloutID = getCalloutID($(this));
|
||||
|
||||
if (!window.LocalStorageAPI.notificationIsRead(calloutID, 'callout')) {
|
||||
$(`#${calloutID}.feature-callout`)
|
||||
.fadeIn(300)
|
||||
.removeClass('start-position');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Hide the InfluxDB URL selector callout
|
||||
// $('button.url-trigger, #influxdb-url-selector .close').click(function () {
|
||||
// hideCallout('influxdb-url-selector');
|
||||
// });
|
||||
|
|
|
@ -1,49 +1,148 @@
|
|||
var tablesElement = $("#flux-group-keys-demo #grouped-tables")
|
||||
import $ from 'jquery';
|
||||
|
||||
// Sample data
|
||||
let data = [
|
||||
[
|
||||
{ _time: "2021-01-01T00:00:00Z", _measurement: "example", loc: "rm1", sensorID: "A123", _field: "temp", _value: 110.3 },
|
||||
{ _time: "2021-01-01T00:01:00Z", _measurement: "example", loc: "rm1", sensorID: "A123", _field: "temp", _value: 112.5 },
|
||||
{ _time: "2021-01-01T00:02:00Z", _measurement: "example", loc: "rm1", sensorID: "A123", _field: "temp", _value: 111.9 }
|
||||
{
|
||||
_time: '2021-01-01T00:00:00Z',
|
||||
_measurement: 'example',
|
||||
loc: 'rm1',
|
||||
sensorID: 'A123',
|
||||
_field: 'temp',
|
||||
_value: 110.3,
|
||||
},
|
||||
{
|
||||
_time: '2021-01-01T00:01:00Z',
|
||||
_measurement: 'example',
|
||||
loc: 'rm1',
|
||||
sensorID: 'A123',
|
||||
_field: 'temp',
|
||||
_value: 112.5,
|
||||
},
|
||||
{
|
||||
_time: '2021-01-01T00:02:00Z',
|
||||
_measurement: 'example',
|
||||
loc: 'rm1',
|
||||
sensorID: 'A123',
|
||||
_field: 'temp',
|
||||
_value: 111.9,
|
||||
},
|
||||
],
|
||||
[
|
||||
{ _time: "2021-01-01T00:00:00Z", _measurement: "example", loc: "rm1", sensorID: "A123", _field: "hum", _value: 73.4 },
|
||||
{ _time: "2021-01-01T00:01:00Z", _measurement: "example", loc: "rm1", sensorID: "A123", _field: "hum", _value: 73.7 },
|
||||
{ _time: "2021-01-01T00:02:00Z", _measurement: "example", loc: "rm1", sensorID: "A123", _field: "hum", _value: 75.1 }
|
||||
{
|
||||
_time: '2021-01-01T00:00:00Z',
|
||||
_measurement: 'example',
|
||||
loc: 'rm1',
|
||||
sensorID: 'A123',
|
||||
_field: 'hum',
|
||||
_value: 73.4,
|
||||
},
|
||||
{
|
||||
_time: '2021-01-01T00:01:00Z',
|
||||
_measurement: 'example',
|
||||
loc: 'rm1',
|
||||
sensorID: 'A123',
|
||||
_field: 'hum',
|
||||
_value: 73.7,
|
||||
},
|
||||
{
|
||||
_time: '2021-01-01T00:02:00Z',
|
||||
_measurement: 'example',
|
||||
loc: 'rm1',
|
||||
sensorID: 'A123',
|
||||
_field: 'hum',
|
||||
_value: 75.1,
|
||||
},
|
||||
],
|
||||
[
|
||||
{ _time: "2021-01-01T00:00:00Z", _measurement: "example", loc: "rm2", sensorID: "B456", _field: "temp", _value: 108.2 },
|
||||
{ _time: "2021-01-01T00:01:00Z", _measurement: "example", loc: "rm2", sensorID: "B456", _field: "temp", _value: 108.5 },
|
||||
{ _time: "2021-01-01T00:02:00Z", _measurement: "example", loc: "rm2", sensorID: "B456", _field: "temp", _value: 109.6 }
|
||||
{
|
||||
_time: '2021-01-01T00:00:00Z',
|
||||
_measurement: 'example',
|
||||
loc: 'rm2',
|
||||
sensorID: 'B456',
|
||||
_field: 'temp',
|
||||
_value: 108.2,
|
||||
},
|
||||
{
|
||||
_time: '2021-01-01T00:01:00Z',
|
||||
_measurement: 'example',
|
||||
loc: 'rm2',
|
||||
sensorID: 'B456',
|
||||
_field: 'temp',
|
||||
_value: 108.5,
|
||||
},
|
||||
{
|
||||
_time: '2021-01-01T00:02:00Z',
|
||||
_measurement: 'example',
|
||||
loc: 'rm2',
|
||||
sensorID: 'B456',
|
||||
_field: 'temp',
|
||||
_value: 109.6,
|
||||
},
|
||||
],
|
||||
[
|
||||
{ _time: "2021-01-01T00:00:00Z", _measurement: "example", loc: "rm2", sensorID: "B456", _field: "hum", _value: 71.8 },
|
||||
{ _time: "2021-01-01T00:01:00Z", _measurement: "example", loc: "rm2", sensorID: "B456", _field: "hum", _value: 72.3 },
|
||||
{ _time: "2021-01-01T00:02:00Z", _measurement: "example", loc: "rm2", sensorID: "B456", _field: "hum", _value: 72.1 }
|
||||
]
|
||||
]
|
||||
{
|
||||
_time: '2021-01-01T00:00:00Z',
|
||||
_measurement: 'example',
|
||||
loc: 'rm2',
|
||||
sensorID: 'B456',
|
||||
_field: 'hum',
|
||||
_value: 71.8,
|
||||
},
|
||||
{
|
||||
_time: '2021-01-01T00:01:00Z',
|
||||
_measurement: 'example',
|
||||
loc: 'rm2',
|
||||
sensorID: 'B456',
|
||||
_field: 'hum',
|
||||
_value: 72.3,
|
||||
},
|
||||
{
|
||||
_time: '2021-01-01T00:02:00Z',
|
||||
_measurement: 'example',
|
||||
loc: 'rm2',
|
||||
sensorID: 'B456',
|
||||
_field: 'hum',
|
||||
_value: 72.1,
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
// Default group key
|
||||
let groupKey = ["_measurement", "loc", "sensorID", "_field"]
|
||||
let groupKey = ['_measurement', 'loc', 'sensorID', '_field'];
|
||||
|
||||
export default function FluxGroupKeysDemo({ component }) {
|
||||
$('.column-list label').click(function () {
|
||||
toggleCheckbox($(this));
|
||||
groupKey = getChecked(component);
|
||||
groupData();
|
||||
buildGroupExample(component);
|
||||
});
|
||||
|
||||
// Group and render tables on load
|
||||
groupData();
|
||||
}
|
||||
|
||||
// Build a table group (group key and table) using an array of objects
|
||||
function buildTable(inputData) {
|
||||
|
||||
// Build the group key string
|
||||
function wrapString(column, value) {
|
||||
var stringColumns = ["_measurement", "loc", "sensorID", "_field"]
|
||||
var stringColumns = ['_measurement', 'loc', 'sensorID', '_field'];
|
||||
if (stringColumns.includes(column)) {
|
||||
return '"' + value + '"'
|
||||
return '"' + value + '"';
|
||||
} else {
|
||||
return value
|
||||
return value;
|
||||
}
|
||||
}
|
||||
var groupKeyString = "Group key instance = [" + (groupKey.map(column => column + ": " + wrapString(column, (inputData[0])[column])) ).join(", ") + "]";
|
||||
var groupKeyLabel = document.createElement("p");
|
||||
groupKeyLabel.className = "table-group-key"
|
||||
groupKeyLabel.innerHTML = groupKeyString
|
||||
|
||||
var groupKeyString =
|
||||
'Group key instance = [' +
|
||||
groupKey
|
||||
.map((column) => column + ': ' + wrapString(column, inputData[0][column]))
|
||||
.join(', ') +
|
||||
']';
|
||||
var groupKeyLabel = document.createElement('p');
|
||||
groupKeyLabel.className = 'table-group-key';
|
||||
groupKeyLabel.innerHTML = groupKeyString;
|
||||
|
||||
// Extract column headers
|
||||
var columns = [];
|
||||
|
@ -54,56 +153,57 @@ function buildTable(inputData) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create the table element
|
||||
var table = document.createElement("table");
|
||||
|
||||
const table = document.createElement('table');
|
||||
|
||||
// Create the table header
|
||||
for (let i = 0; i < columns.length; i++) {
|
||||
var header = table.createTHead();
|
||||
var th = document.createElement("th");
|
||||
var th = document.createElement('th');
|
||||
th.innerHTML = columns[i];
|
||||
if (groupKey.includes(columns[i])) {
|
||||
th.className = "grouped-by";
|
||||
th.className = 'grouped-by';
|
||||
}
|
||||
header.appendChild(th);
|
||||
}
|
||||
|
||||
// Add inputData to the HTML table
|
||||
for (let i = 0; i < inputData.length; i++) {
|
||||
tr = table.insertRow(-1);
|
||||
let tr = table.insertRow(-1);
|
||||
for (let j = 0; j < columns.length; j++) {
|
||||
var td = tr.insertCell(-1);
|
||||
td.innerHTML = inputData[i][columns[j]];
|
||||
// Highlight the value if column is part of the group key
|
||||
if (groupKey.includes(columns[j])) {
|
||||
td.className = "grouped-by";
|
||||
td.className = 'grouped-by';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a table group with group key and table
|
||||
var tableGroup = document.createElement("div");
|
||||
tableGroup.innerHTML += groupKeyLabel.outerHTML + table.outerHTML
|
||||
var tableGroup = document.createElement('div');
|
||||
tableGroup.innerHTML += groupKeyLabel.outerHTML + table.outerHTML;
|
||||
|
||||
return tableGroup
|
||||
return tableGroup;
|
||||
}
|
||||
|
||||
// Clear and rebuild all HTML tables
|
||||
function buildTables(data) {
|
||||
existingTables = tablesElement[0]
|
||||
let tablesElement = $('#flux-group-keys-demo #grouped-tables');
|
||||
let existingTables = tablesElement[0];
|
||||
while (existingTables.firstChild) {
|
||||
existingTables.removeChild(existingTables.firstChild);
|
||||
}
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
var table = buildTable(data[i])
|
||||
var table = buildTable(data[i]);
|
||||
tablesElement.append(table);
|
||||
}
|
||||
}
|
||||
|
||||
// Group data based on the group key and output new tables
|
||||
function groupData() {
|
||||
let groupedData = data.flat()
|
||||
let groupedData = data.flat();
|
||||
|
||||
function groupBy(array, f) {
|
||||
var groups = {};
|
||||
|
@ -114,20 +214,19 @@ function groupData() {
|
|||
});
|
||||
return Object.keys(groups).map(function (group) {
|
||||
return groups[group];
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
groupedData = groupBy(groupedData, function (r) {
|
||||
return groupKey.map(v => r[v]);
|
||||
return groupKey.map((v) => r[v]);
|
||||
});
|
||||
|
||||
buildTables(groupedData);
|
||||
}
|
||||
|
||||
// Get selected column names
|
||||
var checkboxes = $("input[type=checkbox]");
|
||||
|
||||
function getChecked() {
|
||||
function getChecked(component) {
|
||||
// Get selected column names
|
||||
var checkboxes = $(component).find('input[type=checkbox]');
|
||||
var checked = [];
|
||||
for (var i = 0; i < checkboxes.length; i++) {
|
||||
var checkbox = checkboxes[i];
|
||||
|
@ -141,17 +240,12 @@ function toggleCheckbox(element) {
|
|||
}
|
||||
|
||||
// Build example group function
|
||||
function buildGroupExample() {
|
||||
var columnCollection = getChecked().map(i => '<span class=\"s2\">"' + i + '"</span>').join(", ")
|
||||
$("pre#group-by-example")[0].innerHTML = "data\n <span class='nx'>|></span> group(columns<span class='nx'>:</span> [" + columnCollection + "])";
|
||||
function buildGroupExample(component) {
|
||||
var columnCollection = getChecked(component)
|
||||
.map((i) => '<span class=\"s2\">"' + i + '"</span>')
|
||||
.join(', ');
|
||||
$('pre#group-by-example')[0].innerHTML =
|
||||
"data\n <span class='nx'>|></span> group(columns<span class='nx'>:</span> [" +
|
||||
columnCollection +
|
||||
'])';
|
||||
}
|
||||
|
||||
$(".column-list label").click(function () {
|
||||
toggleCheckbox($(this))
|
||||
groupKey = getChecked();
|
||||
groupData();
|
||||
buildGroupExample();
|
||||
});
|
||||
|
||||
// Group and render tables on load
|
||||
groupData()
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
$('.exp-btn').click(function() {
|
||||
var targetBtnElement = $(this).parent()
|
||||
$('.exp-btn > p', targetBtnElement).fadeOut(100);
|
||||
setTimeout(function() {
|
||||
$('.exp-btn-links', targetBtnElement).fadeIn(200)
|
||||
$('.exp-btn', targetBtnElement).addClass('open');
|
||||
$('.close-btn', targetBtnElement).fadeIn(200);
|
||||
}, 100);
|
||||
})
|
||||
|
||||
$('.close-btn').click(function() {
|
||||
var targetBtnElement = $(this).parent().parent()
|
||||
$('.exp-btn-links', targetBtnElement).fadeOut(100)
|
||||
$('.exp-btn', targetBtnElement).removeClass('open');
|
||||
$(this).fadeOut(100);
|
||||
setTimeout(function() {
|
||||
$('p', targetBtnElement).fadeIn(100);
|
||||
}, 100);
|
||||
})
|
||||
|
||||
/////////////////////////////// EXPANDING BUTTONS //////////////////////////////
|
||||
|
|
@ -1 +0,0 @@
|
|||
export * from './main.js';
|
|
@ -1,41 +1,58 @@
|
|||
// Dynamically update keybindings or hotkeys
|
||||
function getPlatform() {
|
||||
if (/Mac/.test(navigator.platform)) {
|
||||
return "osx"
|
||||
} else if (/Win/.test(navigator.platform)) {
|
||||
return "win"
|
||||
} else if (/Linux/.test(navigator.platform)) {
|
||||
return "linux"
|
||||
} else {
|
||||
return "other"
|
||||
}
|
||||
import { getPlatform } from './utils/user-agent-platform.js';
|
||||
import $ from 'jquery';
|
||||
|
||||
/**
|
||||
* Adds OS-specific class to component
|
||||
* @param {string} osClass - OS-specific class to add
|
||||
* @param {Object} options - Component options
|
||||
* @param {jQuery} options.$component - jQuery element reference
|
||||
*/
|
||||
function addOSClass(osClass, { $component }) {
|
||||
$component.addClass(osClass);
|
||||
}
|
||||
|
||||
const platform = getPlatform()
|
||||
/**
|
||||
* Updates keybinding display based on detected platform
|
||||
* @param {Object} options - Component options
|
||||
* @param {jQuery} options.$component - jQuery element reference
|
||||
* @param {string} options.platform - Detected platform
|
||||
*/
|
||||
function updateKeyBindings({ $component, platform }) {
|
||||
const osx = $component.data('osx');
|
||||
const linux = $component.data('linux');
|
||||
const win = $component.data('win');
|
||||
|
||||
function addOSClass(osClass) {
|
||||
$('.keybinding').addClass(osClass)
|
||||
}
|
||||
let keybind;
|
||||
|
||||
function updateKeyBindings() {
|
||||
$('.keybinding').each(function() {
|
||||
var osx = $(this).data("osx")
|
||||
var linux = $(this).data("linux")
|
||||
var win = $(this).data("win")
|
||||
|
||||
if (platform === "other") {
|
||||
if (win != linux) {
|
||||
var keybind = '<code class="osx">' + osx + '</code> for macOS, <code>' + linux + '</code> for Linux, and <code>' + win + '</code> for Windows';
|
||||
} else {
|
||||
var keybind = '<code>' + linux + '</code> for Linux and Windows and <code class="osx">' + osx + '</code> for macOS';
|
||||
}
|
||||
if (platform === 'other') {
|
||||
if (win !== linux) {
|
||||
keybind =
|
||||
`<code class="osx">${osx}</code> for macOS, ` +
|
||||
`<code>${linux}</code> for Linux, ` +
|
||||
`and <code>${win}</code> for Windows`;
|
||||
} else {
|
||||
var keybind = '<code>' + $(this).data(platform) + '</code>'
|
||||
keybind =
|
||||
`<code>${linux}</code> for Linux and Windows and ` +
|
||||
`<code class="osx">${osx}</code> for macOS`;
|
||||
}
|
||||
} else {
|
||||
keybind = `<code>${$component.data(platform)}</code>`;
|
||||
}
|
||||
|
||||
$(this).html(keybind)
|
||||
})
|
||||
$component.html(keybind);
|
||||
}
|
||||
|
||||
addOSClass(platform)
|
||||
updateKeyBindings()
|
||||
/**
|
||||
* Initialize and render platform-specific keybindings
|
||||
* @param {Object} options - Component options
|
||||
* @param {HTMLElement} options.component - DOM element
|
||||
* @returns {void}
|
||||
*/
|
||||
export default function KeyBinding({ component }) {
|
||||
// Initialize keybindings
|
||||
const platform = getPlatform();
|
||||
const $component = $(component);
|
||||
|
||||
addOSClass(platform, { $component });
|
||||
updateKeyBindings({ $component, platform });
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ function countTag(tag) {
|
|||
return $(".visible[data-tags*='" + tag + "']").length
|
||||
}
|
||||
|
||||
function getFilterCounts() {
|
||||
$('#list-filters label').each(function() {
|
||||
function getFilterCounts($labels) {
|
||||
$labels.each(function() {
|
||||
var tagName = $('input', this).attr('name').replace(/[\W/]+/, "-");
|
||||
var tagCount = countTag(tagName);
|
||||
$(this).attr('data-count', '(' + tagCount + ')');
|
||||
|
@ -16,35 +16,39 @@ function getFilterCounts() {
|
|||
})
|
||||
}
|
||||
|
||||
// Get initial filter count on page load
|
||||
getFilterCounts()
|
||||
export default function ListFilters({ component }) {
|
||||
const $labels = $(component).find('label');
|
||||
const $inputs = $(component).find('input');
|
||||
|
||||
$("#list-filters input").click(function() {
|
||||
getFilterCounts($labels);
|
||||
|
||||
// List of tags to hide
|
||||
var tagArray = $("#list-filters input:checkbox:checked").map(function(){
|
||||
return $(this).attr('name').replace(/[\W]+/, "-");
|
||||
}).get();
|
||||
$inputs.click(function() {
|
||||
|
||||
// List of tags to restore
|
||||
var restoreArray = $("#list-filters input:checkbox:not(:checked)").map(function(){
|
||||
return $(this).attr('name').replace(/[\W]+/, "-");
|
||||
}).get();
|
||||
// List of tags to hide
|
||||
var tagArray = $(component).find("input:checkbox:checked").map(function(){
|
||||
return $(this).attr('name').replace(/[\W]+/, "-");
|
||||
}).get();
|
||||
|
||||
// Actions for filter select
|
||||
if ( $(this).is(':checked') ) {
|
||||
$.each( tagArray, function( index, value ) {
|
||||
$(".filter-item.visible:not([data-tags~='" + value + "'])").removeClass('visible').fadeOut()
|
||||
})
|
||||
} else {
|
||||
$.each( restoreArray, function( index, value ) {
|
||||
$(".filter-item:not(.visible)[data-tags~='" + value + "']").addClass('visible').fadeIn()
|
||||
})
|
||||
$.each( tagArray, function( index, value ) {
|
||||
$(".filter-item.visible:not([data-tags~='" + value + "'])").removeClass('visible').hide()
|
||||
})
|
||||
}
|
||||
// List of tags to restore
|
||||
var restoreArray = $(component).find("input:checkbox:not(:checked)").map(function(){
|
||||
return $(this).attr('name').replace(/[\W]+/, "-");
|
||||
}).get();
|
||||
|
||||
// Refresh filter count
|
||||
getFilterCounts()
|
||||
});
|
||||
// Actions for filter select
|
||||
if ( $(this).is(':checked') ) {
|
||||
$.each( tagArray, function( index, value ) {
|
||||
$(".filter-item.visible:not([data-tags~='" + value + "'])").removeClass('visible').fadeOut()
|
||||
})
|
||||
} else {
|
||||
$.each( restoreArray, function( index, value ) {
|
||||
$(".filter-item:not(.visible)[data-tags~='" + value + "']").addClass('visible').fadeIn()
|
||||
})
|
||||
$.each( tagArray, function( index, value ) {
|
||||
$(".filter-item.visible:not([data-tags~='" + value + "'])").removeClass('visible').hide()
|
||||
})
|
||||
}
|
||||
|
||||
// Refresh filter count
|
||||
getFilterCounts($labels);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -82,13 +82,16 @@ function getPreferences() {
|
|||
//////////// MANAGE INFLUXDATA DOCS URLS IN LOCAL STORAGE //////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
const defaultUrls = {};
|
||||
// Guard against pageParams being null/undefined and safely access nested properties
|
||||
if (pageParams && pageParams.influxdb_urls) {
|
||||
Object.entries(pageParams.influxdb_urls).forEach(([product, {providers}]) => {
|
||||
defaultUrls[product] = providers.filter(provider => provider.name === 'Default')[0]?.regions[0]?.url;
|
||||
});
|
||||
Object.entries(pageParams.influxdb_urls).forEach(
|
||||
([product, { providers }]) => {
|
||||
defaultUrls[product] =
|
||||
providers.filter((provider) => provider.name === 'Default')[0]
|
||||
?.regions[0]?.url || 'https://cloud2.influxdata.com';
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export const DEFAULT_STORAGE_URLS = {
|
||||
|
@ -177,7 +180,10 @@ const defaultNotificationsObj = {
|
|||
function getNotifications() {
|
||||
// Initialize notifications data if it doesn't already exist
|
||||
if (localStorage.getItem(notificationStorageKey) === null) {
|
||||
initializeStorageItem('notifications', JSON.stringify(defaultNotificationsObj));
|
||||
initializeStorageItem(
|
||||
'notifications',
|
||||
JSON.stringify(defaultNotificationsObj)
|
||||
);
|
||||
}
|
||||
|
||||
// Retrieve and parse the notifications data as JSON
|
||||
|
@ -221,7 +227,10 @@ function setNotificationAsRead(notificationID, notificationType) {
|
|||
readNotifications.push(notificationID);
|
||||
notificationsObj[notificationType + 's'] = readNotifications;
|
||||
|
||||
localStorage.setItem(notificationStorageKey, JSON.stringify(notificationsObj));
|
||||
localStorage.setItem(
|
||||
notificationStorageKey,
|
||||
JSON.stringify(notificationsObj)
|
||||
);
|
||||
}
|
||||
|
||||
// Export functions as a module and make the file backwards compatible for non-module environments until all remaining dependent scripts are ported to modules
|
||||
|
|
|
@ -3,15 +3,19 @@
|
|||
// If you need to pass parameters from the calling Hugo page, you can import them here like so:
|
||||
// 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.
|
||||
* TODO: Refactor these into single-purpose component modules.
|
||||
*/
|
||||
import * as apiLibs from './api-libs.js';
|
||||
import * as codeControls from './code-controls.js';
|
||||
import * as contentInteractions from './content-interactions.js';
|
||||
import * as datetime from './datetime.js';
|
||||
import { delay } from './helpers.js';
|
||||
import { InfluxDBUrl } from './influxdb-url.js';
|
||||
import * as localStorage from './local-storage.js';
|
||||
import * as localStorage from './local-storage.js';
|
||||
import * as modals from './modals.js';
|
||||
import * as notifications from './notifications.js';
|
||||
import * as pageContext from './page-context.js';
|
||||
|
@ -29,8 +33,17 @@ import * as v3Wayfinding from './v3-wayfinding.js';
|
|||
import AskAITrigger from './ask-ai-trigger.js';
|
||||
import CodePlaceholder from './code-placeholders.js';
|
||||
import { CustomTimeTrigger } from './custom-timestamps.js';
|
||||
import Diagram from './components/diagram.js';
|
||||
import DocSearch from './components/doc-search.js';
|
||||
import FeatureCallout from './feature-callouts.js';
|
||||
import FluxGroupKeysDemo from './flux-group-keys.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 ReleaseToc from './release-toc.js';
|
||||
import { SearchButton } from './search-button.js';
|
||||
import SidebarSearch from './components/sidebar-search.js';
|
||||
import { SidebarToggle } from './sidebar-toggle.js';
|
||||
import Theme from './theme.js';
|
||||
import ThemeSwitch from './theme-switch.js';
|
||||
|
@ -49,8 +62,17 @@ const componentRegistry = {
|
|||
'ask-ai-trigger': AskAITrigger,
|
||||
'code-placeholder': CodePlaceholder,
|
||||
'custom-time-trigger': CustomTimeTrigger,
|
||||
'diagram': Diagram,
|
||||
'doc-search': DocSearch,
|
||||
'feature-callout': FeatureCallout,
|
||||
'flux-group-keys-demo': FluxGroupKeysDemo,
|
||||
'flux-influxdb-versions-trigger': FluxInfluxDBVersionsTrigger,
|
||||
'keybinding': KeyBinding,
|
||||
'list-filters': ListFilters,
|
||||
'product-selector': ProductSelector,
|
||||
'release-toc': ReleaseToc,
|
||||
'search-button': SearchButton,
|
||||
'sidebar-search': SidebarSearch,
|
||||
'sidebar-toggle': SidebarToggle,
|
||||
'theme': Theme,
|
||||
'theme-switch': ThemeSwitch
|
||||
|
@ -72,6 +94,11 @@ function initGlobals() {
|
|||
window.influxdatadocs.toggleModal = modals.toggleModal;
|
||||
window.influxdatadocs.componentRegistry = componentRegistry;
|
||||
|
||||
// Re-export jQuery to global namespace for legacy scripts
|
||||
if (typeof window.jQuery === 'undefined') {
|
||||
window.jQuery = window.$ = $;
|
||||
}
|
||||
|
||||
return window.influxdatadocs;
|
||||
}
|
||||
|
||||
|
@ -122,6 +149,7 @@ function initModules() {
|
|||
apiLibs.initialize();
|
||||
codeControls.initialize();
|
||||
contentInteractions.initialize();
|
||||
datetime.initialize();
|
||||
InfluxDBUrl();
|
||||
notifications.initialize();
|
||||
pageFeedback.initialize();
|
||||
|
|
|
@ -1,69 +1,59 @@
|
|||
/////////////////////////// Table of Contents Script ///////////////////////////
|
||||
|
||||
/*
|
||||
* This script is used to generate a table of contents for the
|
||||
* release notes pages.
|
||||
*/
|
||||
* This script is used to generate a table of contents for the
|
||||
* release notes pages.
|
||||
*/
|
||||
export default function ReleaseToc({ component }) {
|
||||
// Use jQuery filter to get an array of all the *release* h2 elements
|
||||
const releases = $('h2').filter(
|
||||
(_i, el) => !el.id.match(/checkpoint-releases/)
|
||||
);
|
||||
|
||||
// Get all h2 elements that are not checkpoint-releases
|
||||
const releases = Array.from(document.querySelectorAll('h2')).filter(
|
||||
el => !el.id.match(/checkpoint-releases/)
|
||||
);
|
||||
// Extract data about each release from the array of releases
|
||||
const releaseData = releases.map((_i, el) => ({
|
||||
name: el.textContent,
|
||||
id: el.id,
|
||||
class: el.getAttribute('class'),
|
||||
date: el.getAttribute('date'),
|
||||
}));
|
||||
|
||||
// Extract data about each release from the array of releases
|
||||
const releaseData = releases.map(el => ({
|
||||
name: el.textContent,
|
||||
id: el.id,
|
||||
class: el.getAttribute('class'),
|
||||
date: el.getAttribute('date')
|
||||
}));
|
||||
// Use release data to generate a list item for each release
|
||||
getReleaseItem = (releaseData) => {
|
||||
var li = document.createElement('li');
|
||||
if (releaseData.class !== null) {
|
||||
li.className = releaseData.class;
|
||||
}
|
||||
li.innerHTML = `<a href="#${releaseData.id}">${releaseData.name}</a>`;
|
||||
li.setAttribute('date', releaseData.date);
|
||||
return li;
|
||||
};
|
||||
|
||||
// Use release data to generate a list item for each release
|
||||
function getReleaseItem(releaseData) {
|
||||
const li = document.createElement("li");
|
||||
if (releaseData.class !== null) {
|
||||
li.className = releaseData.class;
|
||||
}
|
||||
li.innerHTML = `<a href="#${releaseData.id}">${releaseData.name}</a>`;
|
||||
li.setAttribute('date', releaseData.date);
|
||||
return li;
|
||||
}
|
||||
// Use jQuery each to build the release table of contents
|
||||
releaseData.each((_i, release) => {
|
||||
$('#release-toc ul')[0].appendChild(getReleaseItem(release));
|
||||
});
|
||||
|
||||
// Build the release table of contents
|
||||
const releaseTocUl = document.querySelector('#release-toc ul');
|
||||
releaseData.forEach(release => {
|
||||
releaseTocUl.appendChild(getReleaseItem(release));
|
||||
});
|
||||
|
||||
/*
|
||||
* This script is used to expand the release notes table of contents by the
|
||||
* number specified in the `show` attribute of `ul.release-list`.
|
||||
* Once all the release items are visible, the "Show More" button is hidden.
|
||||
*/
|
||||
const showMoreBtn = document.querySelector('#release-toc .show-more');
|
||||
if (showMoreBtn) {
|
||||
showMoreBtn.addEventListener('click', function () {
|
||||
/*
|
||||
* This script is used to expand the release notes table of contents by the
|
||||
* number specified in the `show` attribute of `ul.release-list`.
|
||||
* Once all the release items are visible, the "Show More" button is hidden.
|
||||
*/
|
||||
$('#release-toc .show-more').click(function () {
|
||||
const itemHeight = 1.885; // Item height in rem
|
||||
const releaseNum = releaseData.length;
|
||||
const maxHeight = releaseNum * itemHeight;
|
||||
const releaseList = document.getElementById('release-list');
|
||||
const releaseIncrement = Number(releaseList.getAttribute('show'));
|
||||
const currentHeightMatch = releaseList.style.height.match(/\d+\.?\d+/);
|
||||
const currentHeight = currentHeightMatch
|
||||
? Number(currentHeightMatch[0])
|
||||
: 0;
|
||||
const releaseIncrement = Number($('#release-list')[0].getAttribute('show'));
|
||||
const currentHeight = Number(
|
||||
$('#release-list')[0].style.height.match(/\d+\.?\d+/)[0]
|
||||
);
|
||||
const potentialHeight = currentHeight + releaseIncrement * itemHeight;
|
||||
const newHeight = potentialHeight > maxHeight ? maxHeight : potentialHeight;
|
||||
|
||||
releaseList.style.height = `${newHeight}rem`;
|
||||
$('#release-list')[0].style.height = `${newHeight}rem`;
|
||||
|
||||
if (newHeight >= maxHeight) {
|
||||
// Simple fade out
|
||||
showMoreBtn.style.transition = 'opacity 0.1s';
|
||||
showMoreBtn.style.opacity = 0;
|
||||
setTimeout(() => {
|
||||
showMoreBtn.style.display = 'none';
|
||||
}, 100);
|
||||
$('#release-toc .show-more').fadeOut(100);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
})
|
|
@ -1,20 +1,21 @@
|
|||
import Theme from './theme.js';
|
||||
|
||||
export default function ThemeSwitch({ component }) {
|
||||
if ( component == undefined) {
|
||||
if (component === undefined) {
|
||||
component = document;
|
||||
}
|
||||
component.querySelectorAll(`.theme-switch-light`).forEach((button) => {
|
||||
button.addEventListener('click', function(event) {
|
||||
|
||||
component.querySelectorAll('.theme-switch-light').forEach((button) => {
|
||||
button.addEventListener('click', function (event) {
|
||||
event.preventDefault();
|
||||
Theme({ style: 'light-theme' });
|
||||
Theme({ component, style: 'light-theme' });
|
||||
});
|
||||
});
|
||||
|
||||
component.querySelectorAll(`.theme-switch-dark`).forEach((button) => {
|
||||
button.addEventListener('click', function(event) {
|
||||
component.querySelectorAll('.theme-switch-dark').forEach((button) => {
|
||||
button.addEventListener('click', function (event) {
|
||||
event.preventDefault();
|
||||
Theme({ style: 'dark-theme' });
|
||||
Theme({ component, style: 'dark-theme' });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* Helper functions for debugging without source maps
|
||||
* Example usage:
|
||||
* In your code, you can use these functions like this:
|
||||
* ```javascript
|
||||
* import { debugLog, debugBreak, debugInspect } from './debug-helpers.js';
|
||||
*
|
||||
* const data = debugInspect(someData, 'Data');
|
||||
* debugLog('Processing data', 'myFunction');
|
||||
*
|
||||
* function processData() {
|
||||
* // Add a breakpoint that works with DevTools
|
||||
* debugBreak();
|
||||
*
|
||||
* // Your existing code...
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @fileoverview DEVELOPMENT USE ONLY - Functions should not be committed to production
|
||||
*/
|
||||
|
||||
/* eslint-disable no-debugger */
|
||||
/* eslint-disable-next-line */
|
||||
// NOTE: These functions are detected by ESLint rules to prevent committing debug code
|
||||
|
||||
export function debugLog(message, context = '') {
|
||||
const contextStr = context ? `[${context}]` : '';
|
||||
console.log(`DEBUG${contextStr}: ${message}`);
|
||||
}
|
||||
|
||||
export function debugBreak() {
|
||||
debugger;
|
||||
}
|
||||
|
||||
export function debugInspect(value, label = 'Inspect') {
|
||||
console.log(`DEBUG[${label}]:`, value);
|
||||
return value;
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/**
|
||||
* Manages search interactions for DocSearch integration
|
||||
* Uses MutationObserver to watch for dropdown creation
|
||||
*/
|
||||
export default function SearchInteractions({ searchInput }) {
|
||||
const contentWrapper = document.querySelector('.content-wrapper');
|
||||
let observer = null;
|
||||
let dropdownObserver = null;
|
||||
let dropdownMenu = null;
|
||||
const debug = false; // Set to true for debugging logs
|
||||
|
||||
// Fade content wrapper when focusing on search input
|
||||
function handleFocus() {
|
||||
contentWrapper.style.opacity = '0.35';
|
||||
contentWrapper.style.transition = 'opacity 300ms';
|
||||
}
|
||||
|
||||
// Hide search dropdown when leaving search input
|
||||
function handleBlur(event) {
|
||||
// Only process blur if not clicking within dropdown
|
||||
const relatedTarget = event.relatedTarget;
|
||||
if (
|
||||
relatedTarget &&
|
||||
(relatedTarget.closest('.algolia-autocomplete') ||
|
||||
relatedTarget.closest('.ds-dropdown-menu'))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
contentWrapper.style.opacity = '1';
|
||||
contentWrapper.style.transition = 'opacity 200ms';
|
||||
|
||||
// Hide dropdown if it exists
|
||||
if (dropdownMenu) {
|
||||
dropdownMenu.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// Add event listeners
|
||||
searchInput.addEventListener('focus', handleFocus);
|
||||
searchInput.addEventListener('blur', handleBlur);
|
||||
|
||||
// Use MutationObserver to detect when dropdown is added to the DOM
|
||||
observer = new MutationObserver((mutations) => {
|
||||
for (const mutation of mutations) {
|
||||
if (mutation.type === 'childList') {
|
||||
const newDropdown = document.querySelector(
|
||||
'.ds-dropdown-menu:not([data-monitored])'
|
||||
);
|
||||
if (newDropdown) {
|
||||
// Save reference to dropdown
|
||||
dropdownMenu = newDropdown;
|
||||
newDropdown.setAttribute('data-monitored', 'true');
|
||||
|
||||
// Monitor dropdown removal/display changes
|
||||
dropdownObserver = new MutationObserver((dropdownMutations) => {
|
||||
for (const dropdownMutation of dropdownMutations) {
|
||||
if (debug) {
|
||||
if (
|
||||
dropdownMutation.type === 'attributes' &&
|
||||
dropdownMutation.attributeName === 'style'
|
||||
) {
|
||||
console.log(
|
||||
'Dropdown style changed:',
|
||||
dropdownMenu.style.display
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Observe changes to dropdown attributes (like style)
|
||||
dropdownObserver.observe(dropdownMenu, {
|
||||
attributes: true,
|
||||
attributeFilter: ['style'],
|
||||
});
|
||||
|
||||
// Add event listeners to keep dropdown open when interacted with
|
||||
dropdownMenu.addEventListener('mousedown', (e) => {
|
||||
// Prevent blur on searchInput when clicking in dropdown
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Start observing the document body for dropdown creation
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
|
||||
// Return cleanup function
|
||||
return function cleanup() {
|
||||
searchInput.removeEventListener('focus', handleFocus);
|
||||
searchInput.removeEventListener('blur', handleBlur);
|
||||
|
||||
if (observer) {
|
||||
observer.disconnect();
|
||||
}
|
||||
|
||||
if (dropdownObserver) {
|
||||
dropdownObserver.disconnect();
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Platform detection utility functions
|
||||
* Provides methods for detecting user's operating system
|
||||
*/
|
||||
|
||||
/**
|
||||
* Detects user's operating system using modern techniques
|
||||
* Falls back to userAgent parsing when newer APIs aren't available
|
||||
* @returns {string} Operating system identifier ("osx", "win", "linux", or "other")
|
||||
*/
|
||||
export function getPlatform() {
|
||||
// Try to use modern User-Agent Client Hints API first (Chrome 89+, Edge 89+)
|
||||
if (navigator.userAgentData && navigator.userAgentData.platform) {
|
||||
const platform = navigator.userAgentData.platform.toLowerCase();
|
||||
|
||||
if (platform.includes('mac')) return 'osx';
|
||||
if (platform.includes('win')) return 'win';
|
||||
if (platform.includes('linux')) return 'linux';
|
||||
}
|
||||
|
||||
// Fall back to userAgent string parsing
|
||||
const userAgent = navigator.userAgent.toLowerCase();
|
||||
|
||||
if (userAgent.includes('mac') || userAgent.includes('iphone') || userAgent.includes('ipad')) return 'osx';
|
||||
if (userAgent.includes('win')) return 'win';
|
||||
if (userAgent.includes('linux') || userAgent.includes('android')) return 'linux';
|
||||
|
||||
return 'other';
|
||||
}
|
|
@ -1,19 +1,21 @@
|
|||
// Select the product dropdown and dropdown items
|
||||
const productDropdown = document.querySelector("#product-dropdown");
|
||||
const dropdownItems = document.querySelector("#dropdown-items");
|
||||
export default function ProductSelector({ component }) {
|
||||
// Select the product dropdown and dropdown items
|
||||
const productDropdown = component.querySelector("#product-dropdown");
|
||||
const dropdownItems = component.querySelector("#dropdown-items");
|
||||
|
||||
// Expand the menu on click
|
||||
if (productDropdown) {
|
||||
productDropdown.addEventListener("click", function() {
|
||||
productDropdown.classList.toggle("open");
|
||||
dropdownItems.classList.toggle("open");
|
||||
// Expand the menu on click
|
||||
if (productDropdown) {
|
||||
productDropdown.addEventListener("click", function() {
|
||||
productDropdown.classList.toggle("open");
|
||||
dropdownItems.classList.toggle("open");
|
||||
});
|
||||
}
|
||||
|
||||
// Close the dropdown by clicking anywhere else
|
||||
document.addEventListener("click", function(e) {
|
||||
// Check if the click was outside of the '.product-list' container
|
||||
if (!e.target.closest('.product-list')) {
|
||||
dropdownItems.classList.remove("open");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Close the dropdown by clicking anywhere else
|
||||
document.addEventListener("click", function(e) {
|
||||
// Check if the click was outside of the '.product-list' container
|
||||
if (!e.target.closest('.product-list')) {
|
||||
dropdownItems.classList.remove("open");
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Datetime Components
|
||||
----------------------------------------------
|
||||
*/
|
||||
|
||||
.current-timestamp,
|
||||
.current-date,
|
||||
.current-time,
|
||||
.enterprise-eol-date {
|
||||
color: $current-timestamp-color;
|
||||
display: inline-block;
|
||||
font-family: $proxima;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
|
@ -16,6 +16,10 @@
|
|||
background: $article-code-bg !important;
|
||||
font-size: .85em;
|
||||
font-weight: $medium;
|
||||
|
||||
p {
|
||||
background: $article-bg !important;
|
||||
}
|
||||
}
|
||||
|
||||
.node {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"layouts/syntax-highlighting",
|
||||
"layouts/algolia-search-overrides",
|
||||
"layouts/landing",
|
||||
"layouts/datetime",
|
||||
"layouts/error-page",
|
||||
"layouts/footer-widgets",
|
||||
"layouts/modals",
|
||||
|
|
|
@ -203,6 +203,12 @@ $article-btn-text-hover: $g20-white;
|
|||
$article-nav-icon-bg: $g5-pepper;
|
||||
$article-nav-acct-bg: $g3-castle;
|
||||
|
||||
// Datetime shortcode colors
|
||||
$current-timestamp-color: $g15-platinum;
|
||||
$current-date-color: $g15-platinum;
|
||||
$current-time-color: $g15-platinum;
|
||||
$enterprise-eol-date-color: $g15-platinum;
|
||||
|
||||
// Error Page Colors
|
||||
$error-page-btn: $b-pool;
|
||||
$error-page-btn-text: $g20-white;
|
||||
|
|
|
@ -203,6 +203,12 @@ $article-btn-text-hover: $g20-white !default;
|
|||
$article-nav-icon-bg: $g6-smoke !default;
|
||||
$article-nav-acct-bg: $g5-pepper !default;
|
||||
|
||||
// Datetime Colors
|
||||
$current-timestamp-color: $article-text !default;
|
||||
$current-date-color: $article-text !default;
|
||||
$current-time-color: $article-text !default;
|
||||
$enterprise-eol-date-color: $article-text !default;
|
||||
|
||||
// Error Page Colors
|
||||
$error-page-btn: $b-pool !default;
|
||||
$error-page-btn-text: $g20-white !default;
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
# Production overrides for CI/CD builds
|
||||
baseURL: 'https://docs.influxdata.com/'
|
||||
|
||||
# Production environment parameters
|
||||
params:
|
||||
env: production
|
||||
environment: production
|
||||
|
||||
# Enable minification for production
|
||||
minify:
|
||||
disableJS: false
|
||||
disableCSS: false
|
||||
disableHTML: false
|
||||
minifyOutput: true
|
||||
|
||||
# Production asset processing
|
||||
build:
|
||||
writeStats: false
|
||||
useResourceCacheWhen: "fallback"
|
||||
buildOptions:
|
||||
sourcemap: false
|
||||
target: "es2015"
|
||||
|
||||
# Asset processing configuration
|
||||
assetDir: "assets"
|
||||
|
||||
# Mount assets for production
|
||||
module:
|
||||
mounts:
|
||||
- source: assets
|
||||
target: assets
|
||||
- source: node_modules
|
||||
target: assets/node_modules
|
||||
|
||||
# Disable development server settings
|
||||
server: {}
|
||||
|
||||
# Suppress the warning mentioned in the error
|
||||
ignoreLogs:
|
||||
- 'warning-goldmark-raw-html'
|
|
@ -1,20 +1,106 @@
|
|||
baseURL: 'http://localhost:1315/'
|
||||
languageCode: en-us
|
||||
title: InfluxDB Documentation
|
||||
|
||||
server:
|
||||
port: 1315
|
||||
# Git history information for lastMod-type functionality
|
||||
enableGitInfo: true
|
||||
|
||||
# Syntax Highlighting
|
||||
pygmentsCodefences: true
|
||||
pygmentsUseClasses: true
|
||||
|
||||
# Preserve case in article tags
|
||||
preserveTaxonomyNames: true
|
||||
|
||||
# Generate a robots.txt
|
||||
enableRobotsTXT: true
|
||||
|
||||
|
||||
# Markdown rendering options
|
||||
blackfriday:
|
||||
hrefTargetBlank: true
|
||||
smartDashes: false
|
||||
|
||||
# Copy taxonomies from main config
|
||||
taxonomies:
|
||||
influxdb/v2/tag: influxdb/v2/tags
|
||||
influxdb/cloud/tag: influxdb/cloud/tags
|
||||
influxdb3/cloud-serverless/tag: influxdb/cloud-serverless/tags
|
||||
influxdb3/cloud-dedicated/tag: influxdb/cloud-dedicated/tags
|
||||
influxdb3/clustered/tag: influxdb3/clustered/tags
|
||||
influxdb3/core/tag: influxdb3/core/tags
|
||||
influxdb3/enterprise/tag: influxdb3/enterprise/tags
|
||||
flux/v0/tag: flux/v0/tags
|
||||
|
||||
markup:
|
||||
goldmark:
|
||||
renderer:
|
||||
unsafe: true
|
||||
extensions:
|
||||
linkify: false
|
||||
parser:
|
||||
attribute:
|
||||
block: true
|
||||
|
||||
privacy:
|
||||
googleAnalytics:
|
||||
anonymizeIP: false
|
||||
disable: false
|
||||
respectDoNotTrack: true
|
||||
useSessionStorage: false
|
||||
youtube:
|
||||
disable: false
|
||||
privacyEnhanced: true
|
||||
|
||||
outputFormats:
|
||||
json:
|
||||
mediaType: application/json
|
||||
baseName: pages
|
||||
isPlainText: true
|
||||
|
||||
# Asset processing for testing (disable minification)
|
||||
build:
|
||||
writeStats: false
|
||||
useResourceCacheWhen: "fallback"
|
||||
noJSConfigInAssets: false
|
||||
|
||||
# Asset processing configuration
|
||||
assetDir: "assets"
|
||||
|
||||
module:
|
||||
mounts:
|
||||
- source: assets
|
||||
target: assets
|
||||
- source: node_modules
|
||||
target: assets/node_modules
|
||||
|
||||
# Override settings for testing
|
||||
buildFuture: true
|
||||
|
||||
# Configure what content is built in testing env
|
||||
params:
|
||||
env: testing
|
||||
environment: testing
|
||||
buildTestContent: true
|
||||
|
||||
|
||||
# Configure the server for testing
|
||||
server:
|
||||
port: 1315
|
||||
baseURL: 'http://localhost:1315/'
|
||||
watchChanges: true
|
||||
disableLiveReload: false
|
||||
|
||||
# Keep your shared content exclusions
|
||||
ignoreFiles:
|
||||
- "content/shared/.*"
|
||||
|
||||
# Ignore specific warning logs
|
||||
ignoreLogs:
|
||||
- warning-goldmark-raw-html
|
||||
- warning-goldmark-raw-html
|
||||
|
||||
# Disable minification for testing
|
||||
minify:
|
||||
disableJS: true
|
||||
disableCSS: true
|
||||
disableHTML: true
|
||||
minifyOutput: false
|
||||
|
|
|
@ -1267,3 +1267,106 @@ This is small tab 2.4 content.
|
|||
{{% /tab-content %}}
|
||||
|
||||
{{< /tabs-wrapper >}}
|
||||
|
||||
## Group key demo
|
||||
|
||||
Used to demonstrate Flux group keys
|
||||
|
||||
{{< tabs-wrapper >}}
|
||||
{{% tabs "small" %}}
|
||||
[Input](#)
|
||||
[Output](#)
|
||||
<span class="tab-view-output">Click to view output</span>
|
||||
{{% /tabs %}}
|
||||
{{% tab-content %}}
|
||||
|
||||
The following data is output from the last `filter()` and piped forward into `group()`:
|
||||
|
||||
> [!Note]
|
||||
> `_start` and `_stop` columns have been omitted.
|
||||
|
||||
{{% flux/group-key "[_measurement=home, room=Kitchen, _field=hum]" true %}}
|
||||
|
||||
| _time | _measurement | room | _field | _value |
|
||||
| :------------------- | :----------- | :---------- | :----- | :----- |
|
||||
| 2022-01-01T08:00:00Z | home | Kitchen | hum | 35.9 |
|
||||
| 2022-01-01T09:00:00Z | home | Kitchen | hum | 36.2 |
|
||||
| 2022-01-01T10:00:00Z | home | Kitchen | hum | 36.1 |
|
||||
|
||||
{{% flux/group-key "[_measurement=home, room=Living Room, _field=hum]" true %}}
|
||||
|
||||
| _time | _measurement | room | _field | _value |
|
||||
| :------------------- | :----------- | :---------- | :----- | :----- |
|
||||
| 2022-01-01T08:00:00Z | home | Living Room | hum | 35.9 |
|
||||
| 2022-01-01T09:00:00Z | home | Living Room | hum | 35.9 |
|
||||
| 2022-01-01T10:00:00Z | home | Living Room | hum | 36 |
|
||||
|
||||
{{% flux/group-key "[_measurement=home, room=Kitchen, _field=temp]" true %}}
|
||||
|
||||
| _time | _measurement | room | _field | _value |
|
||||
| :------------------- | :----------- | :---------- | :----- | :----- |
|
||||
| 2022-01-01T08:00:00Z | home | Kitchen | temp | 21 |
|
||||
| 2022-01-01T09:00:00Z | home | Kitchen | temp | 23 |
|
||||
| 2022-01-01T10:00:00Z | home | Kitchen | temp | 22.7 |
|
||||
|
||||
{{% flux/group-key "[_measurement=home, room=Living Room, _field=temp]" true %}}
|
||||
|
||||
| _time | _measurement | room | _field | _value |
|
||||
| :------------------- | :----------- | :---------- | :----- | :----- |
|
||||
| 2022-01-01T08:00:00Z | home | Living Room | temp | 21.1 |
|
||||
| 2022-01-01T09:00:00Z | home | Living Room | temp | 21.4 |
|
||||
| 2022-01-01T10:00:00Z | home | Living Room | temp | 21.8 |
|
||||
|
||||
{{% /tab-content %}}
|
||||
{{% tab-content %}}
|
||||
|
||||
When grouped by `_field`, all rows with the `temp` field will be in one table
|
||||
and all the rows with the `hum` field will be in another.
|
||||
`_measurement` and `room` columns no longer affect how rows are grouped.
|
||||
|
||||
{{% note %}}
|
||||
`_start` and `_stop` columns have been omitted.
|
||||
{{% /note %}}
|
||||
|
||||
{{% flux/group-key "[_field=hum]" true %}}
|
||||
|
||||
| _time | _measurement | room | _field | _value |
|
||||
| :------------------- | :----------- | :---------- | :----- | :----- |
|
||||
| 2022-01-01T08:00:00Z | home | Kitchen | hum | 35.9 |
|
||||
| 2022-01-01T09:00:00Z | home | Kitchen | hum | 36.2 |
|
||||
| 2022-01-01T10:00:00Z | home | Kitchen | hum | 36.1 |
|
||||
| 2022-01-01T08:00:00Z | home | Living Room | hum | 35.9 |
|
||||
| 2022-01-01T09:00:00Z | home | Living Room | hum | 35.9 |
|
||||
| 2022-01-01T10:00:00Z | home | Living Room | hum | 36 |
|
||||
|
||||
{{% flux/group-key "[_field=temp]" true %}}
|
||||
|
||||
| _time | _measurement | room | _field | _value |
|
||||
| :------------------- | :----------- | :---------- | :----- | :----- |
|
||||
| 2022-01-01T08:00:00Z | home | Kitchen | temp | 21 |
|
||||
| 2022-01-01T09:00:00Z | home | Kitchen | temp | 23 |
|
||||
| 2022-01-01T10:00:00Z | home | Kitchen | temp | 22.7 |
|
||||
| 2022-01-01T08:00:00Z | home | Living Room | temp | 21.1 |
|
||||
| 2022-01-01T09:00:00Z | home | Living Room | temp | 21.4 |
|
||||
| 2022-01-01T10:00:00Z | home | Living Room | temp | 21.8 |
|
||||
|
||||
{{% /tab-content %}}
|
||||
{{< /tabs-wrapper >}}
|
||||
|
||||
## datetime/current-timestamp shortcode
|
||||
|
||||
### Default usage
|
||||
|
||||
{{< datetime/current-timestamp >}}
|
||||
|
||||
### Format YYYY-MM-DD HH:mm:ss
|
||||
|
||||
{{< datetime/current-timestamp format="YYYY-MM-DD HH:mm:ss" >}}
|
||||
|
||||
### Format with UTC timezone
|
||||
|
||||
{{< datetime/current-timestamp format="YYYY-MM-DD HH:mm:ss" timezone="UTC" >}}
|
||||
|
||||
### Format with America/New_York timezone
|
||||
|
||||
{{< datetime/current-timestamp format="YYYY-MM-DD HH:mm:ss" timezone="America/New_York" >}}
|
||||
|
|
|
@ -66,6 +66,23 @@ cloud:
|
|||
- name: East US (Virginia)
|
||||
location: Virginia, USA
|
||||
url: https://eastus-1.azure.cloud2.influxdata.com
|
||||
|
||||
serverless:
|
||||
product: InfluxDB Cloud
|
||||
providers:
|
||||
- name: Amazon Web Services
|
||||
short_name: AWS
|
||||
iox: true
|
||||
regions:
|
||||
- name: US East (Virginia)
|
||||
location: Virginia, USA
|
||||
url: https://us-east-1-1.aws.cloud2.influxdata.com
|
||||
iox: true
|
||||
- name: EU Frankfurt
|
||||
location: Frankfurt, Germany
|
||||
url: https://eu-central-1-1.aws.cloud2.influxdata.com
|
||||
iox: true
|
||||
|
||||
cloud_dedicated:
|
||||
providers:
|
||||
- name: Default
|
||||
|
|
|
@ -106,6 +106,33 @@ export default [
|
|||
files: ['assets/js/**/*.js'],
|
||||
rules: {
|
||||
// Rules specific to JavaScript in Hugo assets
|
||||
// Prevent imports from debug-helpers.js
|
||||
'no-restricted-imports': [
|
||||
'error',
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
name: './utils/debug-helpers.js',
|
||||
message:
|
||||
'Remove debugging functions before committing. Debug helpers should not be used in production code.',
|
||||
},
|
||||
{
|
||||
name: '/utils/debug-helpers.js',
|
||||
message:
|
||||
'Remove debugging functions before committing. Debug helpers should not be used in production code.',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
// Prevent use of debug functions in production code
|
||||
'no-restricted-syntax': [
|
||||
'error',
|
||||
{
|
||||
selector: 'CallExpression[callee.name=/^debug(Log|Break|Inspect)$/]',
|
||||
message:
|
||||
'Remove debugging functions before committing. Debug helpers should not be used in production code.',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -17,7 +17,26 @@ enableRobotsTXT: true
|
|||
|
||||
# Custom staging params
|
||||
params:
|
||||
env: staging
|
||||
environment: staging
|
||||
server:
|
||||
disableLiveReload: true
|
||||
|
||||
# Staging uses the same asset processing as production
|
||||
# Enable minification for staging
|
||||
minify:
|
||||
disableJS: false
|
||||
disableCSS: false
|
||||
disableHTML: false
|
||||
minifyOutput: true
|
||||
|
||||
# Staging asset processing
|
||||
build:
|
||||
writeStats: false
|
||||
useResourceCacheWhen: "always"
|
||||
buildOptions:
|
||||
sourcemap: false
|
||||
target: "es2015"
|
||||
|
||||
# Markdown rendering options
|
||||
blackfriday:
|
||||
|
|
37
hugo.yml
37
hugo.yml
|
@ -49,21 +49,48 @@ privacy:
|
|||
youtube:
|
||||
disable: false
|
||||
privacyEnhanced: true
|
||||
|
||||
outputFormats:
|
||||
json:
|
||||
mediaType: application/json
|
||||
baseName: pages
|
||||
isPlainText: true
|
||||
|
||||
# Asset processing configuration for development
|
||||
build:
|
||||
# Ensure Hugo correctly processes JavaScript modules
|
||||
jsConfig:
|
||||
nodeEnv: "development"
|
||||
writeStats: false
|
||||
useResourceCacheWhen: "fallback"
|
||||
noJSConfigInAssets: false
|
||||
|
||||
# Asset processing configuration
|
||||
assetDir: "assets"
|
||||
|
||||
module:
|
||||
mounts:
|
||||
- source: assets
|
||||
target: assets
|
||||
|
||||
- source: node_modules
|
||||
target: assets/node_modules
|
||||
target: assets/node_modules
|
||||
|
||||
# Development settings
|
||||
params:
|
||||
env: development
|
||||
environment: development
|
||||
|
||||
# Configure the server for development
|
||||
server:
|
||||
port: 1313
|
||||
baseURL: 'http://localhost:1313/'
|
||||
watchChanges: true
|
||||
disableLiveReload: false
|
||||
|
||||
# Ignore specific warning logs
|
||||
ignoreLogs:
|
||||
- warning-goldmark-raw-html
|
||||
|
||||
# Disable minification for development
|
||||
minify:
|
||||
disableJS: true
|
||||
disableCSS: true
|
||||
disableHTML: true
|
||||
minifyOutput: false
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -19,7 +19,7 @@
|
|||
<div class="home-content">
|
||||
|
||||
<div class="section search">
|
||||
<div class="sidebar--search">
|
||||
<div class="sidebar--search" data-component="sidebar-search">
|
||||
<input class="sidebar--search-field"
|
||||
id="algolia-search-input"
|
||||
type="text"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
{{ $urlCalloutText := $scratch.Get "urlCalloutText" }}
|
||||
|
||||
<!-- {{ 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>
|
||||
</div>
|
||||
{{ end }} -->
|
||||
|
|
|
@ -1,18 +1,3 @@
|
|||
{{ $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" }}
|
||||
{{ $dateTime := resources.Get "js/datetime.js" }}
|
||||
{{ $homepageInteractions := resources.Get "js/home-interactions.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 }}
|
||||
{{ $dateTimejs := $dateTime | resources.Fingerprint }}
|
||||
{{ $releaseTOCjs := $releaseTOC | resources.Fingerprint }}
|
||||
|
||||
<!-- Load cloudUrls array -->
|
||||
<script type="text/javascript">
|
||||
cloudUrls = [
|
||||
|
@ -21,37 +6,3 @@
|
|||
{{ end -}}
|
||||
]
|
||||
</script>
|
||||
|
||||
{{ if .Page.HasShortcode "diagram" }}
|
||||
<!-- Load mermaid.js for diagrams -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
startOnLoad: true,
|
||||
|
||||
themeVariables: {
|
||||
fontFamily: "Proxima Nova",
|
||||
fontSize: '18px',
|
||||
}
|
||||
})
|
||||
</script>
|
||||
{{ end }}
|
||||
|
||||
<!-- Load group key demo JS if when the group key demo shortcode is present -->
|
||||
{{ if .Page.HasShortcode "flux/group-key-demo" }}
|
||||
<script type="text/javascript" src="{{ $fluxGroupKeyjs.RelPermalink }}"></script>
|
||||
{{ end }}
|
||||
|
||||
<!-- Load datetime js if when datetime shortcodes are present -->
|
||||
{{ if or (.Page.HasShortcode "datetime/current-time") (.Page.HasShortcode "datetime/current-timestamp")
|
||||
(.Page.HasShortcode "datetime/current-date") (.Page.HasShortcode "datetime/enterprise-eol-date") }}
|
||||
<script type="text/javascript" src="{{ $dateTimejs.RelPermalink }}"></script>
|
||||
{{ end }}
|
||||
|
||||
<!-- Load code release-toc js when release-toc shortcode is present -->
|
||||
{{ if .Page.HasShortcode "release-toc" }}
|
||||
<script type="text/javascript" src="{{ $releaseTOCjs.RelPermalink }}"></script>
|
||||
{{ end }}
|
||||
|
||||
<!-- Load footer.js -->
|
||||
<script type="text/javascript" src="{{ $footerjs.RelPermalink }}"></script>
|
|
@ -7,84 +7,15 @@
|
|||
{{ $includeFlux := and (in $fluxSupported $product) (in $influxdbFluxSupport $version) }}
|
||||
{{ $includeResources := not (in (slice "cloud-serverless" "cloud-dedicated" "clustered" "core" "enterprise" "explorer") $version) }}
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script>
|
||||
<script>
|
||||
var multiVersion = ['influxdb']
|
||||
docsearch({
|
||||
apiKey: '501434b53a46a92a7931aecc7c9672e2',
|
||||
appId: 'WHM9UWMP6M',
|
||||
indexName: 'influxdata',
|
||||
inputSelector: '#algolia-search-input',
|
||||
// Set debug to true if you want to inspect the dropdown
|
||||
debug: true,
|
||||
transformData: function (hits) {
|
||||
function fmtVersion (version, productKey) {
|
||||
if (version == null) {
|
||||
return '';
|
||||
} else if (version === 'cloud') {
|
||||
return 'Cloud (TSM)';
|
||||
} else if (version === 'core') {
|
||||
return 'Core';
|
||||
} else if (version === 'enterprise') {
|
||||
return 'Enterprise';
|
||||
} else if (version === 'explorer') {
|
||||
return 'Explorer';
|
||||
} else if (version === 'cloud-serverless') {
|
||||
return 'Cloud Serverless';
|
||||
} else if (version === 'cloud-dedicated') {
|
||||
return 'Cloud Dedicated';
|
||||
} else if (version === 'clustered') {
|
||||
return 'Clustered';
|
||||
} else if (multiVersion.includes(productKey)) {
|
||||
return version;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
productNames = {
|
||||
influxdb: 'InfluxDB',
|
||||
influxdb3: 'InfluxDB 3',
|
||||
enterprise_influxdb: 'InfluxDB Enterprise',
|
||||
flux: 'Flux',
|
||||
telegraf: 'Telegraf',
|
||||
chronograf: 'Chronograf',
|
||||
kapacitor: 'Kapacitor',
|
||||
platform: 'InfluxData Platform',
|
||||
resources: 'Additional Resources',
|
||||
};
|
||||
hits.map(hit => {
|
||||
pathData = new URL(hit.url).pathname.split('/').filter(n => n);
|
||||
product = productNames[pathData[0]];
|
||||
version = fmtVersion(pathData[1], pathData[0]);
|
||||
|
||||
hit.product = product;
|
||||
hit.version = version;
|
||||
hit.hierarchy.lvl0 =
|
||||
hit.hierarchy.lvl0 +
|
||||
` <span class=\"search-product-version\">${product} ${version}</span>`;
|
||||
hit._highlightResult.hierarchy.lvl0.value =
|
||||
hit._highlightResult.hierarchy.lvl0.value +
|
||||
` <span class=\"search-product-version\">${product} ${version}</span>`;
|
||||
});
|
||||
return hits;
|
||||
},
|
||||
algoliaOptions: {
|
||||
hitsPerPage: 10,
|
||||
'facetFilters': [
|
||||
{{ if or (eq $product "platform") (eq $product "resources") (le (len $productPathData) 1) }}
|
||||
'latest:true'
|
||||
{{ else if $includeFlux }}
|
||||
['searchTag: {{ $product }}-{{ $version }}', 'flux:true', 'resources:{{ $includeResources }}']
|
||||
{{ else }}
|
||||
['searchTag: {{ $product }}-{{ $version }}', 'resources:{{ $includeResources }}']
|
||||
{{ end }}
|
||||
]
|
||||
},
|
||||
autocompleteOptions: {
|
||||
templates: {
|
||||
header: '<div class="search-all-content"><a href="https:\/\/support.influxdata.com" target="_blank">Search all InfluxData content <span class="icon-arrow-up-right"></span></a>',
|
||||
empty: '<div class="search-no-results"><p>Not finding what you\'re looking for?</p> <a href="https:\/\/support.influxdata.com" target="_blank">Search all InfluxData content <span class="icon-arrow-up-right"></span></a></div>'
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<!-- DocSearch Component Container -->
|
||||
<div
|
||||
data-component="doc-search"
|
||||
data-api-key="501434b53a46a92a7931aecc7c9672e2"
|
||||
data-app-id="WHM9UWMP6M"
|
||||
data-index-name="influxdata"
|
||||
data-input-selector="#algolia-search-input"
|
||||
data-search-tag="{{ $product }}-{{ $version }}"
|
||||
data-include-flux="{{ $includeFlux }}"
|
||||
data-include-resources="{{ $includeResources }}"
|
||||
data-debug="{{ if hugo.IsProduction }}false{{ else }}true{{ end }}"
|
||||
></div>
|
||||
|
|
|
@ -5,28 +5,104 @@
|
|||
<!-- Get site data -->
|
||||
<!-- Load cloudUrls array -->
|
||||
{{ $cloudUrls := slice }}
|
||||
{{- range.Site.Data.influxdb_urls.cloud.providers }}
|
||||
{{- range.regions }}
|
||||
{{ $cloudUrls = $cloudUrls | append "{{ safeHTML .url }}" }}
|
||||
{{- range .Site.Data.influxdb_urls.cloud.providers }}
|
||||
{{- range .regions }}
|
||||
{{ $cloudUrls = $cloudUrls | append (safeHTML .url) }}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ $products := .Site.Data.products }}
|
||||
{{ $influxdb_urls := .Site.Data.influxdb_urls }}
|
||||
<!-- Build main.js -->
|
||||
{{ with resources.Get "js/index.js" }}
|
||||
{{ $opts := dict
|
||||
"minify" hugo.IsProduction
|
||||
"sourceMap" (cond hugo.IsProduction "" "external")
|
||||
"targetPath" "js/main.js"
|
||||
"params" (dict "product" $product "currentVersion" $currentVersion "isServer" hugo.IsServer "products" $products "influxdb_urls" $influxdb_urls "cloudUrls" $cloudUrls)
|
||||
}}
|
||||
{{ with . | js.Build $opts }}
|
||||
{{ if hugo.IsProduction }}
|
||||
{{ with . | fingerprint }}
|
||||
<script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<script src="{{ .RelPermalink }}"></script>
|
||||
|
||||
{{ $isDevelopmentOrTesting := or (eq .Site.Params.environment "development") (eq .Site.Params.environment "testing") (eq (getenv "HUGO_ENV") "development") (eq (getenv "HUGO_ENV") "testing") (not hugo.IsProduction) }}
|
||||
|
||||
{{ if $isDevelopmentOrTesting }}
|
||||
{{/* Load individual JS files for debugging with ESM format */}}
|
||||
{{ $sharedParams := dict "product" $product "currentVersion" $currentVersion "isServer" hugo.IsServer "products" $products "influxdb_urls" $influxdb_urls "cloudUrls" $cloudUrls }}
|
||||
|
||||
{{/* Load main.js first to ensure proper initialization */}}
|
||||
{{ $mainJS := resources.Get "js/main.js" }}
|
||||
{{ if $mainJS }}
|
||||
{{ $opts := dict
|
||||
"sourceMap" "external"
|
||||
"sourcesContent" true
|
||||
"targetPath" "js/main.js"
|
||||
"format" "esm"
|
||||
"bundle" false
|
||||
"minify" false
|
||||
"target" "es2017"
|
||||
"write" true
|
||||
"params" $sharedParams
|
||||
}}
|
||||
{{ $processed := $mainJS | js.Build $opts }}
|
||||
{{ if $processed }}
|
||||
<script type="module" src="{{ $processed.RelPermalink }}"></script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{/* Load other individual JS files for debugging with error handling */}}
|
||||
{{ $jsDir := "assets/js" }}
|
||||
{{ if fileExists $jsDir }}
|
||||
{{ range $file := (readDir $jsDir) }}
|
||||
{{ if and (strings.HasSuffix $file.Name ".js") (ne $file.Name "main.js") }}
|
||||
{{ $jsPath := printf "js/%s" $file.Name }}
|
||||
{{ $jsRes := resources.Get $jsPath }}
|
||||
{{ with $jsRes }}
|
||||
{{ $opts := dict
|
||||
"sourceMap" ""
|
||||
"targetPath" $jsPath
|
||||
"format" "esm"
|
||||
"bundle" false
|
||||
"minify" false
|
||||
"target" "es2015"
|
||||
"write" true
|
||||
"params" $sharedParams
|
||||
}}
|
||||
{{ $out := . | js.Build $opts }}
|
||||
|
||||
{{/* Add descriptive debug comments at the beginning of each file */}}
|
||||
{{ $debugHeader := printf "// DEBUG MODE: %s\n// Original file: assets/js/%s\n\n" $file.Name $file.Name }}
|
||||
{{ $modifiedContent := printf "%s%s" $debugHeader $out.Content }}
|
||||
{{ $out = resources.FromString $jsPath $modifiedContent }}
|
||||
|
||||
<script type="module" src="{{ $out.RelPermalink }}"></script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
{{/* Production environment: Use IIFE for better compatibility */}}
|
||||
{{ $mainJS := resources.Get "js/main.js" }}
|
||||
{{ if $mainJS }}
|
||||
{{ $sharedParams := dict "product" $product "currentVersion" $currentVersion "isServer" hugo.IsServer "products" $products "influxdb_urls" $influxdb_urls "cloudUrls" $cloudUrls }}
|
||||
|
||||
{{ $opts := dict
|
||||
"minify" hugo.IsProduction
|
||||
"sourceMap" ""
|
||||
"targetPath" "js/main.js"
|
||||
"params" $sharedParams
|
||||
"format" "iife"
|
||||
"target" "es2019"
|
||||
"splitting" false
|
||||
"external" (slice "*")
|
||||
"define" (dict
|
||||
"process.env.NODE_ENV" "\"production\""
|
||||
)
|
||||
}}
|
||||
|
||||
{{ $processed := "" }}
|
||||
{{ with $mainJS }}
|
||||
{{ $processed = . | js.Build $opts }}
|
||||
{{ end }}
|
||||
|
||||
{{ if $processed }}
|
||||
{{ if hugo.IsProduction }}
|
||||
{{ $fingerprinted := $processed | fingerprint }}
|
||||
{{ if $fingerprinted }}
|
||||
<script defer src="{{ $fingerprinted.RelPermalink }}" integrity="{{ $fingerprinted.Data.Integrity }}" crossorigin="anonymous"></script>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<script defer src="{{ $processed.RelPermalink }}"></script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
|
@ -49,7 +49,7 @@
|
|||
<aside class="sidebar">
|
||||
{{ partial "sidebar/sidebar-toggle.html" (dict "state" "Close") }}
|
||||
<div class="search-and-nav-toggle">
|
||||
<div class="sidebar--search">
|
||||
<div class="sidebar--search" data-component="sidebar-search">
|
||||
<input class="sidebar--search-field"
|
||||
id="algolia-search-input"
|
||||
type="text"
|
||||
|
|
|
@ -43,7 +43,7 @@ Identify products by their product path. Dictionary schema:
|
|||
|
||||
{{ $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">
|
||||
<p class="selected">{{ index (index $productInfo $pageRoot) 0 | default "Select product" }}</p>
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<div class="mermaid">
|
||||
<div class="mermaid" data-component="diagram">
|
||||
{{.Inner}}
|
||||
</div>
|
|
@ -1,4 +1,4 @@
|
|||
<div id="flux-group-keys-demo">
|
||||
<div id="flux-group-keys-demo" data-component="flux-group-keys-demo">
|
||||
<div id="group-by-columns">
|
||||
<ul class="column-list">
|
||||
<li>
|
||||
|
|
|
@ -5,4 +5,4 @@
|
|||
{{- $mac := .Get "mac" | default $default -}}
|
||||
{{- $win := .Get "win" | 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>
|
|
@ -1,6 +1,6 @@
|
|||
{{ $source := .Get 0 | default "telegraf"}}
|
||||
|
||||
<div id="list-filters">
|
||||
<div id="list-filters" data-component="list-filters">
|
||||
|
||||
{{ range ( index .Site.Data.list_filters $source) }}
|
||||
{{ $numValues := len .values }}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{{- $currentVersion := index $productPathData 1 -}}
|
||||
{{- $show := .Get "show" | default 12 -}}
|
||||
|
||||
<div id="release-toc" class="{{ $currentVersion }}">
|
||||
<div id="release-toc" class="{{ $currentVersion }}" data-component="release-toc">
|
||||
<ul id="release-list" style="height: calc({{ $show }} * 1.885rem);" show="{{ $show }}">
|
||||
<!-- PLACEHOLDER FOR JS-GENERATED LIST ITEMS -->
|
||||
</ul>
|
||||
|
|
|
@ -66,8 +66,6 @@
|
|||
"test:links:api-docs": "node cypress/support/run-e2e-specs.js --spec \"cypress/e2e/content/article-links.cy.js\" /influxdb3/core/api/,/influxdb3/enterprise/api/,/influxdb3/cloud-dedicated/api/,/influxdb3/cloud-dedicated/api/v1/,/influxdb/cloud-dedicated/api/v1/,/influxdb/cloud-dedicated/api/management/,/influxdb3/cloud-dedicated/api/management/",
|
||||
"test:shortcode-examples": "node cypress/support/run-e2e-specs.js --spec \"cypress/e2e/content/article-links.cy.js\" content/example.md"
|
||||
},
|
||||
"main": "assets/js/main.js",
|
||||
"module": "assets/js/main.js",
|
||||
"type": "module",
|
||||
"browserslist": [
|
||||
"last 2 versions",
|
||||
|
|
Loading…
Reference in New Issue