mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
DashboardAI: UX improvements (#84934)
This commit is contained in:
parent
26473a0074
commit
5b0b8cb4bf
@ -85,10 +85,12 @@ export const availableIconsIndex = {
|
||||
'dice-three': true,
|
||||
docker: true,
|
||||
'document-info': true,
|
||||
'document-layout-left': true,
|
||||
'download-alt': true,
|
||||
draggabledots: true,
|
||||
edit: true,
|
||||
'ellipsis-v': true,
|
||||
enter: true,
|
||||
envelope: true,
|
||||
'exchange-alt': true,
|
||||
'exclamation-triangle': true,
|
||||
@ -176,6 +178,7 @@ export const availableIconsIndex = {
|
||||
monitor: true,
|
||||
palette: true,
|
||||
'panel-add': true,
|
||||
paragraph: true,
|
||||
'pathfinder-unite': true,
|
||||
pause: true,
|
||||
pen: true,
|
||||
|
@ -43,15 +43,7 @@ export const GenAIButton = ({
|
||||
}: GenAIButtonProps) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const {
|
||||
messages: streamMessages,
|
||||
setMessages,
|
||||
setStopGeneration,
|
||||
reply,
|
||||
value,
|
||||
error,
|
||||
streamStatus,
|
||||
} = useOpenAIStream(model, temperature);
|
||||
const { setMessages, setStopGeneration, reply, value, error, streamStatus } = useOpenAIStream(model, temperature);
|
||||
|
||||
const [history, setHistory] = useState<string[]>([]);
|
||||
const [showHistory, setShowHistory] = useState(false);
|
||||
@ -68,7 +60,7 @@ export const GenAIButton = ({
|
||||
} else {
|
||||
if (!hasHistory) {
|
||||
onClickProp?.(e);
|
||||
setMessages(typeof messages === 'function' ? messages() : messages);
|
||||
setMessages(getMessages());
|
||||
} else {
|
||||
setShowHistory(true);
|
||||
}
|
||||
@ -158,6 +150,13 @@ export const GenAIButton = ({
|
||||
</Button>
|
||||
);
|
||||
|
||||
const getMessages = () => {
|
||||
if (typeof messages === 'function') {
|
||||
return messages();
|
||||
}
|
||||
return messages;
|
||||
};
|
||||
|
||||
const renderButtonWithToggletip = () => {
|
||||
if (hasHistory) {
|
||||
const title = <Text element="p">{toggleTipTitle}</Text>;
|
||||
@ -168,7 +167,7 @@ export const GenAIButton = ({
|
||||
content={
|
||||
<GenAIHistory
|
||||
history={history}
|
||||
messages={streamMessages}
|
||||
messages={getMessages()}
|
||||
onApplySuggestion={onApplySuggestion}
|
||||
updateHistory={pushHistoryEntry}
|
||||
eventTrackingSrc={eventTrackingSrc}
|
||||
|
@ -2,7 +2,7 @@ import { css } from '@emotion/css';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Alert, Button, Icon, IconButton, Input, Stack, Text, TextLink, useStyles2 } from '@grafana/ui';
|
||||
import { Alert, Button, Icon, Input, Stack, Text, TextLink, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { STOP_GENERATION_TEXT } from './GenAIButton';
|
||||
import { GenerationHistoryCarousel } from './GenerationHistoryCarousel';
|
||||
@ -120,31 +120,37 @@ export const GenAIHistory = ({
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<GenerationHistoryCarousel
|
||||
history={history}
|
||||
index={currentIndex}
|
||||
onNavigate={onNavigate}
|
||||
reply={sanitizeReply(reply)}
|
||||
streamStatus={streamStatus}
|
||||
/>
|
||||
|
||||
<div className={styles.actionButtons}>
|
||||
<QuickFeedback onSuggestionClick={onGenerateWithFeedback} isGenerating={isStreamGenerating} />
|
||||
</div>
|
||||
|
||||
<Input
|
||||
placeholder="Tell AI what to do next..."
|
||||
suffix={
|
||||
<IconButton
|
||||
name="corner-down-right-alt"
|
||||
<Button
|
||||
icon="enter"
|
||||
variant="secondary"
|
||||
fill="text"
|
||||
aria-label="Send custom feedback"
|
||||
onClick={onClickSubmitCustomFeedback}
|
||||
disabled={customFeedback === ''}
|
||||
/>
|
||||
>
|
||||
Send
|
||||
</Button>
|
||||
}
|
||||
value={customFeedback}
|
||||
onChange={onChangeCustomFeedback}
|
||||
onKeyDown={onKeyDownCustomFeedbackInput}
|
||||
/>
|
||||
<div className={styles.actions}>
|
||||
<QuickFeedback onSuggestionClick={onGenerateWithFeedback} isGenerating={isStreamGenerating} />
|
||||
<GenerationHistoryCarousel
|
||||
history={history}
|
||||
index={currentIndex}
|
||||
onNavigate={onNavigate}
|
||||
reply={sanitizeReply(reply)}
|
||||
streamStatus={streamStatus}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.applySuggestion}>
|
||||
<Stack justifyContent={'flex-end'} direction={'row'}>
|
||||
<Button icon={!isStreamGenerating ? 'check' : 'fa fa-spinner'} onClick={onApply}>
|
||||
@ -152,12 +158,14 @@ export const GenAIHistory = ({
|
||||
</Button>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<div className={styles.footer}>
|
||||
<Icon name="exclamation-circle" aria-label="exclamation-circle" className={styles.infoColor} />
|
||||
<Text variant="bodySmall" color="secondary">
|
||||
This content is AI-generated using the{' '}
|
||||
<TextLink
|
||||
variant="bodySmall"
|
||||
inline={true}
|
||||
href="https://grafana.com/docs/grafana-cloud/alerting-and-irm/machine-learning/llm-plugin/"
|
||||
external
|
||||
onClick={onClickDocs}
|
||||
@ -177,10 +185,10 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
||||
width: 520,
|
||||
maxHeight: 350,
|
||||
// This is the space the footer height
|
||||
paddingBottom: 35,
|
||||
paddingBottom: 25,
|
||||
}),
|
||||
applySuggestion: css({
|
||||
marginTop: theme.spacing(1),
|
||||
paddingTop: theme.spacing(2),
|
||||
}),
|
||||
actions: css({
|
||||
display: 'flex',
|
||||
@ -206,4 +214,10 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
||||
infoColor: css({
|
||||
color: theme.colors.info.main,
|
||||
}),
|
||||
actionButtons: css({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
padding: '24px 0 8px 0',
|
||||
}),
|
||||
});
|
||||
|
@ -35,18 +35,18 @@ export const GenerationHistoryCarousel = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<MinimalisticPagination
|
||||
currentPage={index}
|
||||
numberOfPages={historySize}
|
||||
onNavigate={onNavigate}
|
||||
hideWhenSinglePage={true}
|
||||
className={styles.paginationWrapper}
|
||||
/>
|
||||
<div className={styles.contentWrapper}>
|
||||
<Text element="p" color="secondary">
|
||||
{getHistoryText()}
|
||||
</Text>
|
||||
</div>
|
||||
<MinimalisticPagination
|
||||
currentPage={index}
|
||||
numberOfPages={historySize}
|
||||
onNavigate={onNavigate}
|
||||
hideWhenSinglePage={false}
|
||||
className={styles.paginationWrapper}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@ -63,8 +63,11 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
||||
flexBasis: '100%',
|
||||
flexGrow: 3,
|
||||
whiteSpace: 'pre-wrap',
|
||||
marginTop: 20,
|
||||
height: 110,
|
||||
maxHeight: 110,
|
||||
overflowY: 'scroll',
|
||||
backgroundColor: theme.colors.background.secondary,
|
||||
border: `1px solid ${theme.colors.border.weak}`,
|
||||
padding: theme.spacing(1),
|
||||
minHeight: 60,
|
||||
}),
|
||||
});
|
||||
|
@ -20,6 +20,7 @@ export const QuickFeedback = ({ onSuggestionClick, isGenerating }: QuickActionsP
|
||||
onClick={() => onSuggestionClick(QuickFeedbackType.Shorter)}
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
icon="paragraph"
|
||||
disabled={isGenerating}
|
||||
>
|
||||
{QuickFeedbackType.Shorter}
|
||||
@ -28,12 +29,14 @@ export const QuickFeedback = ({ onSuggestionClick, isGenerating }: QuickActionsP
|
||||
onClick={() => onSuggestionClick(QuickFeedbackType.MoreDescriptive)}
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
icon="document-layout-left"
|
||||
disabled={isGenerating}
|
||||
>
|
||||
{QuickFeedbackType.MoreDescriptive}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => onSuggestionClick(QuickFeedbackType.Regenerate)}
|
||||
icon="sync"
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
disabled={isGenerating}
|
||||
@ -48,10 +51,6 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
||||
quickSuggestionsWrapper: css({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
flexWrap: 'wrap',
|
||||
flexGrow: 1,
|
||||
gap: 8,
|
||||
paddingTop: 10,
|
||||
}),
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user