diff --git a/x-pack/index.js b/x-pack/index.js index 89cbb03f084eb..ab29aaa2a10a2 100644 --- a/x-pack/index.js +++ b/x-pack/index.js @@ -12,7 +12,6 @@ import { dashboardMode } from './legacy/plugins/dashboard_mode'; import { beats } from './legacy/plugins/beats_management'; import { maps } from './legacy/plugins/maps'; import { spaces } from './legacy/plugins/spaces'; -import { canvas } from './legacy/plugins/canvas'; import { infra } from './legacy/plugins/infra'; import { taskManager } from './legacy/plugins/task_manager'; import { encryptedSavedObjects } from './legacy/plugins/encrypted_saved_objects'; @@ -28,7 +27,6 @@ module.exports = function(kibana) { dashboardMode(kibana), beats(kibana), maps(kibana), - canvas(kibana), infra(kibana), taskManager(kibana), encryptedSavedObjects(kibana), diff --git a/x-pack/legacy/plugins/canvas/public/application.tsx b/x-pack/legacy/plugins/canvas/public/application.tsx index f71123cd28b90..8ee65c3386afc 100644 --- a/x-pack/legacy/plugins/canvas/public/application.tsx +++ b/x-pack/legacy/plugins/canvas/public/application.tsx @@ -24,7 +24,7 @@ import { initRegistries, populateRegistries, destroyRegistries } from './registr import { getDocumentationLinks } from './lib/documentation_links'; // @ts-ignore untyped component import { HelpMenu } from './components/help_menu/help_menu'; -import { createStore } from './store'; +import { createStore, destroyStore } from './store'; import { VALUE_CLICK_TRIGGER, ActionByType } from '../../../../../src/plugins/ui_actions/public'; /* eslint-disable */ @@ -35,6 +35,12 @@ import { init as initStatsReporter } from './lib/ui_metric'; import { CapabilitiesStrings } from '../i18n'; import { startServices, stopServices, services } from './services'; +// @ts-ignore Untyped local +import { destroyHistory } from './lib/history_provider'; +// @ts-ignore Untyped local +import { stopRouter } from './lib/router_provider'; + +import './style/index.scss'; const { ReadOnlyBadge: strings } = CapabilitiesStrings; @@ -54,6 +60,8 @@ export const renderApp = ( { element }: AppMountParameters, canvasStore: Store ) => { + element.classList.add('canvas'); + element.classList.add('canvasContainerWrapper'); const canvasServices = Object.entries(services).reduce((reduction, [key, provider]) => { reduction[key] = provider.getService(); @@ -70,7 +78,9 @@ export const renderApp = ( , element ); - return () => ReactDOM.unmountComponentAtNode(element); + return () => { + ReactDOM.unmountComponentAtNode(element); + }; }; export const initializeCanvas = async ( @@ -144,6 +154,7 @@ export const teardownCanvas = (coreStart: CoreStart, startPlugins: CanvasStartDe stopServices(); destroyRegistries(); resetInterpreter(); + destroyStore(); startPlugins.uiActions.detachAction(VALUE_CLICK_TRIGGER, emptyAction.id); if (restoreAction) { @@ -153,4 +164,7 @@ export const teardownCanvas = (coreStart: CoreStart, startPlugins: CanvasStartDe coreStart.chrome.setBadge(undefined); coreStart.chrome.setHelpExtension(undefined); + + destroyHistory(); + stopRouter(); }; diff --git a/x-pack/legacy/plugins/canvas/public/components/app/index.js b/x-pack/legacy/plugins/canvas/public/components/app/index.js index 36af5477631b4..de0d4c190eae6 100644 --- a/x-pack/legacy/plugins/canvas/public/components/app/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/app/index.js @@ -10,7 +10,6 @@ import { getAppReady, getBasePath } from '../../state/selectors/app'; import { appReady, appError } from '../../state/actions/app'; import { App as Component } from './app'; -import { trackRouteChange } from './track_route_change'; const mapStateToProps = state => { // appReady could be an error object @@ -46,6 +45,6 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { export const App = compose( connect(mapStateToProps, mapDispatchToProps, mergeProps), withProps(() => ({ - onRouteChange: trackRouteChange, + onRouteChange: () => undefined, })) )(Component); diff --git a/x-pack/legacy/plugins/canvas/public/legacy.ts b/x-pack/legacy/plugins/canvas/public/legacy.ts index f83887bbcbdfd..f4a2b309b3499 100644 --- a/x-pack/legacy/plugins/canvas/public/legacy.ts +++ b/x-pack/legacy/plugins/canvas/public/legacy.ts @@ -9,7 +9,6 @@ import { CanvasStartDeps, CanvasSetupDeps } from './plugin'; // eslint-disable-l // @ts-ignore Untyped Kibana Lib import chrome, { loadingCount } from 'ui/chrome'; // eslint-disable-line import/order -import { absoluteToParsedUrl } from 'ui/url/absolute_to_parsed_url'; // eslint-disable-line import/order // @ts-ignore Untyped Kibana Lib import { formatMsg } from '../../../../../src/plugins/kibana_legacy/public'; // eslint-disable-line import/order @@ -32,12 +31,6 @@ const shimStartPlugins: CanvasStartDeps = { expressions: npStart.plugins.expressions, inspector: npStart.plugins.inspector, uiActions: npStart.plugins.uiActions, - __LEGACY: { - // ToDo: Copy directly into canvas - absoluteToParsedUrl, - // ToDo: Won't be a part of New Platform. Will need to handle internally - trackSubUrlForApp: chrome.trackSubUrlForApp, - }, }; // These methods are intended to be a replacement for import from 'ui/whatever' diff --git a/x-pack/legacy/plugins/canvas/public/lib/history_provider.js b/x-pack/legacy/plugins/canvas/public/lib/history_provider.js index 59b6b88fa38c3..4ff9f0b9d4605 100644 --- a/x-pack/legacy/plugins/canvas/public/lib/history_provider.js +++ b/x-pack/legacy/plugins/canvas/public/lib/history_provider.js @@ -6,7 +6,7 @@ import lzString from 'lz-string'; import { createMemoryHistory, parsePath, createPath } from 'history'; -import createHashStateHistory from 'history-extra'; +import createHashStateHistory from 'history-extra/dist/createHashStateHistory'; import { getWindow } from './get_window'; function wrapHistoryInstance(history) { @@ -134,7 +134,7 @@ function wrapHistoryInstance(history) { return wrappedHistory; } -const instances = new WeakMap(); +let instances = new WeakMap(); const getHistoryInstance = win => { // if no window object, use memory module @@ -158,3 +158,7 @@ export const historyProvider = (win = getWindow()) => { return wrappedInstance; }; + +export const destroyHistory = () => { + instances = new WeakMap(); +}; diff --git a/x-pack/legacy/plugins/canvas/public/lib/router_provider.js b/x-pack/legacy/plugins/canvas/public/lib/router_provider.js index 134875cce681a..42960baa00de1 100644 --- a/x-pack/legacy/plugins/canvas/public/lib/router_provider.js +++ b/x-pack/legacy/plugins/canvas/public/lib/router_provider.js @@ -110,7 +110,19 @@ export function routerProvider(routes) { return unlisten; // return function to remove change handler }, + stop: () => { + for (const listener of componentListeners) { + listener(); + } + }, }; return router; } + +export const stopRouter = () => { + if (router) { + router.stop(); + router = undefined; + } +}; diff --git a/x-pack/legacy/plugins/canvas/public/plugin.tsx b/x-pack/legacy/plugins/canvas/public/plugin.tsx index baeb4ebd453d2..1e85aad6328a5 100644 --- a/x-pack/legacy/plugins/canvas/public/plugin.tsx +++ b/x-pack/legacy/plugins/canvas/public/plugin.tsx @@ -4,8 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Chrome } from 'ui/chrome'; -import { CoreSetup, CoreStart, Plugin } from '../../../../../src/core/public'; +import { + CoreSetup, + CoreStart, + Plugin, + AppMountParameters, + DEFAULT_APP_CATEGORIES, +} from '../../../../../src/core/public'; import { HomePublicPluginSetup } from '../../../../../src/plugins/home/public'; import { initLoadingIndicator } from './lib/loading_indicator'; import { featureCatalogueEntry } from './feature_catalogue_entry'; @@ -40,12 +45,7 @@ export interface CanvasStartDeps { embeddable: EmbeddableStart; expressions: ExpressionsStart; inspector: InspectorStart; - uiActions: UiActionsStart; - __LEGACY: { - absoluteToParsedUrl: (url: string, basePath: string) => any; - trackSubUrlForApp: Chrome['trackSubUrlForApp']; - }; } /** @@ -63,7 +63,6 @@ export class CanvasPlugin implements Plugin { // TODO: Do we want to completely move canvas_plugin_src into it's own plugin? private srcPlugin = new CanvasSrcPlugin(); - private startPlugins: CanvasStartDeps | undefined; public setup(core: CoreSetup, plugins: CanvasSetupDeps) { const { api: canvasApi, registries } = getPluginApi(plugins.expressions); @@ -71,28 +70,19 @@ export class CanvasPlugin this.srcPlugin.setup(core, { canvas: canvasApi }); core.application.register({ + category: DEFAULT_APP_CATEGORIES.analyze, id: 'canvas', - title: 'Canvas App', - mount: async (context, params) => { + title: 'Canvas', + euiIconType: 'canvasApp', + order: 0, // need to figure out if this is the proper order for us + mount: async (params: AppMountParameters) => { // Load application bundle const { renderApp, initializeCanvas, teardownCanvas } = await import('./application'); // Get start services const [coreStart, depsStart] = await core.getStartServices(); - // TODO: We only need this to get the __LEGACY stuff that isn't coming from getStartSevices. - // We won't need this as soon as we move over to NP Completely - if (!this.startPlugins) { - throw new Error('Start Plugins not ready at mount time'); - } - - const canvasStore = await initializeCanvas( - core, - coreStart, - plugins, - this.startPlugins, - registries - ); + const canvasStore = await initializeCanvas(core, coreStart, plugins, depsStart, registries); const unmount = renderApp(coreStart, depsStart, params, canvasStore); @@ -127,7 +117,6 @@ export class CanvasPlugin } public start(core: CoreStart, plugins: CanvasStartDeps) { - this.startPlugins = plugins; this.srcPlugin.start(core, plugins); initLoadingIndicator(core.http.addLoadingCountSource); } diff --git a/x-pack/legacy/plugins/canvas/public/state/actions/elements.js b/x-pack/legacy/plugins/canvas/public/state/actions/elements.js index f4a3393b8962d..5ec8eb6137f2b 100644 --- a/x-pack/legacy/plugins/canvas/public/state/actions/elements.js +++ b/x-pack/legacy/plugins/canvas/public/state/actions/elements.js @@ -5,7 +5,7 @@ */ import { createAction } from 'redux-actions'; -import { createThunk } from 'redux-thunks'; +import { createThunk } from 'redux-thunks/cjs'; import immutable from 'object-path-immutable'; import { get, pick, cloneDeep, without } from 'lodash'; import { toExpression, safeElementFromExpression } from '@kbn/interpreter/common'; @@ -116,7 +116,6 @@ export const fetchContext = createThunk( const fetchRenderableWithContextFn = ({ dispatch }, element, ast, context) => { const argumentPath = [element.id, 'expressionRenderable']; - dispatch( args.setLoading({ path: argumentPath, diff --git a/x-pack/legacy/plugins/canvas/public/state/actions/workpad.js b/x-pack/legacy/plugins/canvas/public/state/actions/workpad.js index 5a7fb76ca868c..167c156dce998 100644 --- a/x-pack/legacy/plugins/canvas/public/state/actions/workpad.js +++ b/x-pack/legacy/plugins/canvas/public/state/actions/workpad.js @@ -5,7 +5,7 @@ */ import { createAction } from 'redux-actions'; -import { createThunk } from 'redux-thunks'; +import { createThunk } from 'redux-thunks/cjs'; import { without, includes } from 'lodash'; import { getWorkpadColors } from '../selectors/workpad'; import { fetchAllRenderables } from './elements'; diff --git a/x-pack/legacy/plugins/canvas/public/state/store.js b/x-pack/legacy/plugins/canvas/public/state/store.js index 760e7a8609978..891f30ca4114f 100644 --- a/x-pack/legacy/plugins/canvas/public/state/store.js +++ b/x-pack/legacy/plugins/canvas/public/state/store.js @@ -22,9 +22,18 @@ export function createStore(initialState) { const rootReducer = getRootReducer(initialState); store = createReduxStore(rootReducer, initialState, middleware); + return store; } +export function destroyStore() { + if (store) { + // Replace reducer so that anything that gets fired after navigating away doesn't really do anything + store.replaceReducer(state => state); + } + store = undefined; +} + export function getState() { return store.getState(); } diff --git a/x-pack/legacy/plugins/canvas/public/store.ts b/x-pack/legacy/plugins/canvas/public/store.ts index 0a378979f6ad9..1460932101725 100644 --- a/x-pack/legacy/plugins/canvas/public/store.ts +++ b/x-pack/legacy/plugins/canvas/public/store.ts @@ -5,7 +5,7 @@ */ // @ts-ignore Untyped local -import { createStore as createReduxStore } from './state/store'; +import { createStore as createReduxStore, destroyStore as destroy } from './state/store'; // @ts-ignore Untyped local import { getInitialState } from './state/initial_state'; @@ -29,3 +29,7 @@ export async function createStore(core: CoreSetup, plugins: CanvasSetupDeps) { return createReduxStore(initialState); } + +export function destroyStore() { + destroy(); +} diff --git a/x-pack/legacy/plugins/canvas/public/style/main.scss b/x-pack/legacy/plugins/canvas/public/style/main.scss index 3d41649397190..4387557cbc9f2 100644 --- a/x-pack/legacy/plugins/canvas/public/style/main.scss +++ b/x-pack/legacy/plugins/canvas/public/style/main.scss @@ -3,6 +3,12 @@ */ $canvasElementCardWidth: 210px; + +.canvas.canvasContainerWrapper { + display: flex; + flex-grow: 1; +} + .canvas.canvasContainer { display: flex; flex-grow: 1; diff --git a/x-pack/legacy/plugins/canvas/public/transitions/fade/fade.css b/x-pack/legacy/plugins/canvas/public/transitions/fade/fade.scss similarity index 100% rename from x-pack/legacy/plugins/canvas/public/transitions/fade/fade.css rename to x-pack/legacy/plugins/canvas/public/transitions/fade/fade.scss diff --git a/x-pack/legacy/plugins/canvas/public/transitions/fade/index.ts b/x-pack/legacy/plugins/canvas/public/transitions/fade/index.ts index 71bad81f8b9b8..ad69fae848628 100644 --- a/x-pack/legacy/plugins/canvas/public/transitions/fade/index.ts +++ b/x-pack/legacy/plugins/canvas/public/transitions/fade/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import './fade.css'; +import './fade.scss'; import { TransitionStrings } from '../../../i18n'; diff --git a/x-pack/legacy/plugins/canvas/public/transitions/rotate/index.ts b/x-pack/legacy/plugins/canvas/public/transitions/rotate/index.ts index 0a160d3719290..4a6915e17ee26 100644 --- a/x-pack/legacy/plugins/canvas/public/transitions/rotate/index.ts +++ b/x-pack/legacy/plugins/canvas/public/transitions/rotate/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import './rotate.css'; +import './rotate.scss'; import { TransitionStrings } from '../../../i18n'; diff --git a/x-pack/legacy/plugins/canvas/public/transitions/rotate/rotate.css b/x-pack/legacy/plugins/canvas/public/transitions/rotate/rotate.scss similarity index 100% rename from x-pack/legacy/plugins/canvas/public/transitions/rotate/rotate.css rename to x-pack/legacy/plugins/canvas/public/transitions/rotate/rotate.scss diff --git a/x-pack/legacy/plugins/canvas/public/transitions/slide/index.ts b/x-pack/legacy/plugins/canvas/public/transitions/slide/index.ts index 904acf9f26e76..c0dfb9295c212 100644 --- a/x-pack/legacy/plugins/canvas/public/transitions/slide/index.ts +++ b/x-pack/legacy/plugins/canvas/public/transitions/slide/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import './slide.css'; +import './slide.scss'; import { TransitionStrings } from '../../../i18n'; diff --git a/x-pack/legacy/plugins/canvas/public/transitions/slide/slide.css b/x-pack/legacy/plugins/canvas/public/transitions/slide/slide.scss similarity index 100% rename from x-pack/legacy/plugins/canvas/public/transitions/slide/slide.css rename to x-pack/legacy/plugins/canvas/public/transitions/slide/slide.scss diff --git a/x-pack/legacy/plugins/canvas/public/transitions/zoom/index.ts b/x-pack/legacy/plugins/canvas/public/transitions/zoom/index.ts index 44dc19e6855d2..7aecc56197a6f 100644 --- a/x-pack/legacy/plugins/canvas/public/transitions/zoom/index.ts +++ b/x-pack/legacy/plugins/canvas/public/transitions/zoom/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import './zoom.css'; +import './zoom.scss'; import { TransitionStrings } from '../../../i18n'; diff --git a/x-pack/legacy/plugins/canvas/public/transitions/zoom/zoom.css b/x-pack/legacy/plugins/canvas/public/transitions/zoom/zoom.scss similarity index 77% rename from x-pack/legacy/plugins/canvas/public/transitions/zoom/zoom.css rename to x-pack/legacy/plugins/canvas/public/transitions/zoom/zoom.scss index 6811a6f178907..f76ea71e8d60c 100644 --- a/x-pack/legacy/plugins/canvas/public/transitions/zoom/zoom.css +++ b/x-pack/legacy/plugins/canvas/public/transitions/zoom/zoom.scss @@ -1,7 +1,7 @@ @keyframes zoomIn { from { opacity: 0; - transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(.3, .3, .3); } 50% { @@ -20,7 +20,7 @@ 50% { opacity: 0; - transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(.3, .3, .3); } to { diff --git a/x-pack/legacy/plugins/canvas/shareable_runtime/index.ts b/x-pack/legacy/plugins/canvas/shareable_runtime/index.ts index 5f1526d1bc240..2398a348f5a31 100644 --- a/x-pack/legacy/plugins/canvas/shareable_runtime/index.ts +++ b/x-pack/legacy/plugins/canvas/shareable_runtime/index.ts @@ -6,7 +6,7 @@ export * from './api'; import '../../../../../built_assets/css/plugins/kibana/index.light.css'; -import '../../../../../built_assets/css/plugins/canvas/style/index.light.css'; +import '../public/style/index.scss'; import '@elastic/eui/dist/eui_theme_light.css'; import '@kbn/ui-framework/dist/kui_light.css'; diff --git a/x-pack/plugins/canvas/kibana.json b/x-pack/plugins/canvas/kibana.json index 3cc442d591f3f..2d6ab43228aa1 100644 --- a/x-pack/plugins/canvas/kibana.json +++ b/x-pack/plugins/canvas/kibana.json @@ -4,7 +4,7 @@ "kibanaVersion": "kibana", "configPath": ["xpack", "canvas"], "server": true, - "ui": false, - "requiredPlugins": ["expressions", "features", "home"], + "ui": true, + "requiredPlugins": ["data", "embeddable", "expressions", "features", "home", "inspector", "uiActions"], "optionalPlugins": ["usageCollection"] } diff --git a/x-pack/plugins/canvas/public/index.ts b/x-pack/plugins/canvas/public/index.ts new file mode 100644 index 0000000000000..736d5ccc0f8e5 --- /dev/null +++ b/x-pack/plugins/canvas/public/index.ts @@ -0,0 +1,10 @@ +/* + * 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 { PluginInitializerContext } from 'kibana/public'; +import { CanvasPlugin } from '../../../legacy/plugins/canvas/public/plugin'; + +export const plugin = (initializerContext: PluginInitializerContext) => new CanvasPlugin();