From ed7703c1f73b148fce0799149fb4d80f0aee29b6 Mon Sep 17 00:00:00 2001 From: Joel Griffith Date: Thu, 30 Jan 2020 14:39:54 -0800 Subject: [PATCH] [Reporting] New Platform: moves most of our libs/constants and utils to np shims (#55935) * Moves a majority of our UI lib/component and utils to np shims * Fixing some slight np differences from legacy * Mostly shimmed client, save for a few APIs and routing * Fixing canvas job notifier * Un-needed typedef file Co-authored-by: Elastic Machine --- .../workpad_header/workpad_export/index.ts | 2 +- .../plugins/reporting/common/constants.ts | 3 ++ .../components/reporting_panel_content.tsx | 11 ++--- .../reporting/public/lib/download_report.ts | 6 ++- .../lib/job_completion_notifications.d.ts | 13 ----- .../lib/job_completion_notifications.js | 35 ------------- .../lib/job_completion_notifications.ts | 36 ++++++++++++++ .../reporting/public/lib/job_queue_client.ts | 26 ++++------ .../reporting/public/lib/reporting_client.ts | 49 +++++++++---------- .../panel_actions/get_csv_panel_action.tsx | 28 ++++------- .../share_context_menu/register_reporting.tsx | 20 +++++--- 11 files changed, 105 insertions(+), 124 deletions(-) delete mode 100644 x-pack/legacy/plugins/reporting/public/lib/job_completion_notifications.d.ts delete mode 100644 x-pack/legacy/plugins/reporting/public/lib/job_completion_notifications.js create mode 100644 x-pack/legacy/plugins/reporting/public/lib/job_completion_notifications.ts diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/index.ts b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/index.ts index 39611dd6c2994..7f81adad6bf9b 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/index.ts +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/index.ts @@ -6,7 +6,7 @@ import { connect } from 'react-redux'; import { compose, withProps } from 'recompose'; -import { jobCompletionNotifications } from '../../../../../reporting/public/lib/job_completion_notifications'; +import * as jobCompletionNotifications from '../../../../../reporting/public/lib/job_completion_notifications'; // @ts-ignore Untyped local import { getWorkpad, getPages } from '../../../state/selectors/workpad'; // @ts-ignore Untyped local diff --git a/x-pack/legacy/plugins/reporting/common/constants.ts b/x-pack/legacy/plugins/reporting/common/constants.ts index e602d5fc608d3..1746345879192 100644 --- a/x-pack/legacy/plugins/reporting/common/constants.ts +++ b/x-pack/legacy/plugins/reporting/common/constants.ts @@ -14,8 +14,11 @@ export const JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY = export const API_BASE_URL = '/api/reporting'; // "Generation URL" from share menu export const API_BASE_URL_V1 = '/api/reporting/v1'; // export const API_BASE_GENERATE_V1 = `${API_BASE_URL_V1}/generate`; +export const API_LIST_URL = '/api/reporting/jobs'; +export const API_GENERATE_IMMEDIATE = `${API_BASE_URL_V1}/generate/immediate/csv/saved-object`; export const CONTENT_TYPE_CSV = 'text/csv'; +export const CSV_REPORTING_ACTION = 'downloadCsvReport'; export const WHITELISTED_JOB_CONTENT_TYPES = [ 'application/json', diff --git a/x-pack/legacy/plugins/reporting/public/components/reporting_panel_content.tsx b/x-pack/legacy/plugins/reporting/public/components/reporting_panel_content.tsx index ac966ceb99736..aaf4021302a97 100644 --- a/x-pack/legacy/plugins/reporting/public/components/reporting_panel_content.tsx +++ b/x-pack/legacy/plugins/reporting/public/components/reporting_panel_content.tsx @@ -7,11 +7,10 @@ import { EuiButton, EuiCopy, EuiForm, EuiFormRow, EuiSpacer, EuiText } from '@elastic/eui'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import React, { Component, ReactElement } from 'react'; -import { KFetchError } from 'ui/kfetch/kfetch_error'; import { toastNotifications } from 'ui/notify'; import url from 'url'; import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public'; -import { reportingClient } from '../lib/reporting_client'; +import * as reportingClient from '../lib/reporting_client'; interface Props { reportType: string; @@ -217,8 +216,8 @@ class ReportingPanelContentUi extends Component { }); this.props.onClose(); }) - .catch((kfetchError: KFetchError) => { - if (kfetchError.message === 'not exportable') { + .catch((error: any) => { + if (error.message === 'not exportable') { return toastNotifications.addWarning({ title: intl.formatMessage( { @@ -237,7 +236,7 @@ class ReportingPanelContentUi extends Component { } const defaultMessage = - kfetchError.res.status === 403 ? ( + error?.res?.status === 403 ? ( { id: 'xpack.reporting.panelContent.notification.reportingErrorTitle', defaultMessage: 'Reporting error', }), - text: toMountPoint(kfetchError.message || defaultMessage), + text: toMountPoint(error.message || defaultMessage), 'data-test-subj': 'queueReportError', }); }); diff --git a/x-pack/legacy/plugins/reporting/public/lib/download_report.ts b/x-pack/legacy/plugins/reporting/public/lib/download_report.ts index 18bae64f8788d..54194c87afabc 100644 --- a/x-pack/legacy/plugins/reporting/public/lib/download_report.ts +++ b/x-pack/legacy/plugins/reporting/public/lib/download_report.ts @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import chrome from 'ui/chrome'; +import { npStart } from 'ui/new_platform'; import { API_BASE_URL } from '../../common/constants'; +const { core } = npStart; + export function getReportURL(jobId: string) { - const apiBaseUrl = chrome.addBasePath(API_BASE_URL); + const apiBaseUrl = core.http.basePath.prepend(API_BASE_URL); const downloadLink = `${apiBaseUrl}/jobs/download/${jobId}`; return downloadLink; diff --git a/x-pack/legacy/plugins/reporting/public/lib/job_completion_notifications.d.ts b/x-pack/legacy/plugins/reporting/public/lib/job_completion_notifications.d.ts deleted file mode 100644 index 3eacc3046e15a..0000000000000 --- a/x-pack/legacy/plugins/reporting/public/lib/job_completion_notifications.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -declare class JobCompletionNotifications { - public add(jobId: string): void; -} - -declare const jobCompletionNotifications: JobCompletionNotifications; - -export { jobCompletionNotifications }; diff --git a/x-pack/legacy/plugins/reporting/public/lib/job_completion_notifications.js b/x-pack/legacy/plugins/reporting/public/lib/job_completion_notifications.js deleted file mode 100644 index 786082638757e..0000000000000 --- a/x-pack/legacy/plugins/reporting/public/lib/job_completion_notifications.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY } from '../../common/constants'; - -export const jobCompletionNotifications = { - add(jobId) { - const jobs = this.getAll(); - jobs.push(jobId); - this._set(jobs); - }, - - getAll() { - const sessionValue = sessionStorage.getItem(JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY); - return sessionValue ? JSON.parse(sessionValue) : []; - }, - - remove(jobId) { - const jobs = this.getAll(); - const index = jobs.indexOf(jobId); - if (!index) { - throw new Error('Unable to find job to remove it'); - } - - jobs.splice(index, 1); - this._set(jobs); - }, - - _set(jobs) { - sessionStorage.setItem(JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY, JSON.stringify(jobs)); - }, -}; diff --git a/x-pack/legacy/plugins/reporting/public/lib/job_completion_notifications.ts b/x-pack/legacy/plugins/reporting/public/lib/job_completion_notifications.ts new file mode 100644 index 0000000000000..3a61bc1e5a044 --- /dev/null +++ b/x-pack/legacy/plugins/reporting/public/lib/job_completion_notifications.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY } from '../../common/constants'; + +type jobId = string; + +const set = (jobs: any) => { + sessionStorage.setItem(JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY, JSON.stringify(jobs)); +}; + +const getAll = () => { + const sessionValue = sessionStorage.getItem(JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY); + return sessionValue ? JSON.parse(sessionValue) : []; +}; + +export const add = (jobId: jobId) => { + const jobs = getAll(); + jobs.push(jobId); + set(jobs); +}; + +export const remove = (jobId: jobId) => { + const jobs = getAll(); + const index = jobs.indexOf(jobId); + + if (!index) { + throw new Error('Unable to find job to remove it'); + } + + jobs.splice(index, 1); + set(jobs); +}; diff --git a/x-pack/legacy/plugins/reporting/public/lib/job_queue_client.ts b/x-pack/legacy/plugins/reporting/public/lib/job_queue_client.ts index 0f68c56a18bf6..281a2e1cdf9a5 100644 --- a/x-pack/legacy/plugins/reporting/public/lib/job_queue_client.ts +++ b/x-pack/legacy/plugins/reporting/public/lib/job_queue_client.ts @@ -4,9 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { kfetch } from 'ui/kfetch'; +import { npStart } from 'ui/new_platform'; +import { API_LIST_URL } from '../../common/constants'; -const API_BASE_URL = '/api/reporting/jobs'; +const { core } = npStart; export interface JobQueueEntry { _id: string; @@ -52,40 +53,33 @@ export interface JobInfo { } class JobQueueClient { - public list = (page = 0, jobIds?: string[]): Promise => { + public list = (page = 0, jobIds: string[] = []): Promise => { const query = { page } as any; - if (jobIds && jobIds.length > 0) { + if (jobIds.length > 0) { // Only getting the first 10, to prevent URL overflows query.ids = jobIds.slice(0, 10).join(','); } - return kfetch({ - method: 'GET', - pathname: `${API_BASE_URL}/list`, + + return core.http.get(`${API_LIST_URL}/list`, { query, asSystemRequest: true, }); }; public total(): Promise { - return kfetch({ - method: 'GET', - pathname: `${API_BASE_URL}/count`, + return core.http.get(`${API_LIST_URL}/count`, { asSystemRequest: true, }); } public getContent(jobId: string): Promise { - return kfetch({ - method: 'GET', - pathname: `${API_BASE_URL}/output/${jobId}`, + return core.http.get(`${API_LIST_URL}/output/${jobId}`, { asSystemRequest: true, }); } public getInfo(jobId: string): Promise { - return kfetch({ - method: 'GET', - pathname: `${API_BASE_URL}/info/${jobId}`, + return core.http.get(`${API_LIST_URL}/info/${jobId}`, { asSystemRequest: true, }); } diff --git a/x-pack/legacy/plugins/reporting/public/lib/reporting_client.ts b/x-pack/legacy/plugins/reporting/public/lib/reporting_client.ts index b9574dfa457f3..9056c7967b4a8 100644 --- a/x-pack/legacy/plugins/reporting/public/lib/reporting_client.ts +++ b/x-pack/legacy/plugins/reporting/public/lib/reporting_client.ts @@ -4,13 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { kfetch } from 'ui/kfetch'; +import { npStart } from 'ui/new_platform'; +import querystring from 'querystring'; + +const { core } = npStart; // @ts-ignore import rison from 'rison-node'; -import chrome from 'ui/chrome'; -import { QueryString } from 'ui/utils/query_string'; -import { jobCompletionNotifications } from './job_completion_notifications'; +import { add } from './job_completion_notifications'; const API_BASE_URL = '/api/reporting/generate'; @@ -18,26 +19,22 @@ interface JobParams { [paramName: string]: any; } -class ReportingClient { - public getReportingJobPath = (exportType: string, jobParams: JobParams) => { - return `${chrome.addBasePath(API_BASE_URL)}/${exportType}?${QueryString.param( - 'jobParams', - rison.encode(jobParams) - )}`; - }; - - public createReportingJob = async (exportType: string, jobParams: any) => { - const jobParamsRison = rison.encode(jobParams); - const resp = await kfetch({ - method: 'POST', - pathname: `${API_BASE_URL}/${exportType}`, - body: JSON.stringify({ - jobParams: jobParamsRison, - }), - }); - jobCompletionNotifications.add(resp.job.id); - return resp; - }; -} +export const getReportingJobPath = (exportType: string, jobParams: JobParams) => { + const params = querystring.stringify({ jobParams: rison.encode(jobParams) }); + + return `${core.http.basePath.prepend(API_BASE_URL)}/${exportType}?${params}`; +}; + +export const createReportingJob = async (exportType: string, jobParams: any) => { + const jobParamsRison = rison.encode(jobParams); + const resp = await core.http.post(`${API_BASE_URL}/${exportType}`, { + method: 'POST', + body: JSON.stringify({ + jobParams: jobParamsRison, + }), + }); + + add(resp.job.id); -export const reportingClient = new ReportingClient(); + return resp; +}; diff --git a/x-pack/legacy/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx b/x-pack/legacy/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx index 95ca1792a7eb1..fde053f8dbdfc 100644 --- a/x-pack/legacy/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx +++ b/x-pack/legacy/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx @@ -7,11 +7,7 @@ import dateMath from '@elastic/datemath'; import { i18n } from '@kbn/i18n'; import moment from 'moment-timezone'; -import { kfetch } from 'ui/kfetch'; -import { toastNotifications } from 'ui/notify'; -import chrome from 'ui/chrome'; - -import { npSetup } from 'ui/new_platform'; +import { npSetup, npStart } from 'ui/new_platform'; import { IAction, IncompatibleActionError } from '../../../../../../src/plugins/ui_actions/public'; import { @@ -22,11 +18,9 @@ import { import { SEARCH_EMBEDDABLE_TYPE } from '../../../../../../src/legacy/core_plugins/kibana/public/discover/np_ready/embeddable/constants'; import { ISearchEmbeddable } from '../../../../../../src/legacy/core_plugins/kibana/public/discover/np_ready/embeddable/types'; -import { API_BASE_URL_V1 } from '../../common/constants'; - -const API_BASE_URL = `${API_BASE_URL_V1}/generate/immediate/csv/saved-object`; +import { API_GENERATE_IMMEDIATE, CSV_REPORTING_ACTION } from '../../common/constants'; -const CSV_REPORTING_ACTION = 'downloadCsvReport'; +const { core } = npStart; function isSavedSearchEmbeddable( embeddable: IEmbeddable | ISearchEmbeddable @@ -71,12 +65,6 @@ class GetCsvReportPanelAction implements IAction { } public isCompatible = async (context: ActionContext) => { - const enablePanelActionDownload = chrome.getInjected('enablePanelActionDownload'); - - if (!enablePanelActionDownload) { - return false; - } - const { embeddable } = context; return embeddable.getInput().viewMode !== ViewMode.EDIT && embeddable.type === 'search'; @@ -100,7 +88,7 @@ class GetCsvReportPanelAction implements IAction { const searchEmbeddable = embeddable; const searchRequestBody = await this.getSearchRequestBody({ searchEmbeddable }); const state = _.pick(searchRequestBody, ['sort', 'docvalue_fields', 'query']); - const kibanaTimezone = chrome.getUiSettingsClient().get('dateFormat:tz'); + const kibanaTimezone = core.uiSettings.get('dateFormat:tz'); const id = `search:${embeddable.getSavedSearch().id}`; const filename = embeddable.getTitle(); @@ -125,7 +113,7 @@ class GetCsvReportPanelAction implements IAction { this.isDownloading = true; - toastNotifications.addSuccess({ + core.notifications.toasts.addSuccess({ title: i18n.translate('xpack.reporting.dashboard.csvDownloadStartedTitle', { defaultMessage: `CSV Download Started`, }), @@ -135,7 +123,8 @@ class GetCsvReportPanelAction implements IAction { 'data-test-subj': 'csvDownloadStarted', }); - await kfetch({ method: 'POST', pathname: `${API_BASE_URL}/${id}`, body }) + await core.http + .post(`${API_GENERATE_IMMEDIATE}/${id}`, { body }) .then((rawResponse: string) => { this.isDownloading = false; @@ -162,7 +151,7 @@ class GetCsvReportPanelAction implements IAction { private onGenerationFail(error: Error) { this.isDownloading = false; - toastNotifications.addDanger({ + core.notifications.toasts.addDanger({ title: i18n.translate('xpack.reporting.dashboard.failedCsvDownloadTitle', { defaultMessage: `CSV download failed`, }), @@ -175,5 +164,6 @@ class GetCsvReportPanelAction implements IAction { } const action = new GetCsvReportPanelAction(); + npSetup.plugins.uiActions.registerAction(action); npSetup.plugins.uiActions.attachAction(CONTEXT_MENU_TRIGGER, action.id); diff --git a/x-pack/legacy/plugins/reporting/public/share_context_menu/register_reporting.tsx b/x-pack/legacy/plugins/reporting/public/share_context_menu/register_reporting.tsx index fb5e74664e6c6..8e0da6a69225e 100644 --- a/x-pack/legacy/plugins/reporting/public/share_context_menu/register_reporting.tsx +++ b/x-pack/legacy/plugins/reporting/public/share_context_menu/register_reporting.tsx @@ -14,6 +14,8 @@ import chrome from 'ui/chrome'; import { ScreenCapturePanelContent } from '../components/screen_capture_panel_content'; import { ShareContext } from '../../../../../../src/plugins/share/public'; +const { core } = npSetup; + async function reportingProvider() { const injector = await chrome.dangerouslyGetActiveInjector(); const getShareMenuItems = ({ @@ -35,12 +37,15 @@ async function reportingProvider() { const getReportingJobParams = () => { // Replace hashes with original RISON values. - const relativeUrl = shareableUrl.replace(window.location.origin + chrome.getBasePath(), ''); + const relativeUrl = shareableUrl.replace( + window.location.origin + core.http.basePath.get(), + '' + ); const browserTimezone = - chrome.getUiSettingsClient().get('dateFormat:tz') === 'Browser' + core.uiSettings.get('dateFormat:tz') === 'Browser' ? moment.tz.guess() - : chrome.getUiSettingsClient().get('dateFormat:tz'); + : core.uiSettings.get('dateFormat:tz'); return { ...sharingData, @@ -52,12 +57,15 @@ async function reportingProvider() { const getPngJobParams = () => { // Replace hashes with original RISON values. - const relativeUrl = shareableUrl.replace(window.location.origin + chrome.getBasePath(), ''); + const relativeUrl = shareableUrl.replace( + window.location.origin + core.http.basePath.get(), + '' + ); const browserTimezone = - chrome.getUiSettingsClient().get('dateFormat:tz') === 'Browser' + core.uiSettings.get('dateFormat:tz') === 'Browser' ? moment.tz.guess() - : chrome.getUiSettingsClient().get('dateFormat:tz'); + : core.uiSettings.get('dateFormat:tz'); return { ...sharingData,