mirror of
https://github.com/grafana/grafana.git
synced 2025-07-31 06:02:24 +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', () => {
|
describe('createShortLink', () => {
|
||||||
it('creates short link', async () => {
|
it('creates short link', async () => {
|
||||||
const shortUrl = await createShortLink('www.verylonglinkwehavehere.com');
|
const shortUrl = await createShortLink('www.verylonglinkwehavehere.com');
|
||||||
@ -23,11 +34,34 @@ describe('createShortLink', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('createAndCopyShortLink', () => {
|
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();
|
document.execCommand = jest.fn();
|
||||||
await createAndCopyShortLink('www.verylonglinkwehavehere.com');
|
await createAndCopyShortLink('www.verylonglinkwehavehere.com');
|
||||||
expect(document.execCommand).toHaveBeenCalledWith('copy');
|
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', () => {
|
describe('getLogsPermalinkRange', () => {
|
||||||
|
@ -35,7 +35,23 @@ 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) => {
|
export const createAndCopyShortLink = async (path: string) => {
|
||||||
|
if (typeof ClipboardItem !== 'undefined' && navigator.clipboard.write) {
|
||||||
|
navigator.clipboard.write([createShortLinkClipboardItem(path)]);
|
||||||
|
dispatch(notifyApp(createSuccessNotification('Shortened link copied to clipboard')));
|
||||||
|
} else {
|
||||||
const shortLink = await createShortLink(path);
|
const shortLink = await createShortLink(path);
|
||||||
if (shortLink) {
|
if (shortLink) {
|
||||||
copyStringToClipboard(shortLink);
|
copyStringToClipboard(shortLink);
|
||||||
@ -43,6 +59,7 @@ export const createAndCopyShortLink = async (path: string) => {
|
|||||||
} else {
|
} else {
|
||||||
dispatch(notifyApp(createErrorNotification('Error generating shortened link')));
|
dispatch(notifyApp(createErrorNotification('Error generating shortened link')));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createAndCopyShareDashboardLink = async (
|
export const createAndCopyShareDashboardLink = async (
|
||||||
|
@ -15,7 +15,7 @@ const newShareButtonSelector = e2eSelectors.pages.Dashboard.DashNav.newShareButt
|
|||||||
export const ShareDashboardButton = ({ dashboard }: ToolbarActionProps) => {
|
export const ShareDashboardButton = ({ dashboard }: ToolbarActionProps) => {
|
||||||
const [_, buildUrl] = useAsyncFn(async () => {
|
const [_, buildUrl] = useAsyncFn(async () => {
|
||||||
DashboardInteractions.toolbarShareClick();
|
DashboardInteractions.toolbarShareClick();
|
||||||
return await buildShareUrl(dashboard);
|
await buildShareUrl(dashboard);
|
||||||
}, [dashboard]);
|
}, [dashboard]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -22,8 +22,8 @@ export default function ShareButton({ dashboard, panel }: { dashboard: Dashboard
|
|||||||
|
|
||||||
const [_, buildUrl] = useAsyncFn(async () => {
|
const [_, buildUrl] = useAsyncFn(async () => {
|
||||||
DashboardInteractions.toolbarShareClick();
|
DashboardInteractions.toolbarShareClick();
|
||||||
return await buildShareUrl(dashboard, panel);
|
await buildShareUrl(dashboard, panel);
|
||||||
}, [dashboard]);
|
}, [dashboard, panel]);
|
||||||
|
|
||||||
const onMenuClick = useCallback((isOpen: boolean) => {
|
const onMenuClick = useCallback((isOpen: boolean) => {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
|
Reference in New Issue
Block a user