mirror of
https://github.com/grafana/grafana.git
synced 2024-11-26 02:40:26 -06:00
Dashgpt: Make generate title and description work in scened dashboard settings (#84649)
* wip * add GenAI to scenes dashboard settings * rework title and description into controlled inputs --------- Co-authored-by: Sergej-Vlasov <sergej.s.vlasov@gmail.com>
This commit is contained in:
parent
9dc4221508
commit
74e62ac6fa
@ -1,16 +1,17 @@
|
||||
import React, { ChangeEvent } from 'react';
|
||||
|
||||
import { PageLayoutType } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { SceneComponentProps, SceneObjectBase, sceneGraph } from '@grafana/scenes';
|
||||
import { TimeZone } from '@grafana/schema';
|
||||
import {
|
||||
Box,
|
||||
CollapsableSection,
|
||||
Field,
|
||||
HorizontalGroup,
|
||||
Input,
|
||||
Label,
|
||||
RadioButtonGroup,
|
||||
Stack,
|
||||
TagsInput,
|
||||
TextArea,
|
||||
} from '@grafana/ui';
|
||||
@ -19,6 +20,8 @@ import { FolderPicker } from 'app/core/components/Select/FolderPicker';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { TimePickerSettings } from 'app/features/dashboard/components/DashboardSettings/TimePickerSettings';
|
||||
import { DeleteDashboardButton } from 'app/features/dashboard/components/DeleteDashboard/DeleteDashboardButton';
|
||||
import { GenAIDashDescriptionButton } from 'app/features/dashboard/components/GenAI/GenAIDashDescriptionButton';
|
||||
import { GenAIDashTitleButton } from 'app/features/dashboard/components/GenAI/GenAIDashTitleButton';
|
||||
|
||||
import { DashboardScene } from '../scene/DashboardScene';
|
||||
import { NavToolbarActions } from '../scene/NavToolbarActions';
|
||||
@ -155,42 +158,40 @@ export class GeneralSettingsEditView
|
||||
<Box marginBottom={5}>
|
||||
<Field
|
||||
label={
|
||||
<HorizontalGroup justify="space-between">
|
||||
<Stack justifyContent="space-between">
|
||||
<Label htmlFor="title-input">
|
||||
<Trans i18nKey="dashboard-settings.general.title-label">Title</Trans>
|
||||
</Label>
|
||||
{/* TODO: Make the component use persisted model */}
|
||||
{/* {config.featureToggles.dashgpt && (
|
||||
<GenAIDashTitleButton onGenerate={onTitleChange} dashboard={dashboard} />
|
||||
)} */}
|
||||
</HorizontalGroup>
|
||||
{config.featureToggles.dashgpt && (
|
||||
<GenAIDashTitleButton onGenerate={(title) => model.onTitleChange(title)} />
|
||||
)}
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
<Input
|
||||
id="title-input"
|
||||
name="title"
|
||||
defaultValue={title}
|
||||
onBlur={(e: ChangeEvent<HTMLInputElement>) => model.onTitleChange(e.target.value)}
|
||||
value={title}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) => model.onTitleChange(e.target.value)}
|
||||
/>
|
||||
</Field>
|
||||
<Field
|
||||
label={
|
||||
<HorizontalGroup justify="space-between">
|
||||
<Stack justifyContent="space-between">
|
||||
<Label htmlFor="description-input">
|
||||
{t('dashboard-settings.general.description-label', 'Description')}
|
||||
</Label>
|
||||
|
||||
{/* {config.featureToggles.dashgpt && (
|
||||
<GenAIDashDescriptionButton onGenerate={onDescriptionChange} dashboard={dashboard} />
|
||||
)} */}
|
||||
</HorizontalGroup>
|
||||
{config.featureToggles.dashgpt && (
|
||||
<GenAIDashDescriptionButton onGenerate={(description) => model.onDescriptionChange(description)} />
|
||||
)}
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
<TextArea
|
||||
id="description-input"
|
||||
name="description"
|
||||
defaultValue={description}
|
||||
onBlur={(e: ChangeEvent<HTMLTextAreaElement>) => model.onDescriptionChange(e.target.value)}
|
||||
value={description}
|
||||
onChange={(e: ChangeEvent<HTMLTextAreaElement>) => model.onDescriptionChange(e.target.value)}
|
||||
/>
|
||||
</Field>
|
||||
<Field label={t('dashboard-settings.general.tags-label', 'Tags')}>
|
||||
|
@ -10,9 +10,9 @@ import {
|
||||
RadioButtonGroup,
|
||||
TagsInput,
|
||||
Label,
|
||||
HorizontalGroup,
|
||||
TextArea,
|
||||
Box,
|
||||
Stack,
|
||||
} from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { FolderPicker } from 'app/core/components/Select/FolderPicker';
|
||||
@ -124,15 +124,13 @@ export function GeneralSettingsUnconnected({
|
||||
<Box marginBottom={5}>
|
||||
<Field
|
||||
label={
|
||||
<HorizontalGroup justify="space-between">
|
||||
<Stack justifyContent="space-between">
|
||||
<Label htmlFor="title-input">
|
||||
<Trans i18nKey="dashboard-settings.general.title-label">Title</Trans>
|
||||
</Label>
|
||||
|
||||
{config.featureToggles.dashgpt && (
|
||||
<GenAIDashTitleButton onGenerate={onTitleChange} dashboard={dashboard} />
|
||||
)}
|
||||
</HorizontalGroup>
|
||||
{config.featureToggles.dashgpt && <GenAIDashTitleButton onGenerate={onTitleChange} />}
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
<Input
|
||||
@ -144,15 +142,13 @@ export function GeneralSettingsUnconnected({
|
||||
</Field>
|
||||
<Field
|
||||
label={
|
||||
<HorizontalGroup justify="space-between">
|
||||
<Stack justifyContent="space-between">
|
||||
<Label htmlFor="description-input">
|
||||
{t('dashboard-settings.general.description-label', 'Description')}
|
||||
</Label>
|
||||
|
||||
{config.featureToggles.dashgpt && (
|
||||
<GenAIDashDescriptionButton onGenerate={onDescriptionChange} dashboard={dashboard} />
|
||||
)}
|
||||
</HorizontalGroup>
|
||||
{config.featureToggles.dashgpt && <GenAIDashDescriptionButton onGenerate={onDescriptionChange} />}
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
<TextArea
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import { DashboardModel } from '../../state';
|
||||
import { getDashboardSrv } from '../../services/DashboardSrv';
|
||||
|
||||
import { GenAIButton } from './GenAIButton';
|
||||
import { EventTrackingSrc } from './tracking';
|
||||
@ -8,7 +8,6 @@ import { getDashboardPanelPrompt, Message, Role } from './utils';
|
||||
|
||||
interface GenAIDashDescriptionButtonProps {
|
||||
onGenerate: (description: string) => void;
|
||||
dashboard: DashboardModel;
|
||||
}
|
||||
|
||||
const DASHBOARD_DESCRIPTION_CHAR_LIMIT = 300;
|
||||
@ -24,12 +23,10 @@ const DESCRIPTION_GENERATION_STANDARD_PROMPT =
|
||||
`The description should be, at most, ${DASHBOARD_DESCRIPTION_CHAR_LIMIT} characters.\n` +
|
||||
'Respond with only the description of the dashboard.';
|
||||
|
||||
export const GenAIDashDescriptionButton = ({ onGenerate, dashboard }: GenAIDashDescriptionButtonProps) => {
|
||||
const messages = React.useMemo(() => getMessages(dashboard), [dashboard]);
|
||||
|
||||
export const GenAIDashDescriptionButton = ({ onGenerate }: GenAIDashDescriptionButtonProps) => {
|
||||
return (
|
||||
<GenAIButton
|
||||
messages={messages}
|
||||
messages={getMessages}
|
||||
onGenerate={onGenerate}
|
||||
eventTrackingSrc={EventTrackingSrc.dashboardDescription}
|
||||
toggleTipTitle={'Improve your dashboard description'}
|
||||
@ -37,7 +34,8 @@ export const GenAIDashDescriptionButton = ({ onGenerate, dashboard }: GenAIDashD
|
||||
);
|
||||
};
|
||||
|
||||
function getMessages(dashboard: DashboardModel): Message[] {
|
||||
function getMessages(): Message[] {
|
||||
const dashboard = getDashboardSrv().getCurrent()!;
|
||||
const panelPrompt = getDashboardPanelPrompt(dashboard);
|
||||
|
||||
return [
|
||||
|
@ -1,13 +1,12 @@
|
||||
import React from 'react';
|
||||
|
||||
import { DashboardModel } from '../../state';
|
||||
import { getDashboardSrv } from '../../services/DashboardSrv';
|
||||
|
||||
import { GenAIButton } from './GenAIButton';
|
||||
import { EventTrackingSrc } from './tracking';
|
||||
import { getDashboardPanelPrompt, Message, Role } from './utils';
|
||||
|
||||
interface GenAIDashTitleButtonProps {
|
||||
dashboard: DashboardModel;
|
||||
onGenerate: (description: string) => void;
|
||||
}
|
||||
|
||||
@ -24,12 +23,10 @@ const TITLE_GENERATION_STANDARD_PROMPT =
|
||||
`The title should be, at most, ${DASH_TITLE_CHAR_LIMIT} characters.\n` +
|
||||
'Respond with only the title of the dashboard.';
|
||||
|
||||
export const GenAIDashTitleButton = ({ onGenerate, dashboard }: GenAIDashTitleButtonProps) => {
|
||||
const messages = React.useMemo(() => getMessages(dashboard), [dashboard]);
|
||||
|
||||
export const GenAIDashTitleButton = ({ onGenerate }: GenAIDashTitleButtonProps) => {
|
||||
return (
|
||||
<GenAIButton
|
||||
messages={messages}
|
||||
messages={getMessages}
|
||||
onGenerate={onGenerate}
|
||||
eventTrackingSrc={EventTrackingSrc.dashboardTitle}
|
||||
toggleTipTitle={'Improve your dashboard title'}
|
||||
@ -37,7 +34,9 @@ export const GenAIDashTitleButton = ({ onGenerate, dashboard }: GenAIDashTitleBu
|
||||
);
|
||||
};
|
||||
|
||||
function getMessages(dashboard: DashboardModel): Message[] {
|
||||
function getMessages(): Message[] {
|
||||
const dashboard = getDashboardSrv().getCurrent()!;
|
||||
|
||||
return [
|
||||
{
|
||||
content: TITLE_GENERATION_STANDARD_PROMPT,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { ChangeEvent } from 'react';
|
||||
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Button, Input, Switch, Form, Field, InputControl, HorizontalGroup, Label, TextArea } from '@grafana/ui';
|
||||
import { Button, Input, Switch, Form, Field, InputControl, Label, TextArea, Stack } from '@grafana/ui';
|
||||
import { FolderPicker } from 'app/core/components/Select/FolderPicker';
|
||||
import { DashboardModel } from 'app/features/dashboard/state';
|
||||
import { validationSrv } from 'app/features/manage-dashboards/services/ValidationSrv';
|
||||
@ -110,12 +110,12 @@ export const SaveDashboardAsForm = ({
|
||||
render={({ field: { ref, ...field } }) => (
|
||||
<Field
|
||||
label={
|
||||
<HorizontalGroup justify="space-between">
|
||||
<Stack justifyContent="space-between">
|
||||
<Label htmlFor="title">Title</Label>
|
||||
{config.featureToggles.dashgpt && isNew && (
|
||||
<GenAIDashTitleButton onGenerate={(title) => field.onChange(title)} dashboard={dashboard} />
|
||||
<GenAIDashTitleButton onGenerate={(title) => field.onChange(title)} />
|
||||
)}
|
||||
</HorizontalGroup>
|
||||
</Stack>
|
||||
}
|
||||
invalid={!!errors.title}
|
||||
error={errors.title?.message}
|
||||
@ -138,15 +138,12 @@ export const SaveDashboardAsForm = ({
|
||||
render={({ field: { ref, ...field } }) => (
|
||||
<Field
|
||||
label={
|
||||
<HorizontalGroup justify="space-between">
|
||||
<Stack justifyContent="space-between">
|
||||
<Label htmlFor="description">Description</Label>
|
||||
{config.featureToggles.dashgpt && isNew && (
|
||||
<GenAIDashDescriptionButton
|
||||
onGenerate={(description) => field.onChange(description)}
|
||||
dashboard={dashboard}
|
||||
/>
|
||||
<GenAIDashDescriptionButton onGenerate={(description) => field.onChange(description)} />
|
||||
)}
|
||||
</HorizontalGroup>
|
||||
</Stack>
|
||||
}
|
||||
invalid={!!errors.description}
|
||||
error={errors.description?.message}
|
||||
@ -184,14 +181,14 @@ export const SaveDashboardAsForm = ({
|
||||
<Switch {...register('copyTags')} />
|
||||
</Field>
|
||||
)}
|
||||
<HorizontalGroup>
|
||||
<Stack>
|
||||
<Button type="button" variant="secondary" onClick={onCancel} fill="outline">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button disabled={isLoading} type="submit" aria-label="Save dashboard button">
|
||||
{isLoading ? 'Saving...' : 'Save'}
|
||||
</Button>
|
||||
</HorizontalGroup>
|
||||
</Stack>
|
||||
</>
|
||||
)}
|
||||
</Form>
|
||||
|
Loading…
Reference in New Issue
Block a user