Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions src/components/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { AppRootProps } from '@grafana/data';
import React, { useMemo, useEffect } from 'react';
import { SceneApp } from '@grafana/scenes';
import { docsPage } from '../../pages/docsPage';
import { ContextPanelComponent } from '../../utils/docs.utils';
import { PluginPropsContext } from '../../utils/utils.plugin';
import { getConfigWithDefaults } from '../../constants';

Expand All @@ -12,10 +11,6 @@ function getSceneApp() {
});
}

export function MemoizedContextPanel() {
return <ContextPanelComponent />;
}

function App(props: AppRootProps) {
const scene = useMemo(() => getSceneApp(), []);

Expand Down
14 changes: 14 additions & 0 deletions src/components/App/ContextPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React, { useMemo } from "react";
import { NavModelItem, usePluginContext } from "@grafana/data";
import { CombinedLearningJourneyPanel } from "components/docs-panel/docs-panel";
import { getConfigWithDefaults } from '../../constants';

export default function MemoizedContextPanel({ helpNode }: { helpNode?: NavModelItem }) {
const pluginContext = usePluginContext();
const config = getConfigWithDefaults(pluginContext?.meta?.jsonData || {});
const panel = useMemo(() => new CombinedLearningJourneyPanel(config, helpNode), [config, helpNode]);

return (
<panel.Component model={panel} />
);
}

Check failure on line 14 in src/components/App/ContextPanel.tsx

View workflow job for this annotation

GitHub Actions / Build, lint and unit tests

Newline required at end of file but not found

Check failure on line 14 in src/components/App/ContextPanel.tsx

View workflow job for this annotation

GitHub Actions / CI / CD / CI / Test and build plugin

Newline required at end of file but not found
33 changes: 29 additions & 4 deletions src/components/HelpFooter/HelpFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
import { Icon, useTheme2, Modal } from '@grafana/ui';
import { config } from '@grafana/runtime';
import { t } from '@grafana/i18n';
import { NavModelItem } from '@grafana/data';
import { getHelpFooterStyles } from '../../styles/help-footer.styles';

interface HelpFooterProps {
className?: string;
helpNode?: NavModelItem;
}

export const HelpFooter: React.FC<HelpFooterProps> = ({ className }) => {
export const HelpFooter: React.FC<HelpFooterProps> = ({ className, helpNode }) => {
const theme = useTheme2();
const styles = getHelpFooterStyles(theme);
const [isHelpModalOpen, setIsHelpModalOpen] = useState(false);
Expand All @@ -21,45 +23,68 @@
setIsHelpModalOpen(false);
};

const helpButtons = [
// Used when helpNode isn't provided.
const defaultHelpButtons = [
{
key: 'documentation',
label: t('helpFooter.buttons.documentation', 'Documentation'),
icon: 'file-alt' as const,
href: 'https://grafana.com/docs/grafana/latest/?utm_source=grafana_footer',
target: '_blank',
},
{
key: 'support',
label: t('helpFooter.buttons.support', 'Support'),
icon: 'question-circle' as const,
href: 'https://grafana.com/support/?utm_source=grafana_footer',
target: '_blank',
},
{
key: 'community',
label: t('helpFooter.buttons.community', 'Community'),
icon: 'comments-alt' as const,
href: 'https://community.grafana.com/?utm_source=grafana_footer',
target: '_blank',
},
{
key: 'enterprise',
label: t('helpFooter.buttons.enterprise', 'Enterprise'),
icon: 'external-link-alt' as const,
href: 'https://grafana.com/products/enterprise/?utm_source=grafana_footer',
target: '_blank',
},
{
key: 'download',
label: t('helpFooter.buttons.download', 'Download'),
icon: 'download-alt' as const,
href: 'https://grafana.com/grafana/download?utm_source=grafana_footer',
},
target: '_blank',
},
{
key: 'shortcuts',
label: t('helpFooter.buttons.shortcuts', 'Shortcuts'),
icon: 'keyboard' as const,
onClick: handleKeyboardShortcuts,
target: '_blank',
},
];

const helpButtons = React.useMemo(() => {
if (helpNode?.children && helpNode.children.length > 0) {
return helpNode.children
.filter((child) => child.text && (child.url || child.onClick))
.map((child, index) => ({
key: child.id || `help-${index}`,
label: child.text || '',
icon: (child.icon || 'question-circle') as any,
href: child.url,
target: child.target,
onClick: child.onClick,
}));
}
return defaultHelpButtons;
}, [helpNode]);

Check failure on line 86 in src/components/HelpFooter/HelpFooter.tsx

View workflow job for this annotation

GitHub Actions / Build, lint and unit tests

React Hook React.useMemo has a missing dependency: 'defaultHelpButtons'. Either include it or remove the dependency array

Check failure on line 86 in src/components/HelpFooter/HelpFooter.tsx

View workflow job for this annotation

GitHub Actions / CI / CD / CI / Test and build plugin

React Hook React.useMemo has a missing dependency: 'defaultHelpButtons'. Either include it or remove the dependency array

return (
<div className={`${styles.helpFooter} ${className || ''}`}>
<div className={styles.helpButtons}>
Expand All @@ -68,7 +93,7 @@
const buttonProps = button.href
? {
href: button.href,
target: '_blank',
target: button.target || '_blank',
rel: 'noopener noreferrer',
}
: {
Expand Down
11 changes: 7 additions & 4 deletions src/components/docs-panel/context-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';

import { SceneComponentProps, SceneObjectBase, SceneObjectState } from '@grafana/scenes';
import { Icon, useStyles2, Card } from '@grafana/ui';
import { usePluginContext } from '@grafana/data';
import { usePluginContext, NavModelItem } from '@grafana/data';
import { t } from '@grafana/i18n';
import logoSvg from '../../img/logo.svg';
import { SkeletonLoader } from '../SkeletonLoader';
Expand All @@ -20,6 +20,7 @@ import { getConfigWithDefaults } from '../../constants';
interface ContextPanelState extends SceneObjectState {
onOpenLearningJourney?: (url: string, title: string) => void;
onOpenDocsPage?: (url: string, title: string) => void;
helpNode?: NavModelItem;
}

export class ContextPanel extends SceneObjectBase<ContextPanelState> {
Expand All @@ -31,11 +32,13 @@ export class ContextPanel extends SceneObjectBase<ContextPanelState> {

public constructor(
onOpenLearningJourney?: (url: string, title: string) => void,
onOpenDocsPage?: (url: string, title: string) => void
onOpenDocsPage?: (url: string, title: string) => void,
helpNode?: NavModelItem
) {
super({
onOpenLearningJourney,
onOpenDocsPage,
helpNode,
});
}

Expand Down Expand Up @@ -410,8 +413,8 @@ function ContextPanelRenderer({ model }: SceneComponentProps<ContextPanel>) {
</div>
)}

{/* Help Footer */}
<HelpFooter />
{/* Help Footer - now receives helpNode */}
<HelpFooter helpNode={model.state.helpNode} />
</div>
</div>
);
Expand Down
7 changes: 4 additions & 3 deletions src/components/docs-panel/docs-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import React, { useState, useEffect, useRef, useCallback } from 'react';
import { SceneObjectBase, SceneObjectState, SceneComponentProps } from '@grafana/scenes';
import { IconButton, Alert, Icon, useStyles2 } from '@grafana/ui';
import { GrafanaTheme2 } from '@grafana/data';
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
import { t } from '@grafana/i18n';
import { getConfigWithDefaults, DocsPluginConfig } from '../../constants';

Expand Down Expand Up @@ -77,11 +77,12 @@ class CombinedLearningJourneyPanel extends SceneObjectBase<CombinedPanelState> {
return true;
}

public constructor(pluginConfig: DocsPluginConfig = {}) {
public constructor(pluginConfig: DocsPluginConfig = {}, helpNode?: NavModelItem) {
const restoredTabs = CombinedLearningJourneyPanel.restoreTabsFromStorage();
const contextPanel = new ContextPanel(
(url: string, title: string) => this.openLearningJourney(url, title),
(url: string, title: string) => this.openDocsPage(url, title)
(url: string, title: string) => this.openDocsPage(url, title),
helpNode
);

const activeTabId = CombinedLearningJourneyPanel.restoreActiveTabFromStorage(restoredTabs);
Expand Down
69 changes: 56 additions & 13 deletions src/module.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AppPlugin, type AppRootProps, PluginExtensionPoints, BusEventWithPayload } from '@grafana/data';
import { AppPlugin, type AppRootProps, BusEventWithPayload, NavModelItem } from '@grafana/data';
import { LoadingPlaceholder } from '@grafana/ui';
import { getAppEvents } from '@grafana/runtime';
import React, { Suspense, lazy } from 'react';
Expand Down Expand Up @@ -29,9 +29,7 @@
}

const LazyApp = lazy(() => import('./components/App/App'));
const LazyMemoizedContextPanel = lazy(() =>
import('./components/App/App').then((module) => ({ default: module.MemoizedContextPanel }))
);
const LazyMemoizedContextPanel = lazy(() => import('./components/App/ContextPanel'));
const LazyAppConfig = lazy(() => import('./components/AppConfig/AppConfig'));
const LazyTermsAndConditions = lazy(() => import('./components/AppConfig/TermsAndConditions'));

Expand All @@ -41,7 +39,7 @@
</Suspense>
);

const plugin = new AppPlugin<{}>()
export const plugin = new AppPlugin<{}>()
.setRootPage(App)
.addConfigPage({
title: 'Configuration',
Expand All @@ -54,13 +52,12 @@
id: 'recommendations-config',
});

export { plugin };

// Expose the main component for the sidebar
plugin.addComponent({
targets: `grafana/extension-sidebar/v0-alpha`,
title: 'Grafana Pathfinder',
description: 'Opens Grafana Pathfinder',
component: function ContextSidebar() {
component: function ContextSidebar(props: { helpNode?: NavModelItem }) {
React.useEffect(() => {
reportAppInteraction(UserInteraction.DocsPanelInteraction, {
action: 'open',
Expand All @@ -79,7 +76,53 @@

return (
<Suspense fallback={<LoadingPlaceholder text="" />}>
<LazyMemoizedContextPanel />
<LazyMemoizedContextPanel helpNode={props.helpNode} />
</Suspense>
);
},
});

plugin.addLink<{ helpNode?: NavModelItem }>({
title: 'Grafana Pathfinder',
description: 'Open Grafana Pathfinder documentation assistant',
targets: ['grafana/app/topbar/help/v1'],
onClick: (_, {openSidebar, context}) => {
reportAppInteraction(UserInteraction.DocsPanelInteraction, {
action: 'open',
source: 'help_button',
timestamp: Date.now(),
});

openSidebar('Grafana Pathfinder', {
helpNode: context?.helpNode,
});
},
});

plugin.exposeComponent({
id: 'grafana-grafanadocsplugin-app/pathfinder-help/v1',
title: 'Grafana Pathfinder',
description: 'Grafana Pathfinder documentation assistant',
component: function PathfinderHelpSidebar(props: { helpNode?: NavModelItem }) {
React.useEffect(() => {
reportAppInteraction(UserInteraction.DocsPanelInteraction, {
action: 'open',
source: 'help_button_sidebar',
timestamp: Date.now(),
});

return () => {
reportAppInteraction(UserInteraction.DocsPanelInteraction, {
action: 'close',
source: 'help_button_sidebar_unmount',
timestamp: Date.now(),
});
};
}, []);

return (
<Suspense fallback={<LoadingPlaceholder text="" />}>
<LazyMemoizedContextPanel helpNode={props.helpNode} />
</Suspense>
);
},
Expand All @@ -88,7 +131,7 @@
plugin.addLink({
title: 'Open Grafana Pathfinder',
description: 'Open Grafana Pathfinder',
targets: [PluginExtensionPoints.CommandPalette],
targets: ['grafana/commandpalette/action'],
onClick: () => {
reportAppInteraction(UserInteraction.DocsPanelInteraction, {
action: 'open',
Expand All @@ -106,7 +149,7 @@
plugin.addLink({
title: 'Need help?',
description: 'Get help with Grafana',
targets: [PluginExtensionPoints.CommandPalette],
targets: ['grafana/commandpalette/action'],
onClick: () => {
reportAppInteraction(UserInteraction.DocsPanelInteraction, {
action: 'open',
Expand All @@ -124,7 +167,7 @@
plugin.addLink({
title: 'Learn Grafana',
description: 'Learn how to use Grafana',
targets: [PluginExtensionPoints.CommandPalette],
targets: ['grafana/commandpalette/action'],
onClick: () => {
reportAppInteraction(UserInteraction.DocsPanelInteraction, {
action: 'open',
Expand All @@ -151,4 +194,4 @@
};
},
onClick: () => {},
});
});

Check failure on line 197 in src/module.tsx

View workflow job for this annotation

GitHub Actions / Build, lint and unit tests

Newline required at end of file but not found

Check failure on line 197 in src/module.tsx

View workflow job for this annotation

GitHub Actions / CI / CD / CI / Test and build plugin

Newline required at end of file but not found
12 changes: 12 additions & 0 deletions src/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,24 @@
"title": "Grafana Pathfinder"
}
],
"exposedComponents": [
{
"id": "grafana-grafanadocsplugin-app/pathfinder-help/v1",
"title": "Grafana Pathfinder",
"description": "Grafana Pathfinder documentation assistant"
}
],
"addedLinks": [
{
"targets": ["grafana/extension-sidebar/v0-alpha"],
"description": "Opens Grafana Pathfinder",
"title": "Documentation-Link"
},
{
"targets": ["grafana/app/topbar/help/v1"],
"description": "Open Grafana Pathfinder documentation assistant",
"title": "Grafana Pathfinder"
},
{
"targets": ["grafana/commandpalette/action"],
"description": "Open Grafana Pathfinder",
Expand Down
8 changes: 4 additions & 4 deletions src/styles/content-html.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1268,8 +1268,8 @@ const getSharedUtilityStyles = (theme: GrafanaTheme2) => ({
margin: 0,
marginBottom: theme.spacing(0.75),
display: '-webkit-box',
'-webkit-line-clamp': '2',
'-webkit-box-orient': 'vertical',
WebkitLineClamp: '2',
WebkitBoxOrient: 'vertical',
overflow: 'hidden',
width: '100%',
},
Expand All @@ -1281,8 +1281,8 @@ const getSharedUtilityStyles = (theme: GrafanaTheme2) => ({
margin: 0,
flex: 1,
display: '-webkit-box',
'-webkit-line-clamp': '3',
'-webkit-box-orient': 'vertical',
WebkitLineClamp: '3',
WebkitBoxOrient: 'vertical',
overflow: 'hidden',
width: '100%',
},
Expand Down
4 changes: 2 additions & 2 deletions src/styles/context-panel.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ export const getRecommendationCardStyles = (theme: GrafanaTheme2) => ({
minWidth: 0,
maxWidth: 'calc(100% - 100px)',
display: '-webkit-box',
'-webkit-line-clamp': '2',
'-webkit-box-orient': 'vertical',
WebkitLineClamp: '2',
WebkitBoxOrient: 'vertical',
overflow: 'hidden',
}),
cardActions: css({
Expand Down
Loading