ShareDrawer: Share snapshot panel (#90678)

pull/91916/head
Juan Cabanas 9 months ago committed by GitHub
parent 7cc925d319
commit 8a97143120
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 18
      public/app/features/dashboard-scene/scene/PanelMenuBehavior.tsx
  2. 16
      public/app/features/dashboard-scene/scene/keyboardShortcuts.ts
  3. 34
      public/app/features/dashboard-scene/sharing/ShareButton/share-snapshot/CreateSnapshot.tsx
  4. 3
      public/app/features/dashboard-scene/sharing/ShareButton/share-snapshot/ShareSnapshot.tsx
  5. 11
      public/locales/en-US/grafana.json
  6. 11
      public/locales/pseudo-LOCALE/grafana.json

@ -13,6 +13,7 @@ import { LocalValueVariable, sceneGraph, SceneGridRow, VizPanel, VizPanelMenu }
import { DataQuery, OptionsWithLegend } from '@grafana/schema';
import appEvents from 'app/core/app_events';
import { t } from 'app/core/internationalization';
import { contextSrv } from 'app/core/services/context_srv';
import { scenesPanelToRuleFormValues } from 'app/features/alerting/unified/utils/rule-form';
import { shareDashboardType } from 'app/features/dashboard/components/ShareModal/utils';
import { InspectTab } from 'app/features/inspector/types';
@ -21,6 +22,7 @@ import { createExtensionSubMenu } from 'app/features/plugins/extensions/utils';
import { addDataTrailPanelAction } from 'app/features/trails/Integrations/dashboardIntegration';
import { ShowConfirmModalEvent } from 'app/types/events';
import { ShareSnapshot } from '../sharing/ShareButton/share-snapshot/ShareSnapshot';
import { ShareDrawer } from '../sharing/ShareDrawer/ShareDrawer';
import { ShareModal } from '../sharing/ShareModal';
import { SharePanelEmbedTab } from '../sharing/SharePanelEmbedTab';
@ -109,6 +111,22 @@ export function panelMenuBehavior(menu: VizPanelMenu, isRepeat = false) {
},
});
if (contextSrv.isSignedIn && config.snapshotEnabled && dashboard.canEditDashboard()) {
subMenu.push({
text: t('share-panel.menu.share-snapshot-title', 'Share snapshot'),
iconClassName: 'camera',
shortcut: 'p s',
onClick: () => {
const drawer = new ShareDrawer({
title: t('share-panel.drawer.share-snapshot-title', 'Share snapshot'),
body: new ShareSnapshot({ dashboardRef: dashboard.getRef(), panelRef: panel.getRef() }),
});
dashboard.showModal(drawer);
},
});
}
items.push({
type: 'submenu',
text: t('panel.header-menu.share', 'Share'),

@ -4,7 +4,9 @@ import { sceneGraph, VizPanel } from '@grafana/scenes';
import appEvents from 'app/core/app_events';
import { t } from 'app/core/internationalization';
import { KeybindingSet } from 'app/core/services/KeybindingSet';
import { contextSrv } from 'app/core/services/context_srv';
import { ShareSnapshot } from '../sharing/ShareButton/share-snapshot/ShareSnapshot';
import { ShareDrawer } from '../sharing/ShareDrawer/ShareDrawer';
import { ShareModal } from '../sharing/ShareModal';
import { SharePanelEmbedTab } from '../sharing/SharePanelEmbedTab';
@ -72,6 +74,20 @@ export function setupKeyboardShortcuts(scene: DashboardScene) {
scene.showModal(drawer);
}),
});
if (contextSrv.isSignedIn && config.snapshotEnabled && scene.canEditDashboard()) {
keybindings.addBinding({
key: 'p s',
onTrigger: withFocusedPanel(scene, async (vizPanel: VizPanel) => {
const drawer = new ShareDrawer({
title: t('share-panel.drawer.share-snapshot-title', 'Share snapshot'),
body: new ShareSnapshot({ dashboardRef: scene.getRef(), panelRef: vizPanel.getRef() }),
});
scene.showModal(drawer);
}),
});
}
} else {
keybindings.addBinding({
key: 'p s',

@ -1,6 +1,7 @@
import { css } from '@emotion/css';
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
import { SceneObjectRef, VizPanel } from '@grafana/scenes';
import {
Alert,
Button,
@ -20,7 +21,10 @@ import { Trans } from 'app/core/internationalization';
import { SnapshotSharingOptions } from '../../../../dashboard/services/SnapshotSrv';
import { getExpireOptions } from '../../ShareSnapshotTab';
const SNAPSHOT_URL = 'https://grafana.com/docs/grafana/latest/dashboards/share-dashboards-panels/#publish-a-snapshot';
const DASHBOARD_SNAPSHOT_URL =
'https://grafana.com/docs/grafana/latest/dashboards/share-dashboards-panels/#publish-a-snapshot';
const PANEL_SNAPSHOT_URL =
'https://grafana.com/docs/grafana/latest/dashboards/share-dashboards-panels/#publish-a-snapshot-1';
interface Props {
isLoading: boolean;
@ -31,6 +35,7 @@ interface Props {
onCreateClick: (isExternal?: boolean) => void;
onNameChange: (v: string) => void;
onExpireChange: (v: number) => void;
panelRef?: SceneObjectRef<VizPanel>;
}
export function CreateSnapshot({
name,
@ -41,6 +46,7 @@ export function CreateSnapshot({
onCancelClick,
onCreateClick,
isLoading,
panelRef,
}: Props) {
const styles = useStyles2(getStyles);
@ -49,18 +55,30 @@ export function CreateSnapshot({
<Alert severity="info" title={''}>
<Stack justifyContent="space-between" gap={2} alignItems="center">
<Text>
<Trans i18nKey="snapshot.share.info-alert">
A Grafana dashboard snapshot publicly shares a dashboard while removing sensitive data such as queries and
panel links, leaving only visible metrics and series names. Anyone with the link can access the snapshot.
</Trans>
{panelRef ? (
<Trans i18nKey="snapshot.share-panel.info-alert">
A Grafana panel snapshot publicly shares a panel while removing sensitive data such as queries and panel
links, leaving only visible metrics and series names. Anyone with the link can access the snapshot.
</Trans>
) : (
<Trans i18nKey="snapshot.share.info-alert">
A Grafana dashboard snapshot publicly shares a dashboard while removing sensitive data such as queries
and panel links, leaving only visible metrics and series names. Anyone with the link can access the
snapshot.
</Trans>
)}
</Text>
<Button variant="secondary" onClick={() => window.open(SNAPSHOT_URL, '_blank')} type="button">
<Button
variant="secondary"
onClick={() => window.open(panelRef ? PANEL_SNAPSHOT_URL : DASHBOARD_SNAPSHOT_URL, '_blank')}
type="button"
>
<Trans i18nKey="snapshot.share.learn-more-button">Learn more</Trans>
</Button>
</Stack>
</Alert>
<Field label={t('snapshot.share.name-label', 'Snapshot name*')}>
<Input id="snapshot-name-input" defaultValue={name} onBlur={(e) => onNameChange(e.target.value)} />
<Field label={t('snapshot.share.name-label', 'Snapshot name')}>
<Input id="snapshot-name-input" defaultValue={name} onChange={(e) => onNameChange(e.currentTarget.value)} />
</Field>
<Field label={t('snapshot.share.expiration-label', 'Expires in')}>
<RadioButtonGroup<number>

@ -23,7 +23,7 @@ function ShareSnapshotRenderer({ model }: SceneComponentProps<ShareSnapshot>) {
const [showDeletedAlert, setShowDeletedAlert] = useState(false);
const [step, setStep] = useState(1);
const { snapshotName, snapshotSharingOptions, selectedExpireOption, dashboardRef } = model.useState();
const { snapshotName, snapshotSharingOptions, selectedExpireOption, dashboardRef, panelRef } = model.useState();
const [snapshotResult, createSnapshot] = useAsyncFn(async (external = false) => {
const response = await model.onSnapshotCreate(external);
@ -76,6 +76,7 @@ function ShareSnapshotRenderer({ model }: SceneComponentProps<ShareSnapshot>) {
onExpireChange={model.onExpireChange}
onCreateClick={createSnapshot}
isLoading={snapshotResult.loading}
panelRef={panelRef}
/>
</>
)}

@ -2130,11 +2130,13 @@
"share-panel": {
"drawer": {
"share-embed-title": "Share embed",
"share-link-title": "Link settings"
"share-link-title": "Link settings",
"share-snapshot-title": "Share snapshot"
},
"menu": {
"share-embed-title": "Share embed",
"share-link-title": "Share link"
"share-link-title": "Share link",
"share-snapshot-title": "Share snapshot"
}
},
"share-playlist": {
@ -2215,12 +2217,15 @@
"info-alert": "A Grafana dashboard snapshot publicly shares a dashboard while removing sensitive data such as queries and panel links, leaving only visible metrics and series names. Anyone with the link can access the snapshot.",
"learn-more-button": "Learn more",
"local-button": "Publish snapshot",
"name-label": "Snapshot name*",
"name-label": "Snapshot name",
"new-snapshot-button": "New snapshot",
"success-creation": "Your snapshot has been created",
"success-delete": "Your snapshot has been deleted",
"view-all-button": "View all snapshots"
},
"share-panel": {
"info-alert": "A Grafana panel snapshot publicly shares a panel while removing sensitive data such as queries and panel links, leaving only visible metrics and series names. Anyone with the link can access the snapshot."
},
"url-column-header": "Snapshot url",
"view-button": "View"
},

@ -2130,11 +2130,13 @@
"share-panel": {
"drawer": {
"share-embed-title": "Ŝĥäřę ęmþęđ",
"share-link-title": "Ŀįʼnĸ şęŧŧįʼnģş"
"share-link-title": "Ŀįʼnĸ şęŧŧįʼnģş",
"share-snapshot-title": "Ŝĥäřę şʼnäpşĥőŧ"
},
"menu": {
"share-embed-title": "Ŝĥäřę ęmþęđ",
"share-link-title": "Ŝĥäřę ľįʼnĸ"
"share-link-title": "Ŝĥäřę ľįʼnĸ",
"share-snapshot-title": "Ŝĥäřę şʼnäpşĥőŧ"
}
},
"share-playlist": {
@ -2215,12 +2217,15 @@
"info-alert": "Å Ğřäƒäʼnä đäşĥþőäřđ şʼnäpşĥőŧ pūþľįčľy şĥäřęş ä đäşĥþőäřđ ŵĥįľę řęmővįʼnģ şęʼnşįŧįvę đäŧä şūčĥ äş qūęřįęş äʼnđ päʼnęľ ľįʼnĸş, ľęävįʼnģ őʼnľy vįşįþľę męŧřįčş äʼnđ şęřįęş ʼnämęş. Åʼnyőʼnę ŵįŧĥ ŧĥę ľįʼnĸ čäʼn äččęşş ŧĥę şʼnäpşĥőŧ.",
"learn-more-button": "Ŀęäřʼn mőřę",
"local-button": "Pūþľįşĥ şʼnäpşĥőŧ",
"name-label": "Ŝʼnäpşĥőŧ ʼnämę*",
"name-label": "Ŝʼnäpşĥőŧ ʼnämę",
"new-snapshot-button": "Ńęŵ şʼnäpşĥőŧ",
"success-creation": "Ÿőūř şʼnäpşĥőŧ ĥäş þęęʼn čřęäŧęđ",
"success-delete": "Ÿőūř şʼnäpşĥőŧ ĥäş þęęʼn đęľęŧęđ",
"view-all-button": "Vįęŵ äľľ şʼnäpşĥőŧş"
},
"share-panel": {
"info-alert": "Å Ğřäƒäʼnä päʼnęľ şʼnäpşĥőŧ pūþľįčľy şĥäřęş ä päʼnęľ ŵĥįľę řęmővįʼnģ şęʼnşįŧįvę đäŧä şūčĥ äş qūęřįęş äʼnđ päʼnęľ ľįʼnĸş, ľęävįʼnģ őʼnľy vįşįþľę męŧřįčş äʼnđ şęřįęş ʼnämęş. Åʼnyőʼnę ŵįŧĥ ŧĥę ľįʼnĸ čäʼn äččęşş ŧĥę şʼnäpşĥőŧ."
},
"url-column-header": "Ŝʼnäpşĥőŧ ūřľ",
"view-button": "Vįęŵ"
},

Loading…
Cancel
Save