mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 02:09:32 -04:00
# Backport This will backport the following commits from `main` to `8.x`: - [[Dashboard] Fix share dashboard iframe embed code incorrectly (#194366)](https://github.com/elastic/kibana/pull/194366) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Jusheng Huang","email":"117657272+viajes7@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-10-03T00:24:46Z","message":"[Dashboard] Fix share dashboard iframe embed code incorrectly (#194366)\n\n## Summary\r\n\r\nFixes [#192980](https://github.com/elastic/kibana/issues/193447)\r\n\r\nMaybe related pr: #179037 \r\n\r\nAfter fix it, having an URL that is like this:\r\n```\r\n?embed=true&_g=(refreshInterval%3A(pause%3A!t%2Cvalue%3A60000)%2Ctime%3A(from%3Anow-15m%2Cto%3Anow))&hide-filter-bar=true\r\n```\r\n\r\n**Screenshot**\r\n<img width=\"1918\" alt=\"image\"\r\nsrc=\"https://github.com/user-attachments/assets/de069fdb-895e-479a-b868-891bbb55594e\">\r\n\r\n---------\r\n\r\nCo-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>\r\nCo-authored-by: Tim Sullivan <tsullivan@users.noreply.github.com>","sha":"e4ff3bb44874f77a63c24de998fde2f6d7ac9404","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","💝community","v9.0.0","Team:SharedUX","v8.16.0","backport:version","v8.15.3"],"title":"[Dashboard] Fix share dashboard iframe embed code incorrectly","number":194366,"url":"https://github.com/elastic/kibana/pull/194366","mergeCommit":{"message":"[Dashboard] Fix share dashboard iframe embed code incorrectly (#194366)\n\n## Summary\r\n\r\nFixes [#192980](https://github.com/elastic/kibana/issues/193447)\r\n\r\nMaybe related pr: #179037 \r\n\r\nAfter fix it, having an URL that is like this:\r\n```\r\n?embed=true&_g=(refreshInterval%3A(pause%3A!t%2Cvalue%3A60000)%2Ctime%3A(from%3Anow-15m%2Cto%3Anow))&hide-filter-bar=true\r\n```\r\n\r\n**Screenshot**\r\n<img width=\"1918\" alt=\"image\"\r\nsrc=\"https://github.com/user-attachments/assets/de069fdb-895e-479a-b868-891bbb55594e\">\r\n\r\n---------\r\n\r\nCo-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>\r\nCo-authored-by: Tim Sullivan <tsullivan@users.noreply.github.com>","sha":"e4ff3bb44874f77a63c24de998fde2f6d7ac9404"}},"sourceBranch":"main","suggestedTargetBranches":["8.x","8.15"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/194366","number":194366,"mergeCommit":{"message":"[Dashboard] Fix share dashboard iframe embed code incorrectly (#194366)\n\n## Summary\r\n\r\nFixes [#192980](https://github.com/elastic/kibana/issues/193447)\r\n\r\nMaybe related pr: #179037 \r\n\r\nAfter fix it, having an URL that is like this:\r\n```\r\n?embed=true&_g=(refreshInterval%3A(pause%3A!t%2Cvalue%3A60000)%2Ctime%3A(from%3Anow-15m%2Cto%3Anow))&hide-filter-bar=true\r\n```\r\n\r\n**Screenshot**\r\n<img width=\"1918\" alt=\"image\"\r\nsrc=\"https://github.com/user-attachments/assets/de069fdb-895e-479a-b868-891bbb55594e\">\r\n\r\n---------\r\n\r\nCo-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>\r\nCo-authored-by: Tim Sullivan <tsullivan@users.noreply.github.com>","sha":"e4ff3bb44874f77a63c24de998fde2f6d7ac9404"}},{"branch":"8.x","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.15","label":"v8.15.3","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Jusheng Huang <117657272+viajes7@users.noreply.github.com>
This commit is contained in:
parent
69513090f2
commit
c9cb0fab40
6 changed files with 73 additions and 19 deletions
|
@ -29,7 +29,6 @@ export interface IShareContext extends ShareContext {
|
||||||
anonymousAccess?: AnonymousAccessServiceContract;
|
anonymousAccess?: AnonymousAccessServiceContract;
|
||||||
urlService: BrowserUrlService;
|
urlService: BrowserUrlService;
|
||||||
snapshotShareWarning?: string;
|
snapshotShareWarning?: string;
|
||||||
isEmbedded: boolean;
|
|
||||||
theme: ThemeServiceSetup;
|
theme: ThemeServiceSetup;
|
||||||
i18n: I18nStart;
|
i18n: I18nStart;
|
||||||
publicAPIEnabled?: boolean;
|
publicAPIEnabled?: boolean;
|
||||||
|
|
|
@ -53,7 +53,6 @@ const mockShareContext = {
|
||||||
allowShortUrl: true,
|
allowShortUrl: true,
|
||||||
anonymousAccess: { getCapabilities: jest.fn(), getState: jest.fn() },
|
anonymousAccess: { getCapabilities: jest.fn(), getState: jest.fn() },
|
||||||
urlService: service,
|
urlService: service,
|
||||||
isEmbedded: true,
|
|
||||||
theme: themeServiceMock.createStartContract(),
|
theme: themeServiceMock.createStartContract(),
|
||||||
objectTypeMeta: { title: 'title' },
|
objectTypeMeta: { title: 'title' },
|
||||||
objectType: 'type',
|
objectType: 'type',
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the "Elastic License
|
||||||
|
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||||
|
* Public License v 1"; you may not use this file except in compliance with, at
|
||||||
|
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||||
|
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { mountWithIntl } from '@kbn/test-jest-helpers';
|
||||||
|
import { EmbedContent } from './embed_content';
|
||||||
|
import React from 'react';
|
||||||
|
import { ReactWrapper } from 'enzyme';
|
||||||
|
|
||||||
|
describe('Share modal embed content tab', () => {
|
||||||
|
describe('share url embedded', () => {
|
||||||
|
let component: ReactWrapper;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
component = mountWithIntl(
|
||||||
|
<EmbedContent
|
||||||
|
objectType="dashboard"
|
||||||
|
setIsNotSaved={() => jest.fn()}
|
||||||
|
shareableUrl="/home#/"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works for simple url', async () => {
|
||||||
|
component.setProps({ shareableUrl: 'http://localhost:5601/app/home#/' });
|
||||||
|
component.update();
|
||||||
|
|
||||||
|
const shareUrl = component
|
||||||
|
.find('button[data-test-subj="copyEmbedUrlButton"]')
|
||||||
|
.prop('data-share-url');
|
||||||
|
expect(shareUrl).toBe(
|
||||||
|
'<iframe src="http://localhost:5601/app/home#/?embed=true&_g=" height="600" width="800"></iframe>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works if the url has a query string', async () => {
|
||||||
|
component.setProps({
|
||||||
|
shareableUrl:
|
||||||
|
'http://localhost:5601/app/dashboards#/create?_g=(refreshInterval%3A(pause%3A!t%2Cvalue%3A60000)%2Ctime%3A(from%3Anow-15m%2Cto%3Anow))',
|
||||||
|
});
|
||||||
|
component.update();
|
||||||
|
|
||||||
|
const shareUrl = component
|
||||||
|
.find('button[data-test-subj="copyEmbedUrlButton"]')
|
||||||
|
.prop('data-share-url');
|
||||||
|
expect(shareUrl).toBe(
|
||||||
|
'<iframe src="http://localhost:5601/app/dashboards#/create?embed=true&_g=(refreshInterval%3A(pause%3A!t%2Cvalue%3A60000)%2Ctime%3A(from%3Anow-15m%2Cto%3Anow))" height="600" width="800"></iframe>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -30,7 +30,6 @@ type EmbedProps = Pick<
|
||||||
| 'shareableUrlLocatorParams'
|
| 'shareableUrlLocatorParams'
|
||||||
| 'shareableUrlForSavedObject'
|
| 'shareableUrlForSavedObject'
|
||||||
| 'shareableUrl'
|
| 'shareableUrl'
|
||||||
| 'isEmbedded'
|
|
||||||
| 'embedUrlParamExtensions'
|
| 'embedUrlParamExtensions'
|
||||||
| 'objectType'
|
| 'objectType'
|
||||||
> & {
|
> & {
|
||||||
|
@ -52,7 +51,6 @@ export const EmbedContent = ({
|
||||||
embedUrlParamExtensions: urlParamExtensions,
|
embedUrlParamExtensions: urlParamExtensions,
|
||||||
shareableUrlForSavedObject,
|
shareableUrlForSavedObject,
|
||||||
shareableUrl,
|
shareableUrl,
|
||||||
isEmbedded,
|
|
||||||
objectType,
|
objectType,
|
||||||
setIsNotSaved,
|
setIsNotSaved,
|
||||||
}: EmbedProps) => {
|
}: EmbedProps) => {
|
||||||
|
@ -69,6 +67,17 @@ export const EmbedContent = ({
|
||||||
if (objectType !== 'dashboard') setIsNotSaved();
|
if (objectType !== 'dashboard') setIsNotSaved();
|
||||||
}, [url, setIsNotSaved, objectType]);
|
}, [url, setIsNotSaved, objectType]);
|
||||||
|
|
||||||
|
const makeUrlEmbeddable = useCallback((tempUrl: string): string => {
|
||||||
|
const embedParam = '?embed=true';
|
||||||
|
const urlHasQueryString = tempUrl.indexOf('?') !== -1;
|
||||||
|
|
||||||
|
if (urlHasQueryString) {
|
||||||
|
return tempUrl.replace('?', `${embedParam}&`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${tempUrl}${embedParam}`;
|
||||||
|
}, []);
|
||||||
|
|
||||||
const getUrlParamExtensions = useCallback(
|
const getUrlParamExtensions = useCallback(
|
||||||
(tempUrl: string): string => {
|
(tempUrl: string): string => {
|
||||||
return urlParams
|
return urlParams
|
||||||
|
@ -90,10 +99,11 @@ export const EmbedContent = ({
|
||||||
|
|
||||||
const updateUrlParams = useCallback(
|
const updateUrlParams = useCallback(
|
||||||
(tempUrl: string) => {
|
(tempUrl: string) => {
|
||||||
|
tempUrl = makeUrlEmbeddable(tempUrl);
|
||||||
tempUrl = urlParams ? getUrlParamExtensions(tempUrl) : tempUrl;
|
tempUrl = urlParams ? getUrlParamExtensions(tempUrl) : tempUrl;
|
||||||
return tempUrl;
|
return tempUrl;
|
||||||
},
|
},
|
||||||
[getUrlParamExtensions, urlParams]
|
[makeUrlEmbeddable, getUrlParamExtensions, urlParams]
|
||||||
);
|
);
|
||||||
|
|
||||||
const getSnapshotUrl = useCallback(
|
const getSnapshotUrl = useCallback(
|
||||||
|
@ -180,16 +190,14 @@ export const EmbedContent = ({
|
||||||
tempUrl = addUrlAnonymousAccessParameters(tempUrl!);
|
tempUrl = addUrlAnonymousAccessParameters(tempUrl!);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEmbedded) {
|
tempUrl = makeIframeTag(tempUrl!);
|
||||||
tempUrl = makeIframeTag(tempUrl!);
|
|
||||||
}
|
|
||||||
setUrl(tempUrl!);
|
setUrl(tempUrl!);
|
||||||
}, [
|
}, [
|
||||||
addUrlAnonymousAccessParameters,
|
addUrlAnonymousAccessParameters,
|
||||||
exportUrlAs,
|
exportUrlAs,
|
||||||
getSavedObjectUrl,
|
getSavedObjectUrl,
|
||||||
getSnapshotUrl,
|
getSnapshotUrl,
|
||||||
isEmbedded,
|
|
||||||
shortUrlCache,
|
shortUrlCache,
|
||||||
useShortUrl,
|
useShortUrl,
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -38,14 +38,8 @@ const embedTabReducer: IEmbedTab['reducer'] = (state = { url: '', isNotSaved: fa
|
||||||
};
|
};
|
||||||
|
|
||||||
const EmbedTabContent: NonNullable<IEmbedTab['content']> = ({ state, dispatch }) => {
|
const EmbedTabContent: NonNullable<IEmbedTab['content']> = ({ state, dispatch }) => {
|
||||||
const {
|
const { embedUrlParamExtensions, shareableUrlForSavedObject, shareableUrl, objectType, isDirty } =
|
||||||
embedUrlParamExtensions,
|
useShareTabsContext()!;
|
||||||
shareableUrlForSavedObject,
|
|
||||||
shareableUrl,
|
|
||||||
isEmbedded,
|
|
||||||
objectType,
|
|
||||||
isDirty,
|
|
||||||
} = useShareTabsContext()!;
|
|
||||||
|
|
||||||
const setIsNotSaved = useCallback(() => {
|
const setIsNotSaved = useCallback(() => {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -60,7 +54,6 @@ const EmbedTabContent: NonNullable<IEmbedTab['content']> = ({ state, dispatch })
|
||||||
embedUrlParamExtensions,
|
embedUrlParamExtensions,
|
||||||
shareableUrlForSavedObject,
|
shareableUrlForSavedObject,
|
||||||
shareableUrl,
|
shareableUrl,
|
||||||
isEmbedded,
|
|
||||||
objectType,
|
objectType,
|
||||||
isNotSaved: state?.isNotSaved,
|
isNotSaved: state?.isNotSaved,
|
||||||
setIsNotSaved,
|
setIsNotSaved,
|
||||||
|
|
|
@ -129,7 +129,6 @@ export class ShareMenuManager {
|
||||||
snapshotShareWarning,
|
snapshotShareWarning,
|
||||||
disabledShareUrl,
|
disabledShareUrl,
|
||||||
isDirty,
|
isDirty,
|
||||||
isEmbedded: allowEmbed,
|
|
||||||
shareMenuItems: menuItems,
|
shareMenuItems: menuItems,
|
||||||
toasts,
|
toasts,
|
||||||
onClose: () => {
|
onClose: () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue