diff --git a/kibana-reports/kibana.json b/kibana-reports/kibana.json index a08a18af..3d6d9969 100644 --- a/kibana-reports/kibana.json +++ b/kibana-reports/kibana.json @@ -2,7 +2,7 @@ "id": "opendistro_kibana_reports", "version": "1.11.0.0", "kibanaVersion": "7.9.1", - "requiredPlugins": ["navigation", "data"], + "requiredPlugins": ["navigation", "data", "kibanaUtils"], "optionalPlugins": ["share"], "server": true, "ui": true diff --git a/kibana-reports/public/components/context_menu/context_menu.js b/kibana-reports/public/components/context_menu/context_menu.js index dd8a4df2..d1f9aa31 100644 --- a/kibana-reports/public/components/context_menu/context_menu.js +++ b/kibana-reports/public/components/context_menu/context_menu.js @@ -23,6 +23,7 @@ import { displayLoadingModal, addSuccessOrFailureToast, contextMenuViewReports, + replaceQueryURL, } from './context_menu_helpers'; import { popoverMenu, @@ -32,25 +33,7 @@ import { import uuidv4 from 'uuid/v4'; import { timeRangeMatcher } from '../utils/utils'; import { parse } from 'url'; - -const replaceQueryURL = () => { - let url = location.pathname + location.hash; - let [, fromDateString, toDateString] = url.match(timeRangeMatcher); - fromDateString = fromDateString.replace(/[']+/g, ''); - - // convert time range to from date format in case time range is relative - const fromDateFormat = dateMath.parse(fromDateString); - toDateString = toDateString.replace(/[']+/g, ''); - let toDateFormat = dateMath.parse(toDateString); - - // replace to and from dates with absolute date - url = url.replace(fromDateString, "'" + fromDateFormat.toISOString() + "'"); - url = url.replace( - toDateString + '))', - "'" + toDateFormat.toISOString() + "'))" - ); - return url; -}; +import { unhashUrl } from '../../../../../src/plugins/kibana_utils/public'; const generateInContextReport = async ( timeRanges, @@ -172,21 +155,21 @@ $(function () { // generate PDF onclick $(document).on('click', '#generatePDF', function () { const timeRanges = getTimeFieldsFromUrl(); - const queryUrl = replaceQueryURL(); + const queryUrl = replaceQueryURL(location.href); generateInContextReport(timeRanges, queryUrl, 'pdf'); }); // generate PNG onclick $(document).on('click', '#generatePNG', function () { const timeRanges = getTimeFieldsFromUrl(); - const queryUrl = replaceQueryURL(); + const queryUrl = replaceQueryURL(location.href); generateInContextReport(timeRanges, queryUrl, 'png'); }); // generate CSV onclick $(document).on('click', '#generateCSV', function () { const timeRanges = getTimeFieldsFromUrl(); - const queryUrl = replaceQueryURL(); + const queryUrl = replaceQueryURL(location.href); const saved_search_id = getUuidFromUrl()[1]; generateInContextReport(timeRanges, queryUrl, 'csv', { saved_search_id }); }); diff --git a/kibana-reports/public/components/context_menu/context_menu_helpers.js b/kibana-reports/public/components/context_menu/context_menu_helpers.js index 6372a9aa..5d7407d0 100644 --- a/kibana-reports/public/components/context_menu/context_menu_helpers.js +++ b/kibana-reports/public/components/context_menu/context_menu_helpers.js @@ -22,6 +22,7 @@ import { permissionsMissingOnGeneration, } from './context_menu_ui'; import { timeRangeMatcher } from '../utils/utils'; +import { unhashUrl } from '../../../../../src/plugins/kibana_utils/public'; const getReportSourceURL = (baseURI) => { let url = baseURI.substr(0, baseURI.indexOf('?')); @@ -52,7 +53,7 @@ export const contextMenuViewReports = () => window.location.assign('opendistro_kibana_reports#/'); export const getTimeFieldsFromUrl = () => { - const url = window.location.href; + const url = unhashUrl(window.location.href); let [, fromDateString, toDateString] = url.match(timeRangeMatcher); fromDateString = fromDateString.replace(/[']+/g, ''); @@ -122,3 +123,28 @@ export const addSuccessOrFailureToast = (status, reportSource) => { } } }; + +export const replaceQueryURL = (pageUrl) => { + // we unhash the url in case Kibana advanced UI setting 'state:storeInSessionStorage' is turned on + const unhashedUrl = new URL(unhashUrl(pageUrl)); + let queryUrl = unhashedUrl.pathname + unhashedUrl.hash; + let [, fromDateString, toDateString] = queryUrl.match(timeRangeMatcher); + fromDateString = fromDateString.replace(/[']+/g, ''); + + // convert time range to from date format in case time range is relative + const fromDateFormat = dateMath.parse(fromDateString); + toDateString = toDateString.replace(/[']+/g, ''); + const toDateFormat = dateMath.parse(toDateString); + + // replace to and from dates with absolute date + queryUrl = queryUrl.replace( + fromDateString, + "'" + fromDateFormat.toISOString() + "'" + ); + queryUrl = queryUrl.replace( + toDateString + '))', + "'" + toDateFormat.toISOString() + "'))" + ); + console.log(`log output queryUrl\n` + queryUrl); + return queryUrl; +}; diff --git a/kibana-reports/public/plugin.ts b/kibana-reports/public/plugin.ts index 7c5ba2e7..43e5ddb4 100644 --- a/kibana-reports/public/plugin.ts +++ b/kibana-reports/public/plugin.ts @@ -26,7 +26,6 @@ import { } from './types'; import './components/context_menu/context_menu'; import { PLUGIN_NAME } from '../common'; - export class OpendistroKibanaReportsPlugin implements Plugin< diff --git a/kibana-reports/server/routes/utils/__tests__/visualReportHelper.test.ts b/kibana-reports/server/routes/utils/__tests__/visualReportHelper.test.ts index ccc2477d..c6bf2533 100644 --- a/kibana-reports/server/routes/utils/__tests__/visualReportHelper.test.ts +++ b/kibana-reports/server/routes/utils/__tests__/visualReportHelper.test.ts @@ -79,7 +79,7 @@ describe.skip('test create visual report', () => { expect(fileName).toContain(`${reportParams.report_name}`); expect(fileName).toContain('.png'); expect(dataUrl).toBeDefined(); - }, 30000); + }, 60000); test('create pdf report', async () => { expect.assertions(3); @@ -94,5 +94,5 @@ describe.skip('test create visual report', () => { expect(fileName).toContain(`${reportParams.report_name}`); expect(fileName).toContain('.pdf'); expect(dataUrl).toBeDefined(); - }, 30000); + }, 60000); }); diff --git a/kibana-reports/server/routes/utils/visual_report/visualReportHelper.ts b/kibana-reports/server/routes/utils/visual_report/visualReportHelper.ts index a6e83dfb..f757193e 100644 --- a/kibana-reports/server/routes/utils/visual_report/visualReportHelper.ts +++ b/kibana-reports/server/routes/utils/visual_report/visualReportHelper.ts @@ -58,24 +58,34 @@ export const createVisualReport = async ( ? DOMPurify.sanitize(header) : DEFAULT_REPORT_HEADER; const reportFooter = footer ? DOMPurify.sanitize(footer) : ''; - + // add waitForDynamicContent function - const waitForDynamicContent = async(page, timeout = 30000, interval = 1000, checks = 5) => { - const maxChecks = timeout / interval; - let passedChecks = 0; + const waitForDynamicContent = async ( + page, + timeout = 30000, + interval = 1000, + checks = 5 + ) => { + const maxChecks = timeout / interval; + let passedChecks = 0; let previousLength = 0; - - let i=0; while(i++ <= maxChecks){ - let pageContent = await page.content(); + + let i = 0; + while (i++ <= maxChecks) { + let pageContent = await page.content(); let currentLength = pageContent.length; - - (previousLength === 0 || previousLength != currentLength) ? passedChecks = 0 : passedChecks++; - if (passedChecks >= checks) { break; } - + + previousLength === 0 || previousLength != currentLength + ? (passedChecks = 0) + : passedChecks++; + if (passedChecks >= checks) { + break; + } + previousLength = currentLength; await page.waitFor(interval); } - } + }; // set up puppeteer const browser = await puppeteer.launch({ @@ -150,7 +160,7 @@ export const createVisualReport = async ( `report source can only be one of [Dashboard, Visualization]` ); } - + // wait for dynamic page content to render await waitForDynamicContent(page);