Skip to content

Commit f084fe3

Browse files
authored
Ask AI group filters (#6529)
* feat(askai): add Kapa.ai source group filtering for InfluxDB v3 - Add ai_source_group_ids field to all InfluxDB v3 products in data/products.yml - Add getProductSourceGroupIds() function to retrieve source group IDs from product data - Enables filtered AI responses using Kapa source groups for documentation pages - Follows existing pattern for dynamic product configuration - Implement version-specific config support (__v1, __v2 suffixes) - Append version hints to example questions for InfluxDB database products only - Make example questions generic (remove product-specific names) - Tools (Telegraf, Chronograf, Kapacitor, Flux, Explorer) display questions without version hints - Pre-fills chat input with [version: /path/] for InfluxDB database products - Users can easily edit or remove the pre-filled text - Works for manual opens (Cmd+K) and programmatic opens - Converts module to TypeScript * refactor(ask-ai): change version format to 'My version: <product name>' Use human-readable product names instead of URL paths for better UX. Example: 'My version: InfluxDB 3 Core' instead of '[version: /influxdb3/core/]' * fix(ask-ai): restore working Kapa.open() pre-fill implementation - Replace textarea detection with direct Kapa.open() call - Add Kapa preinitialization code - Use click handler on .ask-ai-open button with capture phase - Handle conversation reset event to re-fill version context - Remove console logging for cleaner production code * fix(ask-ai): remove parentheses from example questions for consistency Make example question format match the pre-fill format: - Before: 'question (My version: product)' - After: 'question My version: product' This ensures users don't think there's a difference between the two formats. * fix(askai): add Explorer product mapping for Ask AI widget - Add influxdb3_explorer mapping to getCurrentProductData() - Add explorer context to getContext() function - Ensures Explorer pages use correct ai_sample_questions from products.yml - Reorder Explorer questions with 'install and run' first This fixes the issue where Explorer Ask AI widget was showing wrong example questions by properly loading the influxdb3_explorer config. * test(page-context): add comprehensive e2e tests for product mappings Add Cypress tests to validate page-context.js correctly identifies: - Product context values for all InfluxDB products - Product data from products.yml configuration - Version information - AI sample questions and source group IDs - Placeholder host values Tests cover: - InfluxDB 3 (Core, Enterprise, Explorer, Cloud variants, Clustered) - InfluxDB v2 and v1 - InfluxDB Cloud (TSM) - Tools (Telegraf, Chronograf, Kapacitor, Flux) Validates the fix for Explorer Ask AI showing correct example questions. Related to #jts-askai-group-filters branch work. * feat(test): add --no-mapping flag to e2e test runner Allow running functionality tests without requiring content file paths. The --no-mapping flag skips content-to-URL mapping, making it easier to run tests that don't depend on specific content files. Usage: # With content mapping (for content-specific tests) node run-e2e-specs.js content/influxdb3/core/_index.md # Without content mapping (for functionality tests) node run-e2e-specs.js --spec cypress/e2e/page-context.cy.js --no-mapping Benefits: - Simplifies running functionality tests like page-context.cy.js - Reduces test startup time by skipping unnecessary file mapping - Makes test commands clearer about their purpose The page-context test was updated to work correctly with this flag. * deps: update caniuse and related hook files * test: Add a `--no-mapping` flag to run tests without specific content files (i.e., test contains all the URLs it needs) * chore(ask-ai): Format example questions * test(page-context): add comprehensive e2e tests for all products in products.yml - Expanded test suite from 6 to 27 tests covering all products - Added tests for InfluxDB 3 products (Explorer, Core, Enterprise, Cloud Serverless, Cloud Dedicated, Clustered) - Added tests for InfluxDB v2 and Cloud (TSM) - Added tests for InfluxDB v1 and Enterprise v1 - Added tests for other products (Telegraf, Chronograf, Kapacitor, Flux) - Validates page mappings in page-context.js - Validates AI sample questions configuration in products.yml - All 27 tests passing * fix(page-context): correct enterprise_influxdb URL pattern matching - Changed pattern from /enterprise_v1/ to /enterprise_influxdb/ - Fixes Ask AI example questions not showing correctly for Enterprise v1 - Pattern now matches actual URL structure /enterprise_influxdb/v1/ - All 27 e2e tests passing * test(page-context): add UI validation for Ask AI widget configuration - Added 4 tests checking Kapa widget script data attributes - Tests verify data-modal-example-questions contains correct product-specific questions - Validates Explorer, Core, Enterprise, and Enterprise v1 configurations - All 31 tests passing (27 existing + 4 new UI tests) * feat(ask-ai): add help in Ask AI widget placeholder - InfluxDB placeholder recommends specifying product and version - Fix page-context.js to use products.influxdb_cloud instead of products.cloud - Add UI tests verifying version-specific naming in Kapa widget script tags * feat(ask-ai): Tailors placeholder for each version/product. Disables "Viewing <product>" in disclaimer note.
1 parent 936913c commit f084fe3

File tree

32 files changed

+2523
-864
lines changed

32 files changed

+2523
-864
lines changed

.github/instructions/layouts.instructions.md

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ applyTo: "layouts/**/*.html"
1111

1212
When creating or modifying Hugo layouts and shortcodes:
1313

14-
1. Use Hugo template syntax and functions
15-
2. Follow existing patterns in `/layouts/shortcodes/`
16-
3. Test in [content/example.md](../../content/example.md)
17-
4. Document new shortcodes in [DOCS-SHORTCODES.md](../../DOCS-SHORTCODES.md)
14+
1. Use test-driven development using `/cypress/`
15+
2. Use Hugo template syntax and functions
16+
3. Follow existing patterns in `/layouts/shortcodes/`
17+
4. Test in [content/example.md](../../content/example.md)
18+
5. Document new shortcodes in [DOCS-SHORTCODES.md](../../DOCS-SHORTCODES.md)
1819

1920
## Shortcode Pattern
2021

@@ -30,9 +31,32 @@ When creating or modifying Hugo layouts and shortcodes:
3031

3132
## Testing
3233

33-
Add usage examples to `content/example.md` to verify:
34+
**IMPORTANT:** Use test-driven development with Cypress.
35+
36+
Add shortcode usage examples to `content/example.md` to verify:
37+
3438
- Rendering in browser
3539
- Hugo build succeeds
3640
- No console errors
41+
- JavaScript functionality works as expected (check browser console for errors)
42+
- Interactive elements behave correctly (click links, buttons, etc.)
43+
44+
### TDD Workflow
45+
46+
1. Add Cypress tests (high-level to start).
47+
2. Run tests and make sure they fail.
48+
3. Implement code changes
49+
4. Run tests and make sure they pass.
50+
5. Add and refine tests.
51+
6. Repeat.
52+
53+
### Manual Testing Workflow
54+
55+
1. Make changes to shortcode/layout files
56+
2. Wait for Hugo to rebuild (check terminal output)
57+
3. Get the server URL from the log
58+
4. Open browser DevTools console (F12)
59+
5. Test the functionality and check for JavaScript errors
60+
6. Verify the feature works as intended before marking complete
3761

3862
See [DOCS-SHORTCODES.md](../../DOCS-SHORTCODES.md) for complete shortcode documentation.

.husky/_/pre-commit

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ call_lefthook()
3333
then
3434
"$dir/node_modules/lefthook/bin/index.js" "$@"
3535

36+
elif go tool lefthook -h >/dev/null 2>&1
37+
then
38+
go tool lefthook "$@"
3639
elif bundle exec lefthook -h >/dev/null 2>&1
3740
then
3841
bundle exec lefthook "$@"
@@ -42,12 +45,21 @@ call_lefthook()
4245
elif pnpm lefthook -h >/dev/null 2>&1
4346
then
4447
pnpm lefthook "$@"
45-
elif swift package plugin lefthook >/dev/null 2>&1
48+
elif swift package lefthook >/dev/null 2>&1
4649
then
47-
swift package --disable-sandbox plugin lefthook "$@"
50+
swift package --build-path .build/lefthook --disable-sandbox lefthook "$@"
4851
elif command -v mint >/dev/null 2>&1
4952
then
5053
mint run csjones/lefthook-plugin "$@"
54+
elif uv run lefthook -h >/dev/null 2>&1
55+
then
56+
uv run lefthook "$@"
57+
elif mise exec -- lefthook -h >/dev/null 2>&1
58+
then
59+
mise exec -- lefthook "$@"
60+
elif devbox run lefthook -h >/dev/null 2>&1
61+
then
62+
devbox run lefthook "$@"
5163
else
5264
echo "Can't find lefthook in PATH"
5365
fi

.husky/_/pre-push

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ call_lefthook()
3333
then
3434
"$dir/node_modules/lefthook/bin/index.js" "$@"
3535

36+
elif go tool lefthook -h >/dev/null 2>&1
37+
then
38+
go tool lefthook "$@"
3639
elif bundle exec lefthook -h >/dev/null 2>&1
3740
then
3841
bundle exec lefthook "$@"
@@ -42,12 +45,21 @@ call_lefthook()
4245
elif pnpm lefthook -h >/dev/null 2>&1
4346
then
4447
pnpm lefthook "$@"
45-
elif swift package plugin lefthook >/dev/null 2>&1
48+
elif swift package lefthook >/dev/null 2>&1
4649
then
47-
swift package --disable-sandbox plugin lefthook "$@"
50+
swift package --build-path .build/lefthook --disable-sandbox lefthook "$@"
4851
elif command -v mint >/dev/null 2>&1
4952
then
5053
mint run csjones/lefthook-plugin "$@"
54+
elif uv run lefthook -h >/dev/null 2>&1
55+
then
56+
uv run lefthook "$@"
57+
elif mise exec -- lefthook -h >/dev/null 2>&1
58+
then
59+
mise exec -- lefthook "$@"
60+
elif devbox run lefthook -h >/dev/null 2>&1
61+
then
62+
devbox run lefthook "$@"
5163
else
5264
echo "Can't find lefthook in PATH"
5365
fi

.husky/_/prepare-commit-msg

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ call_lefthook()
3333
then
3434
"$dir/node_modules/lefthook/bin/index.js" "$@"
3535

36+
elif go tool lefthook -h >/dev/null 2>&1
37+
then
38+
go tool lefthook "$@"
3639
elif bundle exec lefthook -h >/dev/null 2>&1
3740
then
3841
bundle exec lefthook "$@"
@@ -42,12 +45,21 @@ call_lefthook()
4245
elif pnpm lefthook -h >/dev/null 2>&1
4346
then
4447
pnpm lefthook "$@"
45-
elif swift package plugin lefthook >/dev/null 2>&1
48+
elif swift package lefthook >/dev/null 2>&1
4649
then
47-
swift package --disable-sandbox plugin lefthook "$@"
50+
swift package --build-path .build/lefthook --disable-sandbox lefthook "$@"
4851
elif command -v mint >/dev/null 2>&1
4952
then
5053
mint run csjones/lefthook-plugin "$@"
54+
elif uv run lefthook -h >/dev/null 2>&1
55+
then
56+
uv run lefthook "$@"
57+
elif mise exec -- lefthook -h >/dev/null 2>&1
58+
then
59+
mise exec -- lefthook "$@"
60+
elif devbox run lefthook -h >/dev/null 2>&1
61+
then
62+
devbox run lefthook "$@"
5163
else
5264
echo "Can't find lefthook in PATH"
5365
fi

assets/js/ask-ai-trigger.js

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,117 @@
11
import AskAI from './ask-ai.js';
22

3+
/**
4+
* Global state for Ask AI initialization
5+
*/
6+
const state = {
7+
kapaInitialized: false,
8+
linksListenerInitialized: false,
9+
};
10+
11+
/**
12+
* Initialize the Kapa widget
13+
*/
14+
function initializeKapa() {
15+
if (!state.kapaInitialized) {
16+
AskAI();
17+
state.kapaInitialized = true;
18+
19+
// Store in global namespace for debugging
20+
window.influxdatadocs = window.influxdatadocs || {};
21+
window.influxdatadocs.kapaInitialized = true;
22+
}
23+
}
24+
25+
/**
26+
* Show the trigger button by removing inline display: none style
27+
* @param {HTMLElement} element - The trigger button element
28+
*/
329
function showTrigger(element) {
4-
// Remove the inline display: none style
5-
element.removeAttribute('style');
30+
if (element) {
31+
element.removeAttribute('style');
32+
}
633
}
734

35+
/**
36+
* Initialize Ask AI trigger button component
37+
* @param {Object} options - Component options
38+
* @param {HTMLElement} options.component - The trigger button element
39+
*/
840
export default function AskAITrigger({ component }) {
941
const kapaContainer = document.querySelector('#kapa-widget-container');
42+
1043
if (!component && !kapaContainer) {
1144
return;
1245
}
46+
1347
if (!kapaContainer) {
1448
// Initialize the chat widget
1549
AskAI({ onChatLoad: () => showTrigger(component) });
50+
state.kapaInitialized = true;
51+
window.influxdatadocs = window.influxdatadocs || {};
52+
window.influxdatadocs.kapaInitialized = true;
1653
} else {
1754
showTrigger(component);
1855
}
19-
}
56+
}
57+
58+
/**
59+
* Handle ask-ai-link clicks globally
60+
* This ensures ask-ai-link shortcodes work even without the trigger button
61+
*/
62+
function handleAskAILinks() {
63+
if (state.linksListenerInitialized) {
64+
return;
65+
}
66+
67+
state.linksListenerInitialized = true;
68+
69+
// Store in global namespace for debugging
70+
window.influxdatadocs = window.influxdatadocs || {};
71+
window.influxdatadocs.askAILinksInitialized = true;
72+
73+
// Listen for clicks on ask-ai-link elements
74+
document.addEventListener(
75+
'click',
76+
(event) => {
77+
const link = event.target.closest('.ask-ai-open');
78+
if (!link) return;
79+
80+
const query = link.getAttribute('data-query');
81+
82+
// Initialize Kapa if not already done
83+
if (!state.kapaInitialized) {
84+
initializeKapa();
85+
86+
// Wait for Kapa to be ready, then open with query
87+
if (query && window.Kapa?.open) {
88+
// Give Kapa a moment to initialize
89+
setTimeout(() => {
90+
if (window.Kapa?.open) {
91+
window.Kapa.open({
92+
mode: 'ai',
93+
query: query,
94+
});
95+
}
96+
}, 100);
97+
}
98+
} else {
99+
// Kapa is already initialized - open with query if provided
100+
if (query && window.Kapa?.open) {
101+
window.Kapa.open({
102+
mode: 'ai',
103+
query: query,
104+
});
105+
}
106+
}
107+
},
108+
{ passive: true }
109+
);
110+
}
111+
112+
// Initialize ask-ai-link handling when DOM is ready
113+
if (document.readyState === 'loading') {
114+
document.addEventListener('DOMContentLoaded', handleAskAILinks);
115+
} else {
116+
handleAskAILinks();
117+
}

assets/js/ask-ai.js

Lines changed: 0 additions & 108 deletions
This file was deleted.

0 commit comments

Comments
 (0)