@redocly/theme 0.18.2 → 0.18.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/Breadcrumbs/Breadcrumb.d.ts +1 -0
- package/lib/components/Breadcrumbs/Breadcrumb.js +2 -2
- package/lib/components/Breadcrumbs/Breadcrumbs.js +8 -1
- package/lib/components/Catalog/CatalogCard.js +2 -1
- package/lib/components/Catalog/useCatalog.js +12 -1
- package/lib/components/CodeBlock/CodeBlockControls.js +6 -2
- package/lib/components/ColorModeSwitcher/ColorModeSwitcher.js +2 -0
- package/lib/components/EditPageButton/EditPageButton.js +2 -1
- package/lib/components/Feedback/Feedback.js +13 -3
- package/lib/components/Feedback/Sentiment.js +6 -2
- package/lib/components/Footer/FooterColumn.js +2 -1
- package/lib/components/Menu/MenuLinkItem.js +2 -1
- package/lib/components/Navbar/MobileUserProfile.js +6 -2
- package/lib/components/Navbar/NavbarItem.js +3 -2
- package/lib/components/NavbarLogo/NavbarLogo.js +2 -1
- package/lib/components/Profile/LoginLink.js +4 -1
- package/lib/components/Profile/UserProfile.js +5 -1
- package/lib/components/Search/SearchItem.js +10 -13
- package/lib/components/Sidebar/SidebarLayout.js +2 -1
- package/lib/components/SidebarActions/SidebarActions.js +15 -3
- package/lib/components/TableOfContent/TableOfContent.js +2 -1
- package/lib/config.d.ts +2 -2
- package/lib/config.js +1 -1
- package/package.json +2 -2
- package/src/components/Breadcrumbs/Breadcrumb.tsx +8 -2
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +13 -1
- package/src/components/Catalog/CatalogCard.tsx +2 -1
- package/src/components/Catalog/useCatalog.ts +13 -1
- package/src/components/CodeBlock/CodeBlockControls.tsx +6 -1
- package/src/components/ColorModeSwitcher/ColorModeSwitcher.tsx +3 -0
- package/src/components/EditPageButton/EditPageButton.tsx +2 -1
- package/src/components/Feedback/Feedback.tsx +13 -3
- package/src/components/Feedback/Sentiment.tsx +10 -2
- package/src/components/Footer/FooterColumn.tsx +2 -0
- package/src/components/Menu/MenuLinkItem.tsx +6 -1
- package/src/components/Navbar/MobileUserProfile.tsx +12 -2
- package/src/components/Navbar/NavbarItem.tsx +3 -0
- package/src/components/NavbarLogo/NavbarLogo.tsx +2 -0
- package/src/components/Profile/LoginLink.tsx +8 -1
- package/src/components/Profile/UserProfile.tsx +5 -1
- package/src/components/Search/SearchItem.tsx +22 -27
- package/src/components/Sidebar/SidebarLayout.tsx +6 -1
- package/src/components/SidebarActions/SidebarActions.tsx +18 -3
- package/src/components/TableOfContent/TableOfContent.tsx +2 -0
- package/src/config.ts +1 -1
|
@@ -8,8 +8,8 @@ const react_1 = __importDefault(require("react"));
|
|
|
8
8
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
9
9
|
const Link_1 = require("../../mocks/Link");
|
|
10
10
|
const Breadcrumb = (props) => {
|
|
11
|
-
const { label, link, isActive } = props;
|
|
12
|
-
return (react_1.default.createElement(BreadcrumbWrapper, { "data-component-name": "Breadcrumbs/Breadcrumb", isLink: link != null, isActive: isActive }, link ? (react_1.default.createElement(BreadcrumbLink, { to: link }, label)) : (react_1.default.createElement(BreadcrumbText, null, label))));
|
|
11
|
+
const { label, link, isActive, onClick } = props;
|
|
12
|
+
return (react_1.default.createElement(BreadcrumbWrapper, { "data-component-name": "Breadcrumbs/Breadcrumb", isLink: link != null, isActive: isActive, onClick: onClick }, link ? (react_1.default.createElement(BreadcrumbLink, { to: link }, label)) : (react_1.default.createElement(BreadcrumbText, null, label))));
|
|
13
13
|
};
|
|
14
14
|
exports.Breadcrumb = Breadcrumb;
|
|
15
15
|
const BreadcrumbText = styled_components_1.default.div `
|
|
@@ -7,6 +7,7 @@ exports.Breadcrumbs = void 0;
|
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
8
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
9
9
|
const useBreadcrumbs_1 = require("../../mocks/Sidebar/useBreadcrumbs");
|
|
10
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
10
11
|
const Breadcrumb_1 = require("./Breadcrumb");
|
|
11
12
|
const Breadcrumbs = (props) => {
|
|
12
13
|
const breadcrumbs = (0, useBreadcrumbs_1.useBreadcrumbs)();
|
|
@@ -16,7 +17,13 @@ const Breadcrumbs = (props) => {
|
|
|
16
17
|
return (react_1.default.createElement(Container, { "data-component-name": "Breadcrumbs/Breadcrumbs", className: props.className }, breadcrumbs.map((breadcrumb, idx) => {
|
|
17
18
|
const isLast = idx === breadcrumbs.length - 1;
|
|
18
19
|
return (react_1.default.createElement(react_1.default.Fragment, { key: idx },
|
|
19
|
-
react_1.default.createElement(Breadcrumb_1.Breadcrumb, { link: breadcrumb.link, label: breadcrumb.label, isActive: isLast
|
|
20
|
+
react_1.default.createElement(Breadcrumb_1.Breadcrumb, { link: breadcrumb.link, label: breadcrumb.label, isActive: isLast, onClick: () => {
|
|
21
|
+
telemetry_1.telemetry.send('breadcrumb_clicked', {
|
|
22
|
+
link: breadcrumb.link,
|
|
23
|
+
position: idx + 1,
|
|
24
|
+
total_breadcrumbs: breadcrumbs.length,
|
|
25
|
+
});
|
|
26
|
+
} }),
|
|
20
27
|
isLast ? null : react_1.default.createElement("div", null, "/")));
|
|
21
28
|
})));
|
|
22
29
|
};
|
|
@@ -33,6 +33,7 @@ const Link_1 = require("../../mocks/Link");
|
|
|
33
33
|
const Highlight_1 = require("../../ui/Highlight");
|
|
34
34
|
const Tags_1 = require("../../components/Tags");
|
|
35
35
|
const hooks_1 = require("../../mocks/hooks");
|
|
36
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
36
37
|
function CatalogCard({ item }) {
|
|
37
38
|
var _a;
|
|
38
39
|
const { translate } = (0, hooks_1.useTranslate)();
|
|
@@ -40,7 +41,7 @@ function CatalogCard({ item }) {
|
|
|
40
41
|
footer: 'theme.catalog.card.footer',
|
|
41
42
|
};
|
|
42
43
|
return (React.createElement(Link_1.Link, { key: item.docsLink || item.link, to: item.docsLink || item.link },
|
|
43
|
-
React.createElement(StyledCard,
|
|
44
|
+
React.createElement(StyledCard, { onClick: () => telemetry_1.telemetry.send('catalog_item_clicked', {}) },
|
|
44
45
|
React.createElement(CardTitle, null,
|
|
45
46
|
React.createElement(Highlight_1.Highlight, null, item.title)),
|
|
46
47
|
React.createElement(CardDescription, null,
|
|
@@ -26,6 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.useCatalog = void 0;
|
|
27
27
|
const React = __importStar(require("react"));
|
|
28
28
|
const react_router_dom_1 = require("react-router-dom");
|
|
29
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
29
30
|
const utils_1 = require("../../utils");
|
|
30
31
|
function useCatalog(items, config) {
|
|
31
32
|
const location = (0, react_router_dom_1.useLocation)();
|
|
@@ -60,6 +61,7 @@ function useCatalog(items, config) {
|
|
|
60
61
|
}
|
|
61
62
|
return [...prev.slice(0, filterIdx), newFilterOptions, ...prev.slice(filterIdx + 1)];
|
|
62
63
|
});
|
|
64
|
+
telemetry_1.telemetry.send('catalog_filter_changed', { type: 'toggle' });
|
|
63
65
|
window.scrollTo(0, 0);
|
|
64
66
|
}, []);
|
|
65
67
|
const selectOption = React.useCallback((filterIdx, option) => {
|
|
@@ -77,6 +79,7 @@ function useCatalog(items, config) {
|
|
|
77
79
|
? new Set()
|
|
78
80
|
: f);
|
|
79
81
|
});
|
|
82
|
+
telemetry_1.telemetry.send('catalog_filter_changed', { type: 'select' });
|
|
80
83
|
window.scrollTo(0, 0);
|
|
81
84
|
}, [filtersWithOptions]);
|
|
82
85
|
React.useEffect(() => {
|
|
@@ -136,7 +139,15 @@ function useCatalog(items, config) {
|
|
|
136
139
|
const groups = config.groupByFirstFilter && ((_a = filters[0].selectedOptions) === null || _a === void 0 ? void 0 : _a.size) > 0
|
|
137
140
|
? groupByFirstFilter(resolvedFilters, filteredItems)
|
|
138
141
|
: [{ title: 'APIs', items: filteredItems }];
|
|
139
|
-
return {
|
|
142
|
+
return {
|
|
143
|
+
groups,
|
|
144
|
+
filters: resolvedFilters,
|
|
145
|
+
setFilterTerm: (newTerm) => {
|
|
146
|
+
setFilterTerm(newTerm);
|
|
147
|
+
telemetry_1.telemetry.send('catalog_filter_changed', { type: 'term' });
|
|
148
|
+
},
|
|
149
|
+
filterTerm,
|
|
150
|
+
};
|
|
140
151
|
}, [
|
|
141
152
|
filtersWithOptions,
|
|
142
153
|
normalizedItems,
|
|
@@ -9,6 +9,7 @@ const styled_components_1 = __importDefault(require("styled-components"));
|
|
|
9
9
|
const CodeBlock_1 = require("../../components/CodeBlock");
|
|
10
10
|
const icons_1 = require("../../icons");
|
|
11
11
|
const hooks_1 = require("../../hooks");
|
|
12
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
12
13
|
const CopyButton_1 = require("../CopyButton");
|
|
13
14
|
function CodeBlockControls({ children, className, title, controls, }) {
|
|
14
15
|
var _a, _b, _c, _d, _e;
|
|
@@ -20,12 +21,15 @@ function CodeBlockControls({ children, className, title, controls, }) {
|
|
|
20
21
|
const defaultControls = controls ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
21
22
|
react_1.default.createElement(Title, null, title),
|
|
22
23
|
react_1.default.createElement(ControlsWrapper, null,
|
|
23
|
-
copy && !((_a = codeSnippet === null || codeSnippet === void 0 ? void 0 : codeSnippet.copy) === null || _a === void 0 ? void 0 : _a.hide) ? (react_1.default.createElement(CopyButton_1.CopyButton, { data: copy.data, "data-source": copy.dataSource, "data-hash": copy.dataHash, type: controlsType, toasterPlacement: copy.toasterPlacement, toasterDuration: copy.toasterDuration, buttonText: copy.label, tooltipText: copy.tooltipText, onCopyClick:
|
|
24
|
+
copy && !((_a = codeSnippet === null || codeSnippet === void 0 ? void 0 : codeSnippet.copy) === null || _a === void 0 ? void 0 : _a.hide) ? (react_1.default.createElement(CopyButton_1.CopyButton, { data: copy.data, "data-source": copy.dataSource, "data-hash": copy.dataHash, type: controlsType, toasterPlacement: copy.toasterPlacement, toasterDuration: copy.toasterDuration, buttonText: copy.label, tooltipText: copy.tooltipText, onCopyClick: () => {
|
|
25
|
+
copy === null || copy === void 0 ? void 0 : copy.onClick;
|
|
26
|
+
telemetry_1.telemetry.send('code_snippet_copied', {});
|
|
27
|
+
} })) : null,
|
|
24
28
|
expand && !((_b = codeSnippet === null || codeSnippet === void 0 ? void 0 : codeSnippet.expand) === null || _b === void 0 ? void 0 : _b.hide) ? (react_1.default.createElement(CodeBlock_1.CodeBlockControlButton, { "data-cy": "expand-all", "data-testid": "expand-all", asIcon: controlsType === 'icon', onClick: expand === null || expand === void 0 ? void 0 : expand.onClick, title: (expand === null || expand === void 0 ? void 0 : expand.tooltipText) || 'Expand all' }, controlsType === 'icon' ? react_1.default.createElement(icons_1.ExpandIcon, null) : (expand === null || expand === void 0 ? void 0 : expand.label) ? expand.label : 'Expand all')) : null,
|
|
25
29
|
collapse && !((_c = codeSnippet === null || codeSnippet === void 0 ? void 0 : codeSnippet.collapse) === null || _c === void 0 ? void 0 : _c.hide) ? (react_1.default.createElement(CodeBlock_1.CodeBlockControlButton, { "data-cy": "collapse-all", "data-testid": "collapse-all", asIcon: controlsType === 'icon', onClick: collapse === null || collapse === void 0 ? void 0 : collapse.onClick, title: (collapse === null || collapse === void 0 ? void 0 : collapse.tooltipText) || 'Collapse all' }, controlsType === 'icon' ? (react_1.default.createElement(icons_1.CollapseIcon, null)) : (collapse === null || collapse === void 0 ? void 0 : collapse.label) ? (collapse.label) : ('Collapse all'))) : null,
|
|
26
30
|
select ? (react_1.default.createElement(CodeBlock_1.CodeBlockControlButton, { "data-cy": "select-all", "data-testid": "select-all", asIcon: controlsType === 'icon', onClick: select === null || select === void 0 ? void 0 : select.onClick, title: select === null || select === void 0 ? void 0 : select.tooltipText }, controlsType === 'icon' ? react_1.default.createElement(icons_1.SelectIcon, null) : (select === null || select === void 0 ? void 0 : select.label) ? select.label : 'Select all')) : null,
|
|
27
31
|
deselect ? (react_1.default.createElement(CodeBlock_1.CodeBlockControlButton, { "data-cy": "clear-all", "data-testid": "clear-all", asIcon: controlsType === 'icon', onClick: deselect === null || deselect === void 0 ? void 0 : deselect.onClick, title: deselect === null || deselect === void 0 ? void 0 : deselect.tooltipText }, controlsType === 'icon' ? (react_1.default.createElement(icons_1.DeselectIcon, null)) : (deselect === null || deselect === void 0 ? void 0 : deselect.label) ? (deselect.label) : ('Clear all'))) : null,
|
|
28
|
-
report && ((_d = report === null || report === void 0 ? void 0 : report.props) === null || _d === void 0 ? void 0 : _d.visible) ? (react_1.default.createElement(CodeBlock_1.CodeBlockControlButton, Object.assign({ "data-cy": "report-button", "data-testid": "report-button", asIcon: controlsType === 'icon', title: report.tooltipText }, report.props), controlsType === 'icon' ? react_1.default.createElement(icons_1.ReportIcon, null) : ((_e = report.props) === null || _e === void 0 ? void 0 : _e.buttonText) || 'Report')) : null))) : null;
|
|
32
|
+
report && ((_d = report === null || report === void 0 ? void 0 : report.props) === null || _d === void 0 ? void 0 : _d.visible) ? (react_1.default.createElement(CodeBlock_1.CodeBlockControlButton, Object.assign({ "data-cy": "report-button", "data-testid": "report-button", asIcon: controlsType === 'icon', title: report.tooltipText }, report.props, { onClick: () => telemetry_1.telemetry.send('code_snippet_reported', {}) }), controlsType === 'icon' ? react_1.default.createElement(icons_1.ReportIcon, null) : ((_e = report.props) === null || _e === void 0 ? void 0 : _e.buttonText) || 'Report')) : null))) : null;
|
|
29
33
|
return children || controls ? (react_1.default.createElement(ContainerWraper, { "data-component-name": "CodeBlock/CodeBlockControls", className: className }, children ? children : defaultControls)) : null;
|
|
30
34
|
}
|
|
31
35
|
exports.CodeBlockControls = CodeBlockControls;
|
|
@@ -31,6 +31,7 @@ const react_1 = __importStar(require("react"));
|
|
|
31
31
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
32
32
|
const ColorModeIcon_1 = require("../../icons/ColorModeIcon");
|
|
33
33
|
const hooks_1 = require("../../hooks");
|
|
34
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
34
35
|
function ColorModeSwitcher(props) {
|
|
35
36
|
const { className } = props;
|
|
36
37
|
const themeSettings = (0, hooks_1.useThemeConfig)();
|
|
@@ -53,6 +54,7 @@ function ColorModeSwitcher(props) {
|
|
|
53
54
|
window.requestAnimationFrame(() => {
|
|
54
55
|
document.documentElement.classList.remove('notransition');
|
|
55
56
|
});
|
|
57
|
+
telemetry_1.telemetry.send('color_mode_switched', { from: activeColorMode, to: mode });
|
|
56
58
|
};
|
|
57
59
|
return (react_1.default.createElement(Wrapper, { "data-component-name": "ColorModeSwitcher/ColorModeSwitcher", onClick: handelChangeColorMode, modes: modes, role: "link", className: className }, modes.map((mode) => (react_1.default.createElement(ColorModeIcon_1.ColorModeIcon, { mode: mode, key: mode })))));
|
|
58
60
|
}
|
|
@@ -7,8 +7,9 @@ exports.EditPageButton = void 0;
|
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
8
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
9
9
|
const Link_1 = require("../../mocks/Link");
|
|
10
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
10
11
|
const EditPageButton = ({ text, to, icon }) => {
|
|
11
|
-
return (react_1.default.createElement(EditButton, { to: to },
|
|
12
|
+
return (react_1.default.createElement(EditButton, { to: to, onClick: () => telemetry_1.telemetry.send('edit_page_link_clicked', {}) },
|
|
12
13
|
icon ? react_1.default.createElement(ButtonIcon, { src: icon }) : null,
|
|
13
14
|
react_1.default.createElement(ButtonText, null, text)));
|
|
14
15
|
};
|
|
@@ -33,6 +33,7 @@ const styled_components_1 = __importDefault(require("styled-components"));
|
|
|
33
33
|
const Feedback_1 = require("../../components/Feedback");
|
|
34
34
|
const hooks_1 = require("../../hooks");
|
|
35
35
|
const useSubmitFeedback_1 = require("../../mocks/Feedback/useSubmitFeedback");
|
|
36
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
36
37
|
const Feedback = (props) => {
|
|
37
38
|
const { submitFeedback } = (0, useSubmitFeedback_1.useSubmitFeedback)();
|
|
38
39
|
const { pathname } = (0, react_router_dom_1.useLocation)();
|
|
@@ -42,13 +43,22 @@ const Feedback = (props) => {
|
|
|
42
43
|
switch (type) {
|
|
43
44
|
case 'rating':
|
|
44
45
|
return (React.createElement(Wrapper, null,
|
|
45
|
-
React.createElement(Feedback_1.Rating, { settings: settings, onSubmit: (values) =>
|
|
46
|
+
React.createElement(Feedback_1.Rating, { settings: settings, onSubmit: (values) => {
|
|
47
|
+
submitFeedback({ type: 'rating', values, path });
|
|
48
|
+
telemetry_1.telemetry.send('feedback_sent', { type: 'rating' });
|
|
49
|
+
} })));
|
|
46
50
|
case 'sentiment':
|
|
47
51
|
return (React.createElement(Wrapper, null,
|
|
48
|
-
React.createElement(Feedback_1.Sentiment, { settings: settings, onSubmit: (values) =>
|
|
52
|
+
React.createElement(Feedback_1.Sentiment, { settings: settings, onSubmit: (values) => {
|
|
53
|
+
submitFeedback({ type: 'sentiment', values, path });
|
|
54
|
+
telemetry_1.telemetry.send('feedback_sent', { type: 'sentiment' });
|
|
55
|
+
} })));
|
|
49
56
|
case 'comment':
|
|
50
57
|
return (React.createElement(Wrapper, null,
|
|
51
|
-
React.createElement(Feedback_1.Comment, { settings: settings, onSubmit: (values) =>
|
|
58
|
+
React.createElement(Feedback_1.Comment, { settings: settings, onSubmit: (values) => {
|
|
59
|
+
submitFeedback({ type: 'comment', values, path });
|
|
60
|
+
telemetry_1.telemetry.send('feedback_sent', { type: 'comment' });
|
|
61
|
+
} })));
|
|
52
62
|
default:
|
|
53
63
|
console.log(`No feedback with type ${type}!`);
|
|
54
64
|
break;
|
|
@@ -66,9 +66,13 @@ const Sentiment = ({ settings, onSubmit, className }) => {
|
|
|
66
66
|
}
|
|
67
67
|
return (React.createElement(Wrapper, { "data-component-name": "Feedback/Sentiment", className: className },
|
|
68
68
|
React.createElement(Label, { "data-translation-key": translationKeys.label }, translate(translationKeys.label, label || 'Was this page helpful?')),
|
|
69
|
-
React.createElement(Vote, { onClick: () =>
|
|
69
|
+
React.createElement(Vote, { onClick: () => {
|
|
70
|
+
setScore(1);
|
|
71
|
+
} },
|
|
70
72
|
React.createElement(Thumbs_1.ThumbUp, { text: "Yes" })),
|
|
71
|
-
React.createElement(Vote, { onClick: () =>
|
|
73
|
+
React.createElement(Vote, { onClick: () => {
|
|
74
|
+
setScore(-1);
|
|
75
|
+
} },
|
|
72
76
|
React.createElement(Thumbs_1.ThumbDown, null))));
|
|
73
77
|
};
|
|
74
78
|
exports.Sentiment = Sentiment;
|
|
@@ -31,6 +31,7 @@ const react_1 = __importDefault(require("react"));
|
|
|
31
31
|
const styled_components_1 = __importStar(require("styled-components"));
|
|
32
32
|
const Link_1 = require("../../mocks/Link");
|
|
33
33
|
const hooks_1 = require("../../mocks/hooks");
|
|
34
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
34
35
|
function FooterColumn({ column, className }) {
|
|
35
36
|
var _a;
|
|
36
37
|
const { translate } = (0, hooks_1.useTranslate)();
|
|
@@ -41,7 +42,7 @@ function FooterColumn({ column, className }) {
|
|
|
41
42
|
if (columnItem.type === 'error') {
|
|
42
43
|
return null;
|
|
43
44
|
}
|
|
44
|
-
return columnItem.type === 'separator' ? (react_1.default.createElement(FooterSeparator, { key: columnItem.label + '_' + columnItemIndex }, translate(columnItem.labelTranslationKey, columnItem.label))) : (react_1.default.createElement(FooterLink, { key: columnItemIndex, to: columnItem.link, external: columnItem.external, target: columnItem.target, "data-cy": columnItem.label },
|
|
45
|
+
return columnItem.type === 'separator' ? (react_1.default.createElement(FooterSeparator, { key: columnItem.label + '_' + columnItemIndex }, translate(columnItem.labelTranslationKey, columnItem.label))) : (react_1.default.createElement(FooterLink, { key: columnItemIndex, to: columnItem.link, external: columnItem.external, target: columnItem.target, "data-cy": columnItem.label, onClick: () => telemetry_1.telemetry.send('footer_item_clicked', {}) },
|
|
45
46
|
react_1.default.createElement(exports.FooterLinkIcon, { url: columnItem.icon, withIconPadding: hasIcon }),
|
|
46
47
|
translate(columnItem.labelTranslationKey, columnItem.label)));
|
|
47
48
|
})));
|
|
@@ -7,8 +7,9 @@ exports.MenuLinkItem = void 0;
|
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
8
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
9
9
|
const MenuLink_1 = require("../../components/Menu/MenuLink");
|
|
10
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
10
11
|
function MenuLinkItem({ item, children, className, }) {
|
|
11
|
-
return (react_1.default.createElement(Wrapper, { "data-component-name": "Sidebar/MenuLinkItem", className: className }, item.link ? (react_1.default.createElement(MenuLink_1.MenuLink, Object.assign({ to: item.link }, item), children)) : (children)));
|
|
12
|
+
return (react_1.default.createElement(Wrapper, { "data-component-name": "Sidebar/MenuLinkItem", className: className, onClick: () => telemetry_1.telemetry.send('sidebar_item_clicked', { label: item.label, type: item.type }) }, item.link ? (react_1.default.createElement(MenuLink_1.MenuLink, Object.assign({ to: item.link }, item), children)) : (children)));
|
|
12
13
|
}
|
|
13
14
|
exports.MenuLinkItem = MenuLinkItem;
|
|
14
15
|
const Wrapper = styled_components_1.default.span ``;
|
|
@@ -11,6 +11,7 @@ const LogoutIcon_1 = require("../../icons/LogoutIcon");
|
|
|
11
11
|
const Profile_1 = require("../../components/Profile/Profile");
|
|
12
12
|
const useThemeConfig_1 = require("../../hooks/useThemeConfig");
|
|
13
13
|
const hooks_1 = require("../../mocks/hooks");
|
|
14
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
14
15
|
function MobileUserProfile() {
|
|
15
16
|
const { userProfile } = (0, useThemeConfig_1.useThemeConfig)();
|
|
16
17
|
const { userData, handleLogout, loginUrl } = (0, useProfileProps_1.useProfileProps)();
|
|
@@ -20,12 +21,15 @@ function MobileUserProfile() {
|
|
|
20
21
|
};
|
|
21
22
|
if (!(userData === null || userData === void 0 ? void 0 : userData.isAuthenticated) && !loginUrl)
|
|
22
23
|
return null;
|
|
23
|
-
return (react_1.default.createElement(MobileProfileWrapper, { "data-component-name": "Navbar/MobileUserProfile" }, !(userData === null || userData === void 0 ? void 0 : userData.isAuthenticated) ? (react_1.default.createElement(LoginButton, { href: loginUrl, "data-cy": "login-btn" }, translate(translationKeys.login, (userProfile === null || userProfile === void 0 ? void 0 : userProfile.loginLabel) || 'Login'))) : (react_1.default.createElement(react_1.default.Fragment, null,
|
|
24
|
+
return (react_1.default.createElement(MobileProfileWrapper, { "data-component-name": "Navbar/MobileUserProfile" }, !(userData === null || userData === void 0 ? void 0 : userData.isAuthenticated) ? (react_1.default.createElement(LoginButton, { href: loginUrl, "data-cy": "login-btn", onClick: () => telemetry_1.telemetry.send('login_button_clicked', {}) }, translate(translationKeys.login, (userProfile === null || userProfile === void 0 ? void 0 : userProfile.loginLabel) || 'Login'))) : (react_1.default.createElement(react_1.default.Fragment, null,
|
|
24
25
|
react_1.default.createElement(UserDataWrapper, null,
|
|
25
26
|
react_1.default.createElement(ProfilePicture, null,
|
|
26
27
|
react_1.default.createElement(Profile_1.Profile, { name: userData.name, imageUrl: userData.picture })),
|
|
27
28
|
react_1.default.createElement(UserName, null, userData.name)),
|
|
28
|
-
react_1.default.createElement(LogoutButton, { onClick: () =>
|
|
29
|
+
react_1.default.createElement(LogoutButton, { onClick: () => {
|
|
30
|
+
handleLogout();
|
|
31
|
+
telemetry_1.telemetry.send('logout_menu_item_clicked', {});
|
|
32
|
+
} },
|
|
29
33
|
react_1.default.createElement(LogoutIcon_1.LogoutIcon, null))))));
|
|
30
34
|
}
|
|
31
35
|
exports.MobileUserProfile = MobileUserProfile;
|
|
@@ -34,6 +34,7 @@ const Link_1 = require("../../mocks/Link");
|
|
|
34
34
|
const utils_1 = require("../../mocks/utils");
|
|
35
35
|
const hooks_1 = require("../../mocks/hooks");
|
|
36
36
|
const utils_2 = require("../../utils");
|
|
37
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
37
38
|
const Dropdown_1 = require("../../components/Dropdown");
|
|
38
39
|
function NavbarItem({ navItem, className }) {
|
|
39
40
|
const { pathname } = (0, react_router_dom_1.useLocation)();
|
|
@@ -43,7 +44,7 @@ function NavbarItem({ navItem, className }) {
|
|
|
43
44
|
const item = navItem;
|
|
44
45
|
const isActive = pathname ===
|
|
45
46
|
(0, utils_2.withPathPrefix)((0, utils_1.getPathnameForLocale)(item.link, defaultLocale, currentLocale, locales));
|
|
46
|
-
return (react_1.default.createElement(exports.NavbarMenuItem, { active: isActive, "data-component-name": "Navbar/NavbarItem", className: className },
|
|
47
|
+
return (react_1.default.createElement(exports.NavbarMenuItem, { active: isActive, "data-component-name": "Navbar/NavbarItem", className: className, onClick: () => telemetry_1.telemetry.send('navbar_menu_item_clicked', { type: 'link' }) },
|
|
47
48
|
react_1.default.createElement(exports.NavbarLink, { to: item.link, external: item.external, target: item.target, active: isActive },
|
|
48
49
|
item.icon ? react_1.default.createElement(exports.NavbarIcon, { url: item.icon }) : null,
|
|
49
50
|
react_1.default.createElement(NavbarLabel, null, translate(item.labelTranslationKey, item.label)))));
|
|
@@ -53,7 +54,7 @@ function NavbarItem({ navItem, className }) {
|
|
|
53
54
|
const groupItems = item.items;
|
|
54
55
|
const groupItemsComponents = groupItems.map((item, index) => (react_1.default.createElement(Link_1.Link, { key: `${item.label}_${index}`, to: item.link }, translate(item.labelTranslationKey, item.label))));
|
|
55
56
|
return (react_1.default.createElement(exports.NavbarMenuItemDropdown, { items: groupItemsComponents, triggerEvent: "hover" },
|
|
56
|
-
react_1.default.createElement(exports.NavbarMenuItem, { active: false, "data-component-name": "Navbar/NavbarItem", className: className },
|
|
57
|
+
react_1.default.createElement(exports.NavbarMenuItem, { active: false, "data-component-name": "Navbar/NavbarItem", className: className, onClick: () => telemetry_1.telemetry.send('navbar_menu_item_clicked', { type: 'group' }) },
|
|
57
58
|
react_1.default.createElement(exports.NavbarIcon, { url: item.icon }),
|
|
58
59
|
react_1.default.createElement(NavbarLabel, null, translate(item.labelTranslationKey, item.label)))));
|
|
59
60
|
}
|
|
@@ -7,11 +7,12 @@ exports.NavbarLogo = void 0;
|
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
8
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
9
9
|
const Link_1 = require("../../mocks/Link");
|
|
10
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
10
11
|
function NavbarLogo({ logo, className }) {
|
|
11
12
|
if (!logo.image) {
|
|
12
13
|
return null;
|
|
13
14
|
}
|
|
14
|
-
const img = (react_1.default.createElement(NavLogo, { className: className, src: logo.image, alt: logo.altText, "data-component-name": "NavbarLogo/NavbarLogo" }));
|
|
15
|
+
const img = (react_1.default.createElement(NavLogo, { className: className, src: logo.image, alt: logo.altText, "data-component-name": "NavbarLogo/NavbarLogo", onClick: () => telemetry_1.telemetry.send('logo_clicked', {}) }));
|
|
15
16
|
return logo.link ? react_1.default.createElement(Link_1.Link, { to: logo.link }, img) : img;
|
|
16
17
|
}
|
|
17
18
|
exports.NavbarLogo = NavbarLogo;
|
|
@@ -8,13 +8,16 @@ const react_1 = __importDefault(require("react"));
|
|
|
8
8
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
9
9
|
const useThemeConfig_1 = require("../../hooks/useThemeConfig");
|
|
10
10
|
const hooks_1 = require("../../mocks/hooks");
|
|
11
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
11
12
|
function LoginLink({ href }) {
|
|
12
13
|
const { userProfile } = (0, useThemeConfig_1.useThemeConfig)();
|
|
13
14
|
const { translate } = (0, hooks_1.useTranslate)();
|
|
14
15
|
const translationKeys = {
|
|
15
16
|
login: 'theme.profile.login',
|
|
16
17
|
};
|
|
17
|
-
return (react_1.default.createElement(StyledLink, { href: href, "data-translation-key": translationKeys.login
|
|
18
|
+
return (react_1.default.createElement(StyledLink, { href: href, "data-translation-key": translationKeys.login, onClick: () => {
|
|
19
|
+
telemetry_1.telemetry.send('login_button_clicked', {});
|
|
20
|
+
} }, translate(translationKeys.login, (userProfile === null || userProfile === void 0 ? void 0 : userProfile.loginLabel) || 'Login')));
|
|
18
21
|
}
|
|
19
22
|
exports.LoginLink = LoginLink;
|
|
20
23
|
const StyledLink = styled_components_1.default.a.attrs(() => ({
|
|
@@ -33,6 +33,7 @@ const Profile_1 = require("../../components/Profile/Profile");
|
|
|
33
33
|
const Link_1 = require("../../mocks/Link");
|
|
34
34
|
const useThemeConfig_1 = require("../../hooks/useThemeConfig");
|
|
35
35
|
const hooks_1 = require("../../mocks/hooks");
|
|
36
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
36
37
|
const Dropdown_1 = require("../../components/Dropdown");
|
|
37
38
|
function UserProfile({ userData, handleLogout, hasDeveloperOnboarding = false, }) {
|
|
38
39
|
const { userProfile } = (0, useThemeConfig_1.useThemeConfig)();
|
|
@@ -51,7 +52,10 @@ function UserProfile({ userData, handleLogout, hasDeveloperOnboarding = false, }
|
|
|
51
52
|
menuItems.push(react_1.default.createElement(Link_1.Link, { external: item.external, key: item.label, to: item.link || '', separator: item === null || item === void 0 ? void 0 : item.separatorLine }, item.label));
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
|
-
menuItems.push(react_1.default.createElement(Logout, { onClick: () =>
|
|
55
|
+
menuItems.push(react_1.default.createElement(Logout, { onClick: () => {
|
|
56
|
+
handleLogout();
|
|
57
|
+
telemetry_1.telemetry.send('logout_menu_item_clicked', {});
|
|
58
|
+
}, "data-translation-key": translationKeys.logout, role: "link" }, translate(translationKeys.logout, (userProfile === null || userProfile === void 0 ? void 0 : userProfile.logoutLabel) || 'Log out')));
|
|
55
59
|
return (react_1.default.createElement(ProfileDropdown, { items: menuItems },
|
|
56
60
|
react_1.default.createElement(Profile_1.Profile, { name: userData.name, imageUrl: userData.picture, onClick: userData.logoutDisabled ? undefined : () => setIsOpened(!isOpened) })));
|
|
57
61
|
}
|
|
@@ -34,7 +34,7 @@ const Link_1 = require("../../mocks/Link");
|
|
|
34
34
|
const utils_1 = require("../../components/Search/utils");
|
|
35
35
|
const ProductTag_1 = require("../../components/Search/ProductTag");
|
|
36
36
|
function SearchItem({ item, className, product }) {
|
|
37
|
-
var _a, _b;
|
|
37
|
+
var _a, _b, _c, _d;
|
|
38
38
|
const ref = (0, react_1.useRef)();
|
|
39
39
|
(0, react_1.useEffect)(() => {
|
|
40
40
|
var _a;
|
|
@@ -49,19 +49,16 @@ function SearchItem({ item, className, product }) {
|
|
|
49
49
|
item.pathName ? (0, utils_1.highlight)(item.pathName) : null)) : null,
|
|
50
50
|
react_1.default.createElement(Title, null, (0, utils_1.highlight)(item.title)),
|
|
51
51
|
Array.isArray(item.text) ? react_1.default.createElement(Description, null, (0, utils_1.highlight)(item.text)) : null));
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const path = `${param.place} → ${((_a = param.path) === null || _a === void 0 ? void 0 : _a.length) ? ((_b = param.path) === null || _b === void 0 ? void 0 : _b.join(' → ')) + ' → ' : ''}`;
|
|
55
|
-
return (react_1.default.createElement(SearchLink, { className: className, key: `${item.id}-${index}`, to: item.url, tabIndex: 0, innerRef: ref, "data-component-name": "Search/SearchItem" },
|
|
56
|
-
header,
|
|
57
|
-
react_1.default.createElement(Place, null,
|
|
58
|
-
react_1.default.createElement("div", null,
|
|
59
|
-
path,
|
|
60
|
-
(0, utils_1.highlight)(param.name)),
|
|
61
|
-
react_1.default.createElement("div", null, (0, utils_1.highlight)(param.description)))));
|
|
62
|
-
}))) : (react_1.default.createElement(SearchLink, { className: className, to: item.url, tabIndex: 0, innerRef: ref, "data-component-name": "Search/SearchItem" },
|
|
52
|
+
const itemParam = (_a = item.parameters) === null || _a === void 0 ? void 0 : _a[0];
|
|
53
|
+
return (react_1.default.createElement(react_1.default.Fragment, null, itemParam ? (react_1.default.createElement(SearchLink, { className: className, key: `${item.id}-${0}`, to: item.url, tabIndex: 0, innerRef: ref, "data-component-name": "Search/SearchItem" },
|
|
63
54
|
header,
|
|
64
|
-
react_1.default.createElement(
|
|
55
|
+
react_1.default.createElement(Place, null,
|
|
56
|
+
react_1.default.createElement("div", null,
|
|
57
|
+
`${itemParam.place} → ${((_b = itemParam.path) === null || _b === void 0 ? void 0 : _b.length) ? ((_c = itemParam.path) === null || _c === void 0 ? void 0 : _c.join(' → ')) + ' → ' : ''}`,
|
|
58
|
+
(0, utils_1.highlight)(itemParam.name)),
|
|
59
|
+
react_1.default.createElement("div", null, (0, utils_1.highlight)(itemParam.description))))) : (react_1.default.createElement(SearchLink, { className: className, to: item.url, tabIndex: 0, innerRef: ref, "data-component-name": "Search/SearchItem" },
|
|
60
|
+
header,
|
|
61
|
+
react_1.default.createElement(Path, null, (_d = item.path) === null || _d === void 0 ? void 0 : _d.join(' → '))))));
|
|
65
62
|
}
|
|
66
63
|
exports.SearchItem = SearchItem;
|
|
67
64
|
const Wrapper = styled_components_1.default.div `
|
|
@@ -37,6 +37,7 @@ const MobileSidebarButton_1 = require("../../components/Sidebar/MobileSidebarBut
|
|
|
37
37
|
const MenuContainer_1 = require("../../components/Menu/MenuContainer");
|
|
38
38
|
const SidebarSearch_1 = require("../../components/Search/SidebarSearch");
|
|
39
39
|
const useThemeConfig_1 = require("../../hooks/useThemeConfig");
|
|
40
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
40
41
|
const MobileSidebarIcon_1 = require("./MobileSidebarIcon");
|
|
41
42
|
const StyledFooterWrapper = (0, styled_components_1.default)(FooterWrapper_1.FooterWrapper) `
|
|
42
43
|
display: none;
|
|
@@ -65,7 +66,7 @@ function SidebarLayout({ versions, menu, footer, header, growContent, collapsed,
|
|
|
65
66
|
react_1.default.createElement(MobileSidebarIcon_1.MobileSidebarIcon, null)))) : null) : (react_1.default.createElement(Wrapper, { "data-component-name": "Sidebar/SidebarLayout", className: className },
|
|
66
67
|
!(search === null || search === void 0 ? void 0 : search.hide) && (search === null || search === void 0 ? void 0 : search.placement) === 'sidebar' ? react_1.default.createElement(SidebarSearch_1.SidebarSearch, null) : null,
|
|
67
68
|
react_1.default.createElement(Sidebar_1.Sidebar, { animate: true, opened: isOpen },
|
|
68
|
-
header ? react_1.default.createElement(HeaderWrapper_1.HeaderWrapper,
|
|
69
|
+
header ? (react_1.default.createElement(HeaderWrapper_1.HeaderWrapper, { onClick: () => telemetry_1.telemetry.send('back_to_catalog_button_clicked', {}) }, header)) : null,
|
|
69
70
|
versions ? react_1.default.createElement(react_1.default.Fragment, null, versions) : null,
|
|
70
71
|
react_1.default.createElement(MenuContainer_1.MenuContainer, { growContent: growContent }, menu),
|
|
71
72
|
footer && !isOpen ? (react_1.default.createElement(FooterWrapper_1.FooterWrapper, { "data-component-name": "Sidebar/FooterWrapper" }, footer)) : null)))));
|
|
@@ -9,6 +9,7 @@ const ChangeViewButton_1 = require("../../components/SidebarActions/ChangeViewBu
|
|
|
9
9
|
const ToggleRightPanelButton_1 = require("../../components/SidebarActions/ToggleRightPanelButton");
|
|
10
10
|
const CollapseSidebarButton_1 = require("../../components/SidebarActions/CollapseSidebarButton");
|
|
11
11
|
const styled_1 = require("../../components/SidebarActions/styled");
|
|
12
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
12
13
|
var LayoutVariant;
|
|
13
14
|
(function (LayoutVariant) {
|
|
14
15
|
LayoutVariant["STACKED"] = "stacked";
|
|
@@ -17,10 +18,21 @@ var LayoutVariant;
|
|
|
17
18
|
const SidebarActions = ({ showChangeLayoutButton, showRightPanelToggle, layout, initialShowRightPanelToggle, hideCollapseSidebarButton = false, collapsedSidebar, isOpenapiDocs, onChangeRightPanelViewClick, onChangeViewClick, onChangeCollapseSidebarClick, requestAccessButton, className, }) => {
|
|
18
19
|
return (react_1.default.createElement(styled_1.ControlsWrap, { className: className, isOpenapiDocs: isOpenapiDocs, isCollapsed: collapsedSidebar, "data-component-name": "Sidebar/Actions" },
|
|
19
20
|
isOpenapiDocs && (react_1.default.createElement(styled_1.ControlsWrapChangeLayoutButtons, { isCollapsed: collapsedSidebar },
|
|
20
|
-
initialShowRightPanelToggle && (react_1.default.createElement(ToggleRightPanelButton_1.ToggleRightPanelButton, { showRightPanelToggle: showRightPanelToggle, onClick:
|
|
21
|
-
|
|
21
|
+
initialShowRightPanelToggle && (react_1.default.createElement(ToggleRightPanelButton_1.ToggleRightPanelButton, { showRightPanelToggle: showRightPanelToggle, onClick: () => {
|
|
22
|
+
onChangeRightPanelViewClick();
|
|
23
|
+
telemetry_1.telemetry.send('sidebar_samples_button_clicked', {});
|
|
24
|
+
} })),
|
|
25
|
+
showChangeLayoutButton && showRightPanelToggle && (react_1.default.createElement(ChangeViewButton_1.ChangeViewButton, { layout: layout, onClick: () => {
|
|
26
|
+
onChangeViewClick();
|
|
27
|
+
telemetry_1.telemetry.send('change_layout_button_clicked', {});
|
|
28
|
+
} })))),
|
|
22
29
|
!collapsedSidebar && requestAccessButton,
|
|
23
|
-
!hideCollapseSidebarButton && (react_1.default.createElement(CollapseSidebarButton_1.CollapseSidebarButton, { initialValue: collapsedSidebar, onClick:
|
|
30
|
+
!hideCollapseSidebarButton && (react_1.default.createElement(CollapseSidebarButton_1.CollapseSidebarButton, { initialValue: collapsedSidebar, onClick: () => {
|
|
31
|
+
onChangeCollapseSidebarClick();
|
|
32
|
+
collapsedSidebar
|
|
33
|
+
? telemetry_1.telemetry.send('sidebar_item_expanded', {})
|
|
34
|
+
: telemetry_1.telemetry.send('sidebar_item_collapsed', {});
|
|
35
|
+
} }))));
|
|
24
36
|
};
|
|
25
37
|
exports.SidebarActions = SidebarActions;
|
|
26
38
|
//# sourceMappingURL=SidebarActions.js.map
|
|
@@ -34,6 +34,7 @@ const useActiveHeading_1 = require("../../hooks/useActiveHeading");
|
|
|
34
34
|
const useThemeConfig_1 = require("../../hooks/useThemeConfig");
|
|
35
35
|
const hooks_1 = require("../../mocks/hooks");
|
|
36
36
|
const utils_1 = require("../../components/TableOfContent/utils");
|
|
37
|
+
const telemetry_1 = require("../../mocks/telemetry");
|
|
37
38
|
function TableOfContent(props) {
|
|
38
39
|
const { headings, contentWrapper, className } = props;
|
|
39
40
|
const sidebar = React.useRef(null);
|
|
@@ -58,7 +59,7 @@ function TableOfContent(props) {
|
|
|
58
59
|
return null;
|
|
59
60
|
}
|
|
60
61
|
const href = '#' + heading.id;
|
|
61
|
-
return (React.createElement(MenuItem, { key: href + idx, href: href, depth: heading.depth - leastDepth + 1 || 0, className: activeHeadingId === heading.id ? 'active' : '', dangerouslySetInnerHTML: { __html: heading.value || '' }, "data-cy": `toc-${heading.value}
|
|
62
|
+
return (React.createElement(MenuItem, { key: href + idx, href: href, depth: heading.depth - leastDepth + 1 || 0, className: activeHeadingId === heading.id ? 'active' : '', dangerouslySetInnerHTML: { __html: heading.value || '' }, "data-cy": `toc-${heading.value}`, onClick: () => telemetry_1.telemetry.send('toc_item_clicked', {}) }));
|
|
62
63
|
})))));
|
|
63
64
|
}
|
|
64
65
|
exports.TableOfContent = TableOfContent;
|
package/lib/config.d.ts
CHANGED
|
@@ -412,7 +412,7 @@ declare const scorecardConfigSchema: {
|
|
|
412
412
|
declare const catalogSchema: {
|
|
413
413
|
readonly type: "object";
|
|
414
414
|
readonly additionalProperties: true;
|
|
415
|
-
readonly required: readonly ["slug", "filters", "
|
|
415
|
+
readonly required: readonly ["slug", "filters", "items"];
|
|
416
416
|
readonly properties: {
|
|
417
417
|
readonly slug: {
|
|
418
418
|
readonly type: "string";
|
|
@@ -1662,7 +1662,7 @@ export declare const themeConfigSchema: {
|
|
|
1662
1662
|
readonly '.*': {
|
|
1663
1663
|
readonly type: "object";
|
|
1664
1664
|
readonly additionalProperties: true;
|
|
1665
|
-
readonly required: readonly ["slug", "filters", "
|
|
1665
|
+
readonly required: readonly ["slug", "filters", "items"];
|
|
1666
1666
|
readonly properties: {
|
|
1667
1667
|
readonly slug: {
|
|
1668
1668
|
readonly type: "string";
|
package/lib/config.js
CHANGED
|
@@ -321,7 +321,7 @@ const scorecardConfigSchema = {
|
|
|
321
321
|
const catalogSchema = {
|
|
322
322
|
type: 'object',
|
|
323
323
|
additionalProperties: true,
|
|
324
|
-
required: ['slug', 'filters', '
|
|
324
|
+
required: ['slug', 'filters', 'items'],
|
|
325
325
|
properties: {
|
|
326
326
|
slug: { type: 'string' },
|
|
327
327
|
filters: { type: 'array', items: catalogFilterSchema },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/theme",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.3",
|
|
4
4
|
"description": "Shared UI components lib",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"theme",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"tsconfig-paths-webpack-plugin": "^3.5.2",
|
|
82
82
|
"typescript": "^4.8.4",
|
|
83
83
|
"webpack": "^5.72.0",
|
|
84
|
-
"@redocly/portal-types": "1.0.
|
|
84
|
+
"@redocly/portal-types": "1.0.2"
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
87
|
"@redocly/ajv": "^8.11.0",
|
|
@@ -3,14 +3,20 @@ import styled from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import { Link } from '@portal/Link';
|
|
5
5
|
|
|
6
|
-
export const Breadcrumb = (props: {
|
|
7
|
-
|
|
6
|
+
export const Breadcrumb = (props: {
|
|
7
|
+
label: string;
|
|
8
|
+
link?: string;
|
|
9
|
+
isActive: boolean;
|
|
10
|
+
onClick?: () => void;
|
|
11
|
+
}) => {
|
|
12
|
+
const { label, link, isActive, onClick } = props;
|
|
8
13
|
|
|
9
14
|
return (
|
|
10
15
|
<BreadcrumbWrapper
|
|
11
16
|
data-component-name="Breadcrumbs/Breadcrumb"
|
|
12
17
|
isLink={link != null}
|
|
13
18
|
isActive={isActive}
|
|
19
|
+
onClick={onClick}
|
|
14
20
|
>
|
|
15
21
|
{link ? (
|
|
16
22
|
<BreadcrumbLink to={link}>{label}</BreadcrumbLink>
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import { useBreadcrumbs } from '@portal/Sidebar/useBreadcrumbs';
|
|
5
|
+
import { telemetry } from '@portal/telemetry';
|
|
5
6
|
|
|
6
7
|
import { Breadcrumb } from './Breadcrumb';
|
|
7
8
|
|
|
@@ -18,7 +19,18 @@ export const Breadcrumbs = (props: { className?: string }) => {
|
|
|
18
19
|
const isLast = idx === breadcrumbs.length - 1;
|
|
19
20
|
return (
|
|
20
21
|
<React.Fragment key={idx}>
|
|
21
|
-
<Breadcrumb
|
|
22
|
+
<Breadcrumb
|
|
23
|
+
link={breadcrumb.link}
|
|
24
|
+
label={breadcrumb.label}
|
|
25
|
+
isActive={isLast}
|
|
26
|
+
onClick={() => {
|
|
27
|
+
telemetry.send('breadcrumb_clicked', {
|
|
28
|
+
link: breadcrumb.link,
|
|
29
|
+
position: idx + 1,
|
|
30
|
+
total_breadcrumbs: breadcrumbs.length,
|
|
31
|
+
});
|
|
32
|
+
}}
|
|
33
|
+
/>
|
|
22
34
|
{isLast ? null : <div>/</div>}
|
|
23
35
|
</React.Fragment>
|
|
24
36
|
);
|
|
@@ -6,6 +6,7 @@ import { Link } from '@portal/Link';
|
|
|
6
6
|
import { Highlight } from '@theme/ui/Highlight';
|
|
7
7
|
import { Tags } from '@theme/components/Tags';
|
|
8
8
|
import { useTranslate } from '@portal/hooks';
|
|
9
|
+
import { telemetry } from '@portal/telemetry';
|
|
9
10
|
|
|
10
11
|
export function CatalogCard({ item }: { item: CatalogItem }): JSX.Element {
|
|
11
12
|
const { translate } = useTranslate();
|
|
@@ -14,7 +15,7 @@ export function CatalogCard({ item }: { item: CatalogItem }): JSX.Element {
|
|
|
14
15
|
};
|
|
15
16
|
return (
|
|
16
17
|
<Link key={item.docsLink || item.link} to={item.docsLink || item.link}>
|
|
17
|
-
<StyledCard>
|
|
18
|
+
<StyledCard onClick={() => telemetry.send('catalog_item_clicked', {})}>
|
|
18
19
|
<CardTitle>
|
|
19
20
|
<Highlight>{item.title}</Highlight>
|
|
20
21
|
</CardTitle>
|
|
@@ -3,6 +3,7 @@ import { useLocation, useNavigate } from 'react-router-dom';
|
|
|
3
3
|
|
|
4
4
|
import type { Location } from 'react-router-dom';
|
|
5
5
|
|
|
6
|
+
import { telemetry } from '@portal/telemetry';
|
|
6
7
|
import type { ResolvedNavItem } from '@theme/types/portal';
|
|
7
8
|
import type {
|
|
8
9
|
CatalogItem,
|
|
@@ -45,6 +46,7 @@ export function useCatalog(items: ResolvedNavItem[], config: CatalogConfig): Fil
|
|
|
45
46
|
}
|
|
46
47
|
return [...prev.slice(0, filterIdx), newFilterOptions, ...prev.slice(filterIdx + 1)];
|
|
47
48
|
});
|
|
49
|
+
telemetry.send('catalog_filter_changed', { type: 'toggle' });
|
|
48
50
|
window.scrollTo(0, 0);
|
|
49
51
|
}, []);
|
|
50
52
|
|
|
@@ -68,6 +70,7 @@ export function useCatalog(items: ResolvedNavItem[], config: CatalogConfig): Fil
|
|
|
68
70
|
: f,
|
|
69
71
|
);
|
|
70
72
|
});
|
|
73
|
+
telemetry.send('catalog_filter_changed', { type: 'select' });
|
|
71
74
|
window.scrollTo(0, 0);
|
|
72
75
|
},
|
|
73
76
|
[filtersWithOptions],
|
|
@@ -153,7 +156,16 @@ export function useCatalog(items: ResolvedNavItem[], config: CatalogConfig): Fil
|
|
|
153
156
|
? groupByFirstFilter(resolvedFilters, filteredItems)
|
|
154
157
|
: [{ title: 'APIs', items: filteredItems }];
|
|
155
158
|
|
|
156
|
-
return {
|
|
159
|
+
return {
|
|
160
|
+
groups,
|
|
161
|
+
filters: resolvedFilters,
|
|
162
|
+
setFilterTerm: (newTerm) => {
|
|
163
|
+
setFilterTerm(newTerm);
|
|
164
|
+
|
|
165
|
+
telemetry.send('catalog_filter_changed', { type: 'term' });
|
|
166
|
+
},
|
|
167
|
+
filterTerm,
|
|
168
|
+
};
|
|
157
169
|
}, [
|
|
158
170
|
filtersWithOptions,
|
|
159
171
|
normalizedItems,
|
|
@@ -4,6 +4,7 @@ import styled from 'styled-components';
|
|
|
4
4
|
import { CodeBlockControlButton } from '@theme/components/CodeBlock';
|
|
5
5
|
import { CollapseIcon, DeselectIcon, ExpandIcon, ReportIcon, SelectIcon } from '@theme/icons';
|
|
6
6
|
import { useThemeConfig } from '@theme/hooks';
|
|
7
|
+
import { telemetry } from '@portal/telemetry';
|
|
7
8
|
|
|
8
9
|
import { CopyButton } from '../CopyButton';
|
|
9
10
|
|
|
@@ -68,7 +69,10 @@ export function CodeBlockControls({
|
|
|
68
69
|
toasterDuration={copy.toasterDuration}
|
|
69
70
|
buttonText={copy.label}
|
|
70
71
|
tooltipText={copy.tooltipText}
|
|
71
|
-
onCopyClick={
|
|
72
|
+
onCopyClick={() => {
|
|
73
|
+
copy?.onClick;
|
|
74
|
+
telemetry.send('code_snippet_copied', {});
|
|
75
|
+
}}
|
|
72
76
|
/>
|
|
73
77
|
) : null}
|
|
74
78
|
|
|
@@ -139,6 +143,7 @@ export function CodeBlockControls({
|
|
|
139
143
|
asIcon={controlsType === 'icon'}
|
|
140
144
|
title={report.tooltipText}
|
|
141
145
|
{...report.props}
|
|
146
|
+
onClick={() => telemetry.send('code_snippet_reported', {})}
|
|
142
147
|
>
|
|
143
148
|
{controlsType === 'icon' ? <ReportIcon /> : report.props?.buttonText || 'Report'}
|
|
144
149
|
</CodeBlockControlButton>
|
|
@@ -3,6 +3,7 @@ import styled from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import { ColorModeIcon } from '@theme/icons/ColorModeIcon';
|
|
5
5
|
import { useMount, useThemeConfig } from '@theme/hooks';
|
|
6
|
+
import { telemetry } from '@portal/telemetry';
|
|
6
7
|
|
|
7
8
|
interface ColorModeSwitcherProps {
|
|
8
9
|
className?: string;
|
|
@@ -34,6 +35,8 @@ export function ColorModeSwitcher(props: ColorModeSwitcherProps): JSX.Element |
|
|
|
34
35
|
window.requestAnimationFrame(() => {
|
|
35
36
|
document.documentElement.classList.remove('notransition');
|
|
36
37
|
});
|
|
38
|
+
|
|
39
|
+
telemetry.send('color_mode_switched', { from: activeColorMode, to: mode });
|
|
37
40
|
};
|
|
38
41
|
|
|
39
42
|
return (
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import { Link } from '@portal/Link';
|
|
5
|
+
import { telemetry } from '@portal/telemetry';
|
|
5
6
|
|
|
6
7
|
export interface EditPageButtonProps {
|
|
7
8
|
text: string;
|
|
@@ -11,7 +12,7 @@ export interface EditPageButtonProps {
|
|
|
11
12
|
|
|
12
13
|
export const EditPageButton = ({ text, to, icon }: EditPageButtonProps): JSX.Element => {
|
|
13
14
|
return (
|
|
14
|
-
<EditButton to={to}>
|
|
15
|
+
<EditButton to={to} onClick={() => telemetry.send('edit_page_link_clicked', {})}>
|
|
15
16
|
{icon ? <ButtonIcon src={icon} /> : null}
|
|
16
17
|
<ButtonText>{text}</ButtonText>
|
|
17
18
|
</EditButton>
|
|
@@ -6,6 +6,7 @@ import type { FeedbackProps } from '@theme/types/portal/src/shared/types/feedbac
|
|
|
6
6
|
import { Rating, Sentiment, Comment } from '@theme/components/Feedback';
|
|
7
7
|
import { useThemeConfig } from '@theme/hooks';
|
|
8
8
|
import { useSubmitFeedback } from '@portal/Feedback/useSubmitFeedback';
|
|
9
|
+
import { telemetry } from '@portal/telemetry';
|
|
9
10
|
|
|
10
11
|
export const Feedback = (props: FeedbackProps & { path?: string }) => {
|
|
11
12
|
const { submitFeedback } = useSubmitFeedback();
|
|
@@ -20,7 +21,10 @@ export const Feedback = (props: FeedbackProps & { path?: string }) => {
|
|
|
20
21
|
<Wrapper>
|
|
21
22
|
<Rating
|
|
22
23
|
settings={settings}
|
|
23
|
-
onSubmit={(values) =>
|
|
24
|
+
onSubmit={(values) => {
|
|
25
|
+
submitFeedback({ type: 'rating', values, path });
|
|
26
|
+
telemetry.send('feedback_sent', { type: 'rating' });
|
|
27
|
+
}}
|
|
24
28
|
/>
|
|
25
29
|
</Wrapper>
|
|
26
30
|
);
|
|
@@ -29,7 +33,10 @@ export const Feedback = (props: FeedbackProps & { path?: string }) => {
|
|
|
29
33
|
<Wrapper>
|
|
30
34
|
<Sentiment
|
|
31
35
|
settings={settings}
|
|
32
|
-
onSubmit={(values) =>
|
|
36
|
+
onSubmit={(values) => {
|
|
37
|
+
submitFeedback({ type: 'sentiment', values, path });
|
|
38
|
+
telemetry.send('feedback_sent', { type: 'sentiment' });
|
|
39
|
+
}}
|
|
33
40
|
/>
|
|
34
41
|
</Wrapper>
|
|
35
42
|
);
|
|
@@ -38,7 +45,10 @@ export const Feedback = (props: FeedbackProps & { path?: string }) => {
|
|
|
38
45
|
<Wrapper>
|
|
39
46
|
<Comment
|
|
40
47
|
settings={settings}
|
|
41
|
-
onSubmit={(values) =>
|
|
48
|
+
onSubmit={(values) => {
|
|
49
|
+
submitFeedback({ type: 'comment', values, path });
|
|
50
|
+
telemetry.send('feedback_sent', { type: 'comment' });
|
|
51
|
+
}}
|
|
42
52
|
/>
|
|
43
53
|
</Wrapper>
|
|
44
54
|
);
|
|
@@ -69,10 +69,18 @@ export const Sentiment = ({ settings, onSubmit, className }: SentimentProps): JS
|
|
|
69
69
|
<Label data-translation-key={translationKeys.label}>
|
|
70
70
|
{translate(translationKeys.label, label || 'Was this page helpful?')}
|
|
71
71
|
</Label>
|
|
72
|
-
<Vote
|
|
72
|
+
<Vote
|
|
73
|
+
onClick={() => {
|
|
74
|
+
setScore(1);
|
|
75
|
+
}}
|
|
76
|
+
>
|
|
73
77
|
<ThumbUp text="Yes" />
|
|
74
78
|
</Vote>
|
|
75
|
-
<Vote
|
|
79
|
+
<Vote
|
|
80
|
+
onClick={() => {
|
|
81
|
+
setScore(-1);
|
|
82
|
+
}}
|
|
83
|
+
>
|
|
76
84
|
<ThumbDown />
|
|
77
85
|
</Vote>
|
|
78
86
|
</Wrapper>
|
|
@@ -4,6 +4,7 @@ import styled, { css } from 'styled-components';
|
|
|
4
4
|
import { Link } from '@portal/Link';
|
|
5
5
|
import type { ResolvedNavItem } from '@theme/types/portal';
|
|
6
6
|
import { useTranslate } from '@portal/hooks';
|
|
7
|
+
import { telemetry } from '@portal/telemetry';
|
|
7
8
|
|
|
8
9
|
interface FooterColumnProps {
|
|
9
10
|
column: ResolvedNavItem;
|
|
@@ -35,6 +36,7 @@ export function FooterColumn({ column, className }: FooterColumnProps): JSX.Elem
|
|
|
35
36
|
external={columnItem.external}
|
|
36
37
|
target={columnItem.target}
|
|
37
38
|
data-cy={columnItem.label}
|
|
39
|
+
onClick={() => telemetry.send('footer_item_clicked', {})}
|
|
38
40
|
>
|
|
39
41
|
<FooterLinkIcon url={columnItem.icon} withIconPadding={hasIcon} />
|
|
40
42
|
{translate(columnItem.labelTranslationKey, columnItem.label)}
|
|
@@ -3,6 +3,7 @@ import styled from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import { MenuLink } from '@theme/components/Menu/MenuLink';
|
|
5
5
|
import type { MenuItemProps } from '@theme/components/Sidebar/types';
|
|
6
|
+
import { telemetry } from '@portal/telemetry';
|
|
6
7
|
|
|
7
8
|
export function MenuLinkItem({
|
|
8
9
|
item,
|
|
@@ -10,7 +11,11 @@ export function MenuLinkItem({
|
|
|
10
11
|
className,
|
|
11
12
|
}: React.PropsWithChildren<MenuItemProps>): JSX.Element {
|
|
12
13
|
return (
|
|
13
|
-
<Wrapper
|
|
14
|
+
<Wrapper
|
|
15
|
+
data-component-name="Sidebar/MenuLinkItem"
|
|
16
|
+
className={className}
|
|
17
|
+
onClick={() => telemetry.send('sidebar_item_clicked', { label: item.label, type: item.type })}
|
|
18
|
+
>
|
|
14
19
|
{item.link ? (
|
|
15
20
|
<MenuLink to={item.link} {...item}>
|
|
16
21
|
{children}
|
|
@@ -6,6 +6,7 @@ import { LogoutIcon } from '@theme/icons/LogoutIcon';
|
|
|
6
6
|
import { AvatarWrapper, ProfileWrapper, Profile } from '@theme/components/Profile/Profile';
|
|
7
7
|
import { useThemeConfig } from '@theme/hooks/useThemeConfig';
|
|
8
8
|
import { useTranslate } from '@portal/hooks';
|
|
9
|
+
import { telemetry } from '@portal/telemetry';
|
|
9
10
|
|
|
10
11
|
export function MobileUserProfile() {
|
|
11
12
|
const { userProfile } = useThemeConfig();
|
|
@@ -20,7 +21,11 @@ export function MobileUserProfile() {
|
|
|
20
21
|
return (
|
|
21
22
|
<MobileProfileWrapper data-component-name="Navbar/MobileUserProfile">
|
|
22
23
|
{!userData?.isAuthenticated ? (
|
|
23
|
-
<LoginButton
|
|
24
|
+
<LoginButton
|
|
25
|
+
href={loginUrl}
|
|
26
|
+
data-cy="login-btn"
|
|
27
|
+
onClick={() => telemetry.send('login_button_clicked', {})}
|
|
28
|
+
>
|
|
24
29
|
{translate(translationKeys.login, userProfile?.loginLabel || 'Login')}
|
|
25
30
|
</LoginButton>
|
|
26
31
|
) : (
|
|
@@ -31,7 +36,12 @@ export function MobileUserProfile() {
|
|
|
31
36
|
</ProfilePicture>
|
|
32
37
|
<UserName>{userData.name}</UserName>
|
|
33
38
|
</UserDataWrapper>
|
|
34
|
-
<LogoutButton
|
|
39
|
+
<LogoutButton
|
|
40
|
+
onClick={() => {
|
|
41
|
+
handleLogout();
|
|
42
|
+
telemetry.send('logout_menu_item_clicked', {});
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
35
45
|
<LogoutIcon />
|
|
36
46
|
</LogoutButton>
|
|
37
47
|
</>
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
} from '@theme/types/portal';
|
|
12
12
|
import { useI18nConfig, useTranslate } from '@portal/hooks';
|
|
13
13
|
import { withPathPrefix } from '@theme/utils';
|
|
14
|
+
import { telemetry } from '@portal/telemetry';
|
|
14
15
|
import { Dropdown } from '@theme/components/Dropdown';
|
|
15
16
|
|
|
16
17
|
export interface NavbarItemProps {
|
|
@@ -34,6 +35,7 @@ export function NavbarItem({ navItem, className }: NavbarItemProps): JSX.Element
|
|
|
34
35
|
active={isActive}
|
|
35
36
|
data-component-name="Navbar/NavbarItem"
|
|
36
37
|
className={className}
|
|
38
|
+
onClick={() => telemetry.send('navbar_menu_item_clicked', { type: 'link' })}
|
|
37
39
|
>
|
|
38
40
|
<NavbarLink to={item.link} external={item.external} target={item.target} active={isActive}>
|
|
39
41
|
{item.icon ? <NavbarIcon url={item.icon} /> : null}
|
|
@@ -58,6 +60,7 @@ export function NavbarItem({ navItem, className }: NavbarItemProps): JSX.Element
|
|
|
58
60
|
active={false}
|
|
59
61
|
data-component-name="Navbar/NavbarItem"
|
|
60
62
|
className={className}
|
|
63
|
+
onClick={() => telemetry.send('navbar_menu_item_clicked', { type: 'group' })}
|
|
61
64
|
>
|
|
62
65
|
<NavbarIcon url={item.icon} />
|
|
63
66
|
<NavbarLabel>{translate(item.labelTranslationKey, item.label)}</NavbarLabel>
|
|
@@ -3,6 +3,7 @@ import styled from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import { Link } from '@portal/Link';
|
|
5
5
|
import type { LogoConfig } from '@theme/types/portal';
|
|
6
|
+
import { telemetry } from '@portal/telemetry';
|
|
6
7
|
|
|
7
8
|
export type NavbarLogoProps = {
|
|
8
9
|
logo: Pick<LogoConfig, 'image' | 'link' | 'altText'>;
|
|
@@ -19,6 +20,7 @@ export function NavbarLogo({ logo, className }: NavbarLogoProps): JSX.Element |
|
|
|
19
20
|
src={logo.image}
|
|
20
21
|
alt={logo.altText}
|
|
21
22
|
data-component-name="NavbarLogo/NavbarLogo"
|
|
23
|
+
onClick={() => telemetry.send('logo_clicked', {})}
|
|
22
24
|
/>
|
|
23
25
|
);
|
|
24
26
|
return logo.link ? <Link to={logo.link}>{img}</Link> : img;
|
|
@@ -3,6 +3,7 @@ import styled from 'styled-components';
|
|
|
3
3
|
|
|
4
4
|
import { useThemeConfig } from '@theme/hooks/useThemeConfig';
|
|
5
5
|
import { useTranslate } from '@portal/hooks';
|
|
6
|
+
import { telemetry } from '@portal/telemetry';
|
|
6
7
|
|
|
7
8
|
export interface LoginLinkProps {
|
|
8
9
|
href: string;
|
|
@@ -16,7 +17,13 @@ export function LoginLink({ href }: LoginLinkProps): JSX.Element {
|
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
return (
|
|
19
|
-
<StyledLink
|
|
20
|
+
<StyledLink
|
|
21
|
+
href={href}
|
|
22
|
+
data-translation-key={translationKeys.login}
|
|
23
|
+
onClick={() => {
|
|
24
|
+
telemetry.send('login_button_clicked', {});
|
|
25
|
+
}}
|
|
26
|
+
>
|
|
20
27
|
{translate(translationKeys.login, userProfile?.loginLabel || 'Login')}
|
|
21
28
|
</StyledLink>
|
|
22
29
|
);
|
|
@@ -7,6 +7,7 @@ import { Profile } from '@theme/components/Profile/Profile';
|
|
|
7
7
|
import { Link } from '@portal/Link';
|
|
8
8
|
import { useThemeConfig } from '@theme/hooks/useThemeConfig';
|
|
9
9
|
import { useTranslate } from '@portal/hooks';
|
|
10
|
+
import { telemetry } from '@portal/telemetry';
|
|
10
11
|
import { Dropdown, DropdownList, DropdownListItem } from '@theme/components/Dropdown';
|
|
11
12
|
|
|
12
13
|
export function UserProfile({
|
|
@@ -49,7 +50,10 @@ export function UserProfile({
|
|
|
49
50
|
|
|
50
51
|
menuItems.push(
|
|
51
52
|
<Logout
|
|
52
|
-
onClick={() =>
|
|
53
|
+
onClick={() => {
|
|
54
|
+
handleLogout();
|
|
55
|
+
telemetry.send('logout_menu_item_clicked', {});
|
|
56
|
+
}}
|
|
53
57
|
data-translation-key={translationKeys.logout}
|
|
54
58
|
role="link"
|
|
55
59
|
>
|
|
@@ -37,35 +37,30 @@ export function SearchItem({ item, className, product }: SearchItemProps): JSX.E
|
|
|
37
37
|
</Wrapper>
|
|
38
38
|
);
|
|
39
39
|
|
|
40
|
+
const itemParam = item.parameters?.[0];
|
|
41
|
+
|
|
40
42
|
return (
|
|
41
43
|
<>
|
|
42
|
-
{
|
|
43
|
-
|
|
44
|
-
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
</div>
|
|
63
|
-
<div>{highlight(param.description)}</div>
|
|
64
|
-
</Place>
|
|
65
|
-
</SearchLink>
|
|
66
|
-
);
|
|
67
|
-
})}
|
|
68
|
-
</>
|
|
44
|
+
{itemParam ? (
|
|
45
|
+
<SearchLink
|
|
46
|
+
className={className}
|
|
47
|
+
key={`${item.id}-${0}`}
|
|
48
|
+
to={item.url}
|
|
49
|
+
tabIndex={0}
|
|
50
|
+
innerRef={ref}
|
|
51
|
+
data-component-name="Search/SearchItem"
|
|
52
|
+
>
|
|
53
|
+
{header}
|
|
54
|
+
<Place>
|
|
55
|
+
<div>
|
|
56
|
+
{`${itemParam.place} → ${
|
|
57
|
+
itemParam.path?.length ? itemParam.path?.join(' → ') + ' → ' : ''
|
|
58
|
+
}`}
|
|
59
|
+
{highlight(itemParam.name)}
|
|
60
|
+
</div>
|
|
61
|
+
<div>{highlight(itemParam.description)}</div>
|
|
62
|
+
</Place>
|
|
63
|
+
</SearchLink>
|
|
69
64
|
) : (
|
|
70
65
|
<SearchLink
|
|
71
66
|
className={className}
|
|
@@ -9,6 +9,7 @@ import { MobileSidebarButton } from '@theme/components/Sidebar/MobileSidebarButt
|
|
|
9
9
|
import { MenuContainer } from '@theme/components/Menu/MenuContainer';
|
|
10
10
|
import { SidebarSearch } from '@theme/components/Search/SidebarSearch';
|
|
11
11
|
import { useThemeConfig } from '@theme/hooks/useThemeConfig';
|
|
12
|
+
import { telemetry } from '@portal/telemetry';
|
|
12
13
|
|
|
13
14
|
import { MobileSidebarIcon } from './MobileSidebarIcon';
|
|
14
15
|
|
|
@@ -81,7 +82,11 @@ export function SidebarLayout({
|
|
|
81
82
|
<Wrapper data-component-name="Sidebar/SidebarLayout" className={className}>
|
|
82
83
|
{!search?.hide && search?.placement === 'sidebar' ? <SidebarSearch /> : null}
|
|
83
84
|
<Sidebar animate={true} opened={isOpen}>
|
|
84
|
-
{header ?
|
|
85
|
+
{header ? (
|
|
86
|
+
<HeaderWrapper onClick={() => telemetry.send('back_to_catalog_button_clicked', {})}>
|
|
87
|
+
{header}
|
|
88
|
+
</HeaderWrapper>
|
|
89
|
+
) : null}
|
|
85
90
|
{versions ? <>{versions}</> : null}
|
|
86
91
|
<MenuContainer growContent={growContent}>{menu}</MenuContainer>
|
|
87
92
|
{footer && !isOpen ? (
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
ControlsWrap,
|
|
8
8
|
ControlsWrapChangeLayoutButtons,
|
|
9
9
|
} from '@theme/components/SidebarActions/styled';
|
|
10
|
+
import { telemetry } from '@portal/telemetry';
|
|
10
11
|
|
|
11
12
|
export enum LayoutVariant {
|
|
12
13
|
STACKED = 'stacked',
|
|
@@ -54,11 +55,20 @@ export const SidebarActions = ({
|
|
|
54
55
|
{initialShowRightPanelToggle && (
|
|
55
56
|
<ToggleRightPanelButton
|
|
56
57
|
showRightPanelToggle={showRightPanelToggle}
|
|
57
|
-
onClick={
|
|
58
|
+
onClick={() => {
|
|
59
|
+
onChangeRightPanelViewClick();
|
|
60
|
+
telemetry.send('sidebar_samples_button_clicked', {});
|
|
61
|
+
}}
|
|
58
62
|
/>
|
|
59
63
|
)}
|
|
60
64
|
{showChangeLayoutButton && showRightPanelToggle && (
|
|
61
|
-
<ChangeViewButton
|
|
65
|
+
<ChangeViewButton
|
|
66
|
+
layout={layout}
|
|
67
|
+
onClick={() => {
|
|
68
|
+
onChangeViewClick();
|
|
69
|
+
telemetry.send('change_layout_button_clicked', {});
|
|
70
|
+
}}
|
|
71
|
+
/>
|
|
62
72
|
)}
|
|
63
73
|
</ControlsWrapChangeLayoutButtons>
|
|
64
74
|
)}
|
|
@@ -66,7 +76,12 @@ export const SidebarActions = ({
|
|
|
66
76
|
{!hideCollapseSidebarButton && (
|
|
67
77
|
<CollapseSidebarButton
|
|
68
78
|
initialValue={collapsedSidebar}
|
|
69
|
-
onClick={
|
|
79
|
+
onClick={() => {
|
|
80
|
+
onChangeCollapseSidebarClick();
|
|
81
|
+
collapsedSidebar
|
|
82
|
+
? telemetry.send('sidebar_item_expanded', {})
|
|
83
|
+
: telemetry.send('sidebar_item_collapsed', {});
|
|
84
|
+
}}
|
|
70
85
|
/>
|
|
71
86
|
)}
|
|
72
87
|
</ControlsWrap>
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
getDisplayedHeadings,
|
|
12
12
|
getLeastDepth,
|
|
13
13
|
} from '@theme/components/TableOfContent/utils';
|
|
14
|
+
import { telemetry } from '@portal/telemetry';
|
|
14
15
|
|
|
15
16
|
interface TableOfContentProps {
|
|
16
17
|
headings?: Array<MdHeading | null> | null | undefined;
|
|
@@ -64,6 +65,7 @@ export function TableOfContent(props: TableOfContentProps): JSX.Element | null {
|
|
|
64
65
|
className={activeHeadingId === heading.id ? 'active' : ''}
|
|
65
66
|
dangerouslySetInnerHTML={{ __html: heading.value || '' }}
|
|
66
67
|
data-cy={`toc-${heading.value}`}
|
|
68
|
+
onClick={() => telemetry.send('toc_item_clicked', {})}
|
|
67
69
|
/>
|
|
68
70
|
);
|
|
69
71
|
})}
|
package/src/config.ts
CHANGED
|
@@ -362,7 +362,7 @@ const scorecardConfigSchema = {
|
|
|
362
362
|
const catalogSchema = {
|
|
363
363
|
type: 'object',
|
|
364
364
|
additionalProperties: true,
|
|
365
|
-
required: ['slug', 'filters', '
|
|
365
|
+
required: ['slug', 'filters', 'items'],
|
|
366
366
|
properties: {
|
|
367
367
|
slug: { type: 'string' },
|
|
368
368
|
filters: { type: 'array', items: catalogFilterSchema },
|