mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Dashboard: Remove template variables option from ShareModal (#30395)
* Dashboard: Remove template variables option and update style of ShareModal (#29191) * Simplified design * Changed to text area component for embed and replaced select with RadioButtonGroup * Use primitive string instead of SelectableValue in the states * Changed embed html TextArea to writable and added a copy to clipboard button * Added some space between the buttons on the snapshot tab and removed unnessecary FieldSet elements * Add descriptions to the tabs that were missing descriptions * Capitalization of theme names Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
parent
3cf47b24d3
commit
b40b134e4c
@ -1,18 +1,18 @@
|
||||
import React from 'react';
|
||||
import { cx } from 'emotion';
|
||||
import { IconName } from '../../types';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
interface Props {
|
||||
/** @deprecated */
|
||||
icon?: IconName;
|
||||
/** @deprecated */
|
||||
iconClass?: string;
|
||||
}
|
||||
|
||||
export const ModalTabContent: React.FC<Props> = ({ icon, iconClass, children }) => {
|
||||
/** @internal */
|
||||
export const ModalTabContent: React.FC<Props> = ({ children }) => {
|
||||
return (
|
||||
<div className="share-modal-body">
|
||||
<div className="share-modal-header">
|
||||
{icon && <Icon name={icon} size="xxl" className={cx(iconClass, 'share-modal-big-icon')} />}
|
||||
<div className="share-modal-content">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,13 +1,14 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Select, Switch, Icon, InlineField } from '@grafana/ui';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import React, { FormEvent, PureComponent } from 'react';
|
||||
import { RadioButtonGroup, Switch, Field, TextArea, Icon, ClipboardButton } from '@grafana/ui';
|
||||
import { SelectableValue, AppEvents } from '@grafana/data';
|
||||
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
||||
import { appEvents } from 'app/core/core';
|
||||
import { buildIframeHtml } from './utils';
|
||||
|
||||
const themeOptions: Array<SelectableValue<string>> = [
|
||||
{ label: 'current', value: 'current' },
|
||||
{ label: 'dark', value: 'dark' },
|
||||
{ label: 'light', value: 'light' },
|
||||
{ label: 'Current', value: 'current' },
|
||||
{ label: 'Dark', value: 'dark' },
|
||||
{ label: 'Light', value: 'light' },
|
||||
];
|
||||
|
||||
interface Props {
|
||||
@ -17,8 +18,7 @@ interface Props {
|
||||
|
||||
interface State {
|
||||
useCurrentTimeRange: boolean;
|
||||
includeTemplateVars: boolean;
|
||||
selectedTheme: SelectableValue<string>;
|
||||
selectedTheme: string;
|
||||
iframeHtml: string;
|
||||
}
|
||||
|
||||
@ -27,8 +27,7 @@ export class ShareEmbed extends PureComponent<Props, State> {
|
||||
super(props);
|
||||
this.state = {
|
||||
useCurrentTimeRange: true,
|
||||
includeTemplateVars: true,
|
||||
selectedTheme: themeOptions[0],
|
||||
selectedTheme: 'current',
|
||||
iframeHtml: '',
|
||||
};
|
||||
}
|
||||
@ -39,12 +38,16 @@ export class ShareEmbed extends PureComponent<Props, State> {
|
||||
|
||||
buildIframeHtml = () => {
|
||||
const { panel } = this.props;
|
||||
const { useCurrentTimeRange, includeTemplateVars, selectedTheme } = this.state;
|
||||
const { useCurrentTimeRange, selectedTheme } = this.state;
|
||||
|
||||
const iframeHtml = buildIframeHtml(useCurrentTimeRange, includeTemplateVars, selectedTheme.value, panel);
|
||||
const iframeHtml = buildIframeHtml(useCurrentTimeRange, selectedTheme, panel);
|
||||
this.setState({ iframeHtml });
|
||||
};
|
||||
|
||||
onIframeHtmlChange = (event: FormEvent<HTMLTextAreaElement>) => {
|
||||
this.setState({ iframeHtml: event.currentTarget.value });
|
||||
};
|
||||
|
||||
onUseCurrentTimeRangeChange = () => {
|
||||
this.setState(
|
||||
{
|
||||
@ -54,61 +57,50 @@ export class ShareEmbed extends PureComponent<Props, State> {
|
||||
);
|
||||
};
|
||||
|
||||
onIncludeTemplateVarsChange = () => {
|
||||
this.setState(
|
||||
{
|
||||
includeTemplateVars: !this.state.includeTemplateVars,
|
||||
},
|
||||
this.buildIframeHtml
|
||||
);
|
||||
onThemeChange = (value: string) => {
|
||||
this.setState({ selectedTheme: value }, this.buildIframeHtml);
|
||||
};
|
||||
|
||||
onThemeChange = (value: SelectableValue<string>) => {
|
||||
this.setState(
|
||||
{
|
||||
selectedTheme: value,
|
||||
},
|
||||
this.buildIframeHtml
|
||||
);
|
||||
onIframeHtmlCopy = () => {
|
||||
appEvents.emit(AppEvents.alertSuccess, ['Content copied to clipboard']);
|
||||
};
|
||||
|
||||
getIframeHtml = () => {
|
||||
return this.state.iframeHtml;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { useCurrentTimeRange, includeTemplateVars, selectedTheme, iframeHtml } = this.state;
|
||||
const { useCurrentTimeRange, selectedTheme, iframeHtml } = this.state;
|
||||
const isRelativeTime = this.props.dashboard ? this.props.dashboard.time.to === 'now' : false;
|
||||
|
||||
return (
|
||||
<div className="share-modal-body">
|
||||
<div className="share-modal-header">
|
||||
<Icon name="link" className="share-modal-big-icon" size="xxl" />
|
||||
<div className="share-modal-content">
|
||||
<div className="gf-form-group">
|
||||
<InlineField labelWidth={24} label="Current time range">
|
||||
<Switch
|
||||
id="share-current-time-range"
|
||||
value={useCurrentTimeRange}
|
||||
onChange={this.onUseCurrentTimeRangeChange}
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField labelWidth={24} label="Template variables">
|
||||
<Switch
|
||||
id="share-template-variables"
|
||||
value={includeTemplateVars}
|
||||
onChange={this.onIncludeTemplateVarsChange}
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField labelWidth={24} label="Theme">
|
||||
<Select width={20} options={themeOptions} value={selectedTheme} onChange={this.onThemeChange} />
|
||||
</InlineField>
|
||||
</div>
|
||||
<p className="share-modal-info-text">
|
||||
The html code below can be pasted and included in another web page. Unless anonymous access is enabled,
|
||||
the user viewing that page need to be signed into grafana for the graph to load.
|
||||
</p>
|
||||
|
||||
<div className="gf-form-group gf-form--grow">
|
||||
<div className="gf-form">
|
||||
<textarea rows={5} data-share-panel-url className="gf-form-input" defaultValue={iframeHtml}></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<p className="share-modal-info-text">Generate HTML for embedding an iframe with this panel.</p>
|
||||
<Field
|
||||
label="Current time range"
|
||||
description={isRelativeTime ? 'Transforms the current relative time range to an absolute time range' : ''}
|
||||
>
|
||||
<Switch
|
||||
id="share-current-time-range"
|
||||
value={useCurrentTimeRange}
|
||||
onChange={this.onUseCurrentTimeRangeChange}
|
||||
/>
|
||||
</Field>
|
||||
<Field label="Theme">
|
||||
<RadioButtonGroup options={themeOptions} value={selectedTheme} onChange={this.onThemeChange} />
|
||||
</Field>
|
||||
<Field
|
||||
label="Embed html"
|
||||
description="The html code below can be pasted and included in another web page. Unless anonymous access is enabled,
|
||||
the user viewing that page need to be signed into grafana for the graph to load."
|
||||
>
|
||||
<TextArea rows={5} value={iframeHtml} onChange={this.onIframeHtmlChange}></TextArea>
|
||||
</Field>
|
||||
<ClipboardButton variant="primary" getText={this.getIframeHtml} onClipboardCopy={this.onIframeHtmlCopy}>
|
||||
<Icon name="copy" /> Copy
|
||||
</ClipboardButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { Button, InlineField, Switch, Icon } from '@grafana/ui';
|
||||
import { Button, Field, Switch } from '@grafana/ui';
|
||||
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
||||
import { DashboardExporter } from 'app/features/dashboard/components/DashExportModal';
|
||||
import { appEvents } from 'app/core/core';
|
||||
@ -90,11 +90,11 @@ export class ShareExport extends PureComponent<Props, State> {
|
||||
return (
|
||||
<div className="share-modal-body">
|
||||
<div className="share-modal-header">
|
||||
<Icon name="cloud-upload" size="xxl" className="share-modal-big-icon" />
|
||||
<div className="share-modal-content">
|
||||
<InlineField labelWidth={32} label="Export for sharing externally">
|
||||
<p className="share-modal-info-text">Export this dashboard.</p>
|
||||
<Field label="Export for sharing externally">
|
||||
<Switch value={shareExternally} onChange={this.onShareExternallyChange} />
|
||||
</InlineField>
|
||||
</Field>
|
||||
<div className="gf-form-button-row">
|
||||
<Button variant="primary" onClick={this.onSaveAsFile}>
|
||||
Save to file
|
||||
|
@ -156,7 +156,7 @@ describe('ShareModal', () => {
|
||||
|
||||
it('should add theme when specified', async () => {
|
||||
ctx.wrapper?.setProps({ panel: undefined });
|
||||
ctx.wrapper?.setState({ selectedTheme: { label: 'light', value: 'light' } });
|
||||
ctx.wrapper?.setState({ selectedTheme: 'light' });
|
||||
|
||||
await ctx.wrapper?.instance().buildUrl();
|
||||
const state = ctx.wrapper?.state();
|
||||
@ -175,35 +175,13 @@ describe('ShareModal', () => {
|
||||
expect(state?.imageUrl).toContain('?from=1000&to=2000&orgId=1&panelId=1&width=1000&height=500&tz=UTC');
|
||||
});
|
||||
|
||||
describe('template variables', () => {
|
||||
beforeEach(() => {
|
||||
templateSrv = initTemplateSrv([
|
||||
{ type: 'query', name: 'app', current: { value: 'mupp' } },
|
||||
{ type: 'query', name: 'server', current: { value: 'srv-01' } },
|
||||
]);
|
||||
setTemplateSrv(templateSrv);
|
||||
});
|
||||
|
||||
it('should include template variables in url', async () => {
|
||||
mockLocationHref('http://server/#!/test');
|
||||
ctx.mount();
|
||||
ctx.wrapper?.setState({ includeTemplateVars: true });
|
||||
|
||||
it('should shorten url', () => {
|
||||
mockLocationHref('http://server/#!/test');
|
||||
ctx.mount();
|
||||
ctx.wrapper?.setState({ useShortUrl: true }, async () => {
|
||||
await ctx.wrapper?.instance().buildUrl();
|
||||
const state = ctx.wrapper?.state();
|
||||
expect(state?.shareUrl).toContain(
|
||||
'http://server/#!/test?from=1000&to=2000&orgId=1&var-app=mupp&var-server=srv-01'
|
||||
);
|
||||
});
|
||||
|
||||
it('should shorten url', () => {
|
||||
mockLocationHref('http://server/#!/test');
|
||||
ctx.mount();
|
||||
ctx.wrapper?.setState({ includeTemplateVars: true, useShortUrl: true }, async () => {
|
||||
await ctx.wrapper?.instance().buildUrl();
|
||||
const state = ctx.wrapper?.state();
|
||||
expect(state?.shareUrl).toContain(`/goto/${mockUid}`);
|
||||
});
|
||||
expect(state?.shareUrl).toContain(`/goto/${mockUid}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { selectors as e2eSelectors } from '@grafana/e2e-selectors';
|
||||
import { InlineField, Select, Switch, ClipboardButton, Icon, InfoBox, Input } from '@grafana/ui';
|
||||
import { Field, RadioButtonGroup, Switch, ClipboardButton, Icon, InfoBox, Input, FieldSet } from '@grafana/ui';
|
||||
import { SelectableValue, PanelModel, AppEvents } from '@grafana/data';
|
||||
import { DashboardModel } from 'app/features/dashboard/state';
|
||||
import { buildImageUrl, buildShareUrl } from './utils';
|
||||
@ -8,9 +8,9 @@ import { appEvents } from 'app/core/core';
|
||||
import config from 'app/core/config';
|
||||
|
||||
const themeOptions: Array<SelectableValue<string>> = [
|
||||
{ label: 'current', value: 'current' },
|
||||
{ label: 'dark', value: 'dark' },
|
||||
{ label: 'light', value: 'light' },
|
||||
{ label: 'Current', value: 'current' },
|
||||
{ label: 'Dark', value: 'dark' },
|
||||
{ label: 'Light', value: 'light' },
|
||||
];
|
||||
|
||||
export interface Props {
|
||||
@ -20,9 +20,8 @@ export interface Props {
|
||||
|
||||
export interface State {
|
||||
useCurrentTimeRange: boolean;
|
||||
includeTemplateVars: boolean;
|
||||
useShortUrl: boolean;
|
||||
selectedTheme: SelectableValue<string>;
|
||||
selectedTheme: string;
|
||||
shareUrl: string;
|
||||
imageUrl: string;
|
||||
}
|
||||
@ -32,9 +31,8 @@ export class ShareLink extends PureComponent<Props, State> {
|
||||
super(props);
|
||||
this.state = {
|
||||
useCurrentTimeRange: true,
|
||||
includeTemplateVars: true,
|
||||
useShortUrl: false,
|
||||
selectedTheme: themeOptions[0],
|
||||
selectedTheme: 'current',
|
||||
shareUrl: '',
|
||||
imageUrl: '',
|
||||
};
|
||||
@ -45,11 +43,10 @@ export class ShareLink extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: Props, prevState: State) {
|
||||
const { useCurrentTimeRange, includeTemplateVars, useShortUrl, selectedTheme } = this.state;
|
||||
const { useCurrentTimeRange, useShortUrl, selectedTheme } = this.state;
|
||||
if (
|
||||
prevState.useCurrentTimeRange !== useCurrentTimeRange ||
|
||||
prevState.includeTemplateVars !== includeTemplateVars ||
|
||||
prevState.selectedTheme.value !== selectedTheme.value ||
|
||||
prevState.selectedTheme !== selectedTheme ||
|
||||
prevState.useShortUrl !== useShortUrl
|
||||
) {
|
||||
this.buildUrl();
|
||||
@ -58,16 +55,10 @@ export class ShareLink extends PureComponent<Props, State> {
|
||||
|
||||
buildUrl = async () => {
|
||||
const { panel } = this.props;
|
||||
const { useCurrentTimeRange, includeTemplateVars, useShortUrl, selectedTheme } = this.state;
|
||||
const { useCurrentTimeRange, useShortUrl, selectedTheme } = this.state;
|
||||
|
||||
const shareUrl = await buildShareUrl(
|
||||
useCurrentTimeRange,
|
||||
includeTemplateVars,
|
||||
selectedTheme.value,
|
||||
panel,
|
||||
useShortUrl
|
||||
);
|
||||
const imageUrl = buildImageUrl(useCurrentTimeRange, includeTemplateVars, selectedTheme.value, panel);
|
||||
const shareUrl = await buildShareUrl(useCurrentTimeRange, selectedTheme, panel, useShortUrl);
|
||||
const imageUrl = buildImageUrl(useCurrentTimeRange, selectedTheme, panel);
|
||||
|
||||
this.setState({ shareUrl, imageUrl });
|
||||
};
|
||||
@ -76,15 +67,11 @@ export class ShareLink extends PureComponent<Props, State> {
|
||||
this.setState({ useCurrentTimeRange: !this.state.useCurrentTimeRange });
|
||||
};
|
||||
|
||||
onIncludeTemplateVarsChange = () => {
|
||||
this.setState({ includeTemplateVars: !this.state.includeTemplateVars });
|
||||
};
|
||||
|
||||
onUrlShorten = () => {
|
||||
this.setState({ useShortUrl: !this.state.useShortUrl });
|
||||
};
|
||||
|
||||
onThemeChange = (value: SelectableValue<string>) => {
|
||||
onThemeChange = (value: string) => {
|
||||
this.setState({ selectedTheme: value });
|
||||
};
|
||||
|
||||
@ -98,60 +85,49 @@ export class ShareLink extends PureComponent<Props, State> {
|
||||
|
||||
render() {
|
||||
const { panel } = this.props;
|
||||
const { useCurrentTimeRange, includeTemplateVars, useShortUrl, selectedTheme, shareUrl, imageUrl } = this.state;
|
||||
const isRelativeTime = this.props.dashboard ? this.props.dashboard.time.to === 'now' : false;
|
||||
const { useCurrentTimeRange, useShortUrl, selectedTheme, shareUrl, imageUrl } = this.state;
|
||||
const selectors = e2eSelectors.pages.SharePanelModal;
|
||||
|
||||
return (
|
||||
<div className="share-modal-body">
|
||||
<div className="share-modal-header">
|
||||
<Icon name="link" className="share-modal-big-icon" size="xxl" />
|
||||
<div className="share-modal-content">
|
||||
<p className="share-modal-info-text">
|
||||
Create a direct link to this dashboard or panel, customized with the options below.
|
||||
</p>
|
||||
<div className="gf-form-group">
|
||||
<InlineField labelWidth={24} label="Current time range">
|
||||
<FieldSet>
|
||||
<Field
|
||||
label="Lock time range"
|
||||
description={
|
||||
isRelativeTime ? 'Transforms the current relative time range to an absolute time range' : ''
|
||||
}
|
||||
>
|
||||
<Switch
|
||||
id="share-current-time-range"
|
||||
value={useCurrentTimeRange}
|
||||
onChange={this.onUseCurrentTimeRangeChange}
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField labelWidth={24} label="Template variables">
|
||||
<Switch
|
||||
id="share-template-vars"
|
||||
value={includeTemplateVars}
|
||||
onChange={this.onIncludeTemplateVarsChange}
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField labelWidth={24} label="Theme">
|
||||
<Select width={20} options={themeOptions} value={selectedTheme} onChange={this.onThemeChange} />
|
||||
</InlineField>
|
||||
<InlineField labelWidth={24} label="Shorten URL">
|
||||
</Field>
|
||||
<Field label="Theme">
|
||||
<RadioButtonGroup options={themeOptions} value={selectedTheme} onChange={this.onThemeChange} />
|
||||
</Field>
|
||||
<Field label="Shorten URL">
|
||||
<Switch id="share-shorten-url" value={useShortUrl} onChange={this.onUrlShorten} />
|
||||
</InlineField>
|
||||
</div>
|
||||
<div>
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form gf-form--grow">
|
||||
<Input
|
||||
value={shareUrl}
|
||||
readOnly
|
||||
addonAfter={
|
||||
<ClipboardButton
|
||||
variant="primary"
|
||||
getText={this.getShareUrl}
|
||||
onClipboardCopy={this.onShareUrlCopy}
|
||||
>
|
||||
<Icon name="copy" /> Copy
|
||||
</ClipboardButton>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Field>
|
||||
|
||||
<Field label="Link URL">
|
||||
<Input
|
||||
value={shareUrl}
|
||||
readOnly
|
||||
addonAfter={
|
||||
<ClipboardButton variant="primary" getText={this.getShareUrl} onClipboardCopy={this.onShareUrlCopy}>
|
||||
<Icon name="copy" /> Copy
|
||||
</ClipboardButton>
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
</FieldSet>
|
||||
{panel && config.rendererAvailable && (
|
||||
<div className="gf-form">
|
||||
<a href={imageUrl} target="_blank" rel="noreferrer" aria-label={selectors.linkToRenderedImage}>
|
||||
|
@ -1,15 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import {
|
||||
Button,
|
||||
ClipboardButton,
|
||||
Icon,
|
||||
Spinner,
|
||||
Select,
|
||||
Input,
|
||||
LinkButton,
|
||||
InlineField,
|
||||
InlineFieldRow,
|
||||
} from '@grafana/ui';
|
||||
import { Button, ClipboardButton, Icon, Spinner, Select, Input, LinkButton, Field } from '@grafana/ui';
|
||||
import { AppEvents, SelectableValue } from '@grafana/data';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
||||
@ -229,31 +219,26 @@ export class ShareSnapshot extends PureComponent<Props, State> {
|
||||
URL. Share wisely.
|
||||
</p>
|
||||
</div>
|
||||
<InlineFieldRow className="share-modal-options">
|
||||
<InlineField labelWidth={24} label="Snapshot name">
|
||||
<Input width={30} value={snapshotName} onChange={this.onSnapshotNameChange} />
|
||||
</InlineField>
|
||||
<InlineField labelWidth={24} label="Expire">
|
||||
<Select width={30} options={expireOptions} value={selectedExpireOption} onChange={this.onExpireChange} />
|
||||
</InlineField>
|
||||
</InlineFieldRow>
|
||||
|
||||
<p className="share-modal-info-text">
|
||||
You may need to configure the timeout value if it takes a long time to collect your dashboard's metrics.
|
||||
</p>
|
||||
|
||||
<InlineFieldRow className="share-modal-options">
|
||||
<InlineField labelWidth={24} label="Timeout (seconds)">
|
||||
<Input type="number" width={21} value={timeoutSeconds} onChange={this.onTimeoutChange} />
|
||||
</InlineField>
|
||||
</InlineFieldRow>
|
||||
<Field label="Snapshot name">
|
||||
<Input width={30} value={snapshotName} onChange={this.onSnapshotNameChange} />
|
||||
</Field>
|
||||
<Field label="Expire">
|
||||
<Select width={30} options={expireOptions} value={selectedExpireOption} onChange={this.onExpireChange} />
|
||||
</Field>
|
||||
<Field
|
||||
label="Timeout (seconds)"
|
||||
description="You may need to configure the timeout value if it takes a long time to collect your dashboard's
|
||||
metrics."
|
||||
>
|
||||
<Input type="number" width={21} value={timeoutSeconds} onChange={this.onTimeoutChange} />
|
||||
</Field>
|
||||
|
||||
<div className="gf-form-button-row">
|
||||
<Button className="width-10" variant="primary" disabled={isLoading} onClick={this.createSnapshot()}>
|
||||
<Button variant="primary" disabled={isLoading} onClick={this.createSnapshot()}>
|
||||
Local Snapshot
|
||||
</Button>
|
||||
{externalEnabled && (
|
||||
<Button className="width-16" variant="secondary" disabled={isLoading} onClick={this.createSnapshot(true)}>
|
||||
<Button variant="secondary" disabled={isLoading} onClick={this.createSnapshot(true)}>
|
||||
{sharingButtonText}
|
||||
</Button>
|
||||
)}
|
||||
@ -309,17 +294,11 @@ export class ShareSnapshot extends PureComponent<Props, State> {
|
||||
return (
|
||||
<div className="share-modal-body">
|
||||
<div className="share-modal-header">
|
||||
{isLoading ? (
|
||||
<div className="share-modal-big-icon">
|
||||
<Spinner inline={true} />
|
||||
</div>
|
||||
) : (
|
||||
<Icon name="camera" className="share-modal-big-icon" size="xxl" />
|
||||
)}
|
||||
<div className="share-modal-content">
|
||||
{step === 1 && this.renderStep1()}
|
||||
{step === 2 && this.renderStep2()}
|
||||
{step === 3 && this.renderStep3()}
|
||||
{isLoading && <Spinner inline={true} />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,14 +2,8 @@ import { config } from '@grafana/runtime';
|
||||
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
import { createShortLink } from 'app/core/utils/shortLinks';
|
||||
import { PanelModel, dateTime, urlUtil } from '@grafana/data';
|
||||
import { getAllVariableValuesForUrl } from 'app/features/variables/getAllVariableValuesForUrl';
|
||||
|
||||
export function buildParams(
|
||||
useCurrentTimeRange: boolean,
|
||||
includeTemplateVars: boolean,
|
||||
selectedTheme?: string,
|
||||
panel?: PanelModel
|
||||
) {
|
||||
export function buildParams(useCurrentTimeRange: boolean, selectedTheme?: string, panel?: PanelModel) {
|
||||
let params = urlUtil.getUrlSearchParams();
|
||||
|
||||
const range = getTimeSrv().timeRange();
|
||||
@ -22,13 +16,6 @@ export function buildParams(
|
||||
delete params.to;
|
||||
}
|
||||
|
||||
if (includeTemplateVars) {
|
||||
params = {
|
||||
...params,
|
||||
...getAllVariableValuesForUrl(),
|
||||
};
|
||||
}
|
||||
|
||||
if (selectedTheme !== 'current') {
|
||||
params.theme = selectedTheme;
|
||||
}
|
||||
@ -55,13 +42,12 @@ export function buildBaseUrl() {
|
||||
|
||||
export async function buildShareUrl(
|
||||
useCurrentTimeRange: boolean,
|
||||
includeTemplateVars: boolean,
|
||||
selectedTheme?: string,
|
||||
panel?: PanelModel,
|
||||
shortenUrl?: boolean
|
||||
) {
|
||||
const baseUrl = buildBaseUrl();
|
||||
const params = buildParams(useCurrentTimeRange, includeTemplateVars, selectedTheme, panel);
|
||||
const params = buildParams(useCurrentTimeRange, selectedTheme, panel);
|
||||
const shareUrl = urlUtil.appendQueryToUrl(baseUrl, urlUtil.toUrlParams(params));
|
||||
if (shortenUrl) {
|
||||
return await createShortLink(shareUrl);
|
||||
@ -69,14 +55,9 @@ export async function buildShareUrl(
|
||||
return shareUrl;
|
||||
}
|
||||
|
||||
export function buildSoloUrl(
|
||||
useCurrentTimeRange: boolean,
|
||||
includeTemplateVars: boolean,
|
||||
selectedTheme?: string,
|
||||
panel?: PanelModel
|
||||
) {
|
||||
export function buildSoloUrl(useCurrentTimeRange: boolean, selectedTheme?: string, panel?: PanelModel) {
|
||||
const baseUrl = buildBaseUrl();
|
||||
const params = buildParams(useCurrentTimeRange, includeTemplateVars, selectedTheme, panel);
|
||||
const params = buildParams(useCurrentTimeRange, selectedTheme, panel);
|
||||
|
||||
let soloUrl = baseUrl.replace(config.appSubUrl + '/dashboard/', config.appSubUrl + '/dashboard-solo/');
|
||||
soloUrl = soloUrl.replace(config.appSubUrl + '/d/', config.appSubUrl + '/d-solo/');
|
||||
@ -88,13 +69,8 @@ export function buildSoloUrl(
|
||||
return urlUtil.appendQueryToUrl(soloUrl, urlUtil.toUrlParams(params));
|
||||
}
|
||||
|
||||
export function buildImageUrl(
|
||||
useCurrentTimeRange: boolean,
|
||||
includeTemplateVars: boolean,
|
||||
selectedTheme?: string,
|
||||
panel?: PanelModel
|
||||
) {
|
||||
let soloUrl = buildSoloUrl(useCurrentTimeRange, includeTemplateVars, selectedTheme, panel);
|
||||
export function buildImageUrl(useCurrentTimeRange: boolean, selectedTheme?: string, panel?: PanelModel) {
|
||||
let soloUrl = buildSoloUrl(useCurrentTimeRange, selectedTheme, panel);
|
||||
|
||||
let imageUrl = soloUrl.replace(config.appSubUrl + '/dashboard-solo/', config.appSubUrl + '/render/dashboard-solo/');
|
||||
imageUrl = imageUrl.replace(config.appSubUrl + '/d-solo/', config.appSubUrl + '/render/d-solo/');
|
||||
@ -102,13 +78,8 @@ export function buildImageUrl(
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
export function buildIframeHtml(
|
||||
useCurrentTimeRange: boolean,
|
||||
includeTemplateVars: boolean,
|
||||
selectedTheme?: string,
|
||||
panel?: PanelModel
|
||||
) {
|
||||
let soloUrl = buildSoloUrl(useCurrentTimeRange, includeTemplateVars, selectedTheme, panel);
|
||||
export function buildIframeHtml(useCurrentTimeRange: boolean, selectedTheme?: string, panel?: PanelModel) {
|
||||
let soloUrl = buildSoloUrl(useCurrentTimeRange, selectedTheme, panel);
|
||||
return '<iframe src="' + soloUrl + '" width="450" height="200" frameborder="0"></iframe>';
|
||||
}
|
||||
|
||||
|
@ -127,12 +127,6 @@
|
||||
}
|
||||
|
||||
.share-modal-body {
|
||||
padding: 10px 0;
|
||||
|
||||
.tight-form {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.share-modal-options {
|
||||
margin: 11px 0px 33px 0px;
|
||||
display: inline-block;
|
||||
@ -160,10 +154,6 @@
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.tight-form {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.share-modal-link {
|
||||
max-width: 716px;
|
||||
white-space: nowrap;
|
||||
|
Loading…
Reference in New Issue
Block a user