mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 22:57:16 +08:00
Share Button: Added ClipboardItem route after Safari issues (#107925)
* Share Button: Added ClipboardItem route after Safari issues * Removed console log * Feedback fixes * Test feedback fix * Removed export
This commit is contained in:
@ -15,6 +15,17 @@ jest.mock('@grafana/runtime', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
Object.assign(navigator, {
|
||||
clipboard: {
|
||||
write: jest.fn().mockResolvedValue(undefined),
|
||||
writeText: jest.fn().mockResolvedValue(undefined),
|
||||
},
|
||||
});
|
||||
|
||||
document.execCommand = jest.fn();
|
||||
});
|
||||
|
||||
describe('createShortLink', () => {
|
||||
it('creates short link', async () => {
|
||||
const shortUrl = await createShortLink('www.verylonglinkwehavehere.com');
|
||||
@ -23,11 +34,34 @@ describe('createShortLink', () => {
|
||||
});
|
||||
|
||||
describe('createAndCopyShortLink', () => {
|
||||
it('copies short link to clipboard', async () => {
|
||||
it('copies short link to clipboard via document.execCommand when navigator.clipboard is undefined', async () => {
|
||||
Object.assign(navigator, {
|
||||
clipboard: {
|
||||
write: undefined,
|
||||
},
|
||||
});
|
||||
document.execCommand = jest.fn();
|
||||
await createAndCopyShortLink('www.verylonglinkwehavehere.com');
|
||||
expect(document.execCommand).toHaveBeenCalledWith('copy');
|
||||
});
|
||||
|
||||
it('copies short link to clipboard via navigator.clipboard.writeText when ClipboardItem is undefined', async () => {
|
||||
window.isSecureContext = true;
|
||||
await createAndCopyShortLink('www.verylonglinkwehavehere.com');
|
||||
expect(navigator.clipboard.writeText).toHaveBeenCalledWith('www.short.com');
|
||||
});
|
||||
|
||||
it('copies short link to clipboard via navigator.clipboard.write and ClipboardItem when it is defined', async () => {
|
||||
global.ClipboardItem = jest.fn().mockImplementation(() => ({
|
||||
type: 'text/plain',
|
||||
size: 0,
|
||||
slice: jest.fn(),
|
||||
supports: jest.fn().mockReturnValue(true),
|
||||
// eslint-disable-next-line
|
||||
})) as any;
|
||||
await createAndCopyShortLink('www.verylonglinkwehavehere.com');
|
||||
expect(navigator.clipboard.write).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLogsPermalinkRange', () => {
|
||||
|
@ -35,13 +35,30 @@ export const createShortLink = memoizeOne(async function (path: string) {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates a ClipboardItem for the shortened link. This is used due to clipboard issues in Safari after making async calls.
|
||||
* See https://github.com/grafana/grafana/issues/106889
|
||||
* @param path - The long path to share.
|
||||
* @returns A ClipboardItem for the shortened link.
|
||||
*/
|
||||
const createShortLinkClipboardItem = (path: string) => {
|
||||
return new ClipboardItem({
|
||||
'text/plain': createShortLink(path),
|
||||
});
|
||||
};
|
||||
|
||||
export const createAndCopyShortLink = async (path: string) => {
|
||||
const shortLink = await createShortLink(path);
|
||||
if (shortLink) {
|
||||
copyStringToClipboard(shortLink);
|
||||
if (typeof ClipboardItem !== 'undefined' && navigator.clipboard.write) {
|
||||
navigator.clipboard.write([createShortLinkClipboardItem(path)]);
|
||||
dispatch(notifyApp(createSuccessNotification('Shortened link copied to clipboard')));
|
||||
} else {
|
||||
dispatch(notifyApp(createErrorNotification('Error generating shortened link')));
|
||||
const shortLink = await createShortLink(path);
|
||||
if (shortLink) {
|
||||
copyStringToClipboard(shortLink);
|
||||
dispatch(notifyApp(createSuccessNotification('Shortened link copied to clipboard')));
|
||||
} else {
|
||||
dispatch(notifyApp(createErrorNotification('Error generating shortened link')));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -15,7 +15,7 @@ const newShareButtonSelector = e2eSelectors.pages.Dashboard.DashNav.newShareButt
|
||||
export const ShareDashboardButton = ({ dashboard }: ToolbarActionProps) => {
|
||||
const [_, buildUrl] = useAsyncFn(async () => {
|
||||
DashboardInteractions.toolbarShareClick();
|
||||
return await buildShareUrl(dashboard);
|
||||
await buildShareUrl(dashboard);
|
||||
}, [dashboard]);
|
||||
|
||||
return (
|
||||
|
@ -22,8 +22,8 @@ export default function ShareButton({ dashboard, panel }: { dashboard: Dashboard
|
||||
|
||||
const [_, buildUrl] = useAsyncFn(async () => {
|
||||
DashboardInteractions.toolbarShareClick();
|
||||
return await buildShareUrl(dashboard, panel);
|
||||
}, [dashboard]);
|
||||
await buildShareUrl(dashboard, panel);
|
||||
}, [dashboard, panel]);
|
||||
|
||||
const onMenuClick = useCallback((isOpen: boolean) => {
|
||||
if (isOpen) {
|
||||
|
Reference in New Issue
Block a user