Skip to content

Commit

Permalink
[canvas] disable canvas application when there are no workpads (elast…
Browse files Browse the repository at this point in the history
…ic#200203)

Closes elastic#197370

### Test instructions
1) open new kibana installation
2) verify canvas is not available in menu or application search bar
3) use saved object import to import canvas workpad. Reload browser
4) verify canvas is available in menu and application search bar

---------

Co-authored-by: kibanamachine <[email protected]>
Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
3 people authored and paulinashakirova committed Nov 26, 2024
1 parent 26c97e1 commit 60811de
Show file tree
Hide file tree
Showing 14 changed files with 119 additions and 36 deletions.
2 changes: 2 additions & 0 deletions docs/user/canvas.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
[partintro]
--

*Note:* Canvas is only available for upgraded installations with existing workpads.

*Canvas* is a data visualization and presentation tool that allows you to pull live data from {es},
then combine the data with colors, images, text, and your imagination to create dynamic, multi-page, pixel-perfect displays.
If you are a little bit creative, a little bit technical, and a whole lot curious, then *Canvas* is for you.
Expand Down
26 changes: 0 additions & 26 deletions x-pack/plugins/canvas/public/feature_catalogue_entry.ts

This file was deleted.

11 changes: 7 additions & 4 deletions x-pack/plugins/canvas/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
AppUpdater,
DEFAULT_APP_CATEGORIES,
PluginInitializerContext,
AppStatus,
} from '@kbn/core/public';
import { HomePublicPluginSetup } from '@kbn/home-plugin/public';
import { SpacesPluginStart } from '@kbn/spaces-plugin/public';
Expand All @@ -30,7 +31,6 @@ import { Start as InspectorStart } from '@kbn/inspector-plugin/public';
import { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public';
import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import { ContentManagementPublicStart } from '@kbn/content-management-plugin/public';
import { featureCatalogueEntry } from './feature_catalogue_entry';
import { CanvasAppLocatorDefinition } from '../common/locator';
import { SESSIONSTORAGE_LASTPATH, CANVAS_APP } from '../common/lib/constants';
import { getSessionStorage } from './lib/storage';
Expand All @@ -39,6 +39,7 @@ import { getPluginApi, CanvasApi } from './plugin_api';
import { setupExpressions } from './setup_expressions';
import { addCanvasElementTrigger } from './state/triggers/add_canvas_element_trigger';
import { setKibanaServices, untilPluginStartServicesReady } from './services/kibana_services';
import { getHasWorkpads } from './services/get_has_workpads';

export type { CoreStart, CoreSetup };

Expand Down Expand Up @@ -161,9 +162,11 @@ export class CanvasPlugin
},
});

if (setupPlugins.home) {
setupPlugins.home.featureCatalogue.register(featureCatalogueEntry);
}
getHasWorkpads(coreSetup.http).then((hasWorkpads) => {
this.appUpdater.next(() => ({
status: hasWorkpads ? AppStatus.accessible : AppStatus.inaccessible,
}));
});

if (setupPlugins.share) {
setupPlugins.share.url.locators.create(new CanvasAppLocatorDefinition());
Expand Down
20 changes: 20 additions & 0 deletions x-pack/plugins/canvas/public/services/get_has_workpads.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { HttpSetup } from '@kbn/core/public';
import { API_ROUTE_WORKPAD } from '../../common/lib/constants';

export async function getHasWorkpads(http: HttpSetup): Promise<boolean> {
try {
const response = await http.get(`${API_ROUTE_WORKPAD}/hasWorkpads`, {
version: '1',
});
return (response as { hasWorkpads: boolean })?.hasWorkpads ?? false;
} catch (error) {
return false;
}
}
52 changes: 52 additions & 0 deletions x-pack/plugins/canvas/server/routes/workpad/has_workpads.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { SavedObjectAttributes } from '@kbn/core/server';
import { RouteInitializerDeps } from '..';
import { CANVAS_TYPE, API_ROUTE_WORKPAD } from '../../../common/lib/constants';

export function initializeHasWorkpadsRoute(deps: RouteInitializerDeps) {
const { router } = deps;
router.versioned
.get({
path: `${API_ROUTE_WORKPAD}/hasWorkpads`,
access: 'internal',
})
.addVersion(
{
version: '1',
validate: {
request: {},
},
},
async (context, request, response) => {
const savedObjectsClient = (await context.core).savedObjects.client;

try {
const workpads = await savedObjectsClient.find<SavedObjectAttributes>({
type: CANVAS_TYPE,
fields: ['id'],
perPage: 1,
// search across all spaces
namespaces: ['*'],
});

return response.ok({
body: {
hasWorkpads: workpads.total > 0,
},
});
} catch (error) {
return response.ok({
body: {
hasWorkpads: false,
},
});
}
}
);
}
2 changes: 2 additions & 0 deletions x-pack/plugins/canvas/server/routes/workpad/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import { initializeImportWorkpadRoute } from './import';
import { initializeUpdateWorkpadRoute, initializeUpdateWorkpadAssetsRoute } from './update';
import { initializeDeleteWorkpadRoute } from './delete';
import { initializeResolveWorkpadRoute } from './resolve';
import { initializeHasWorkpadsRoute } from './has_workpads';

export function initWorkpadRoutes(deps: RouteInitializerDeps) {
initializeHasWorkpadsRoute(deps);
initializeFindWorkpadsRoute(deps);
initializeResolveWorkpadRoute(deps);
initializeGetWorkpadRoute(deps);
Expand Down
2 changes: 0 additions & 2 deletions x-pack/plugins/translations/translations/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -12501,7 +12501,6 @@
"xpack.banners.settings.textContent.title": "Texte de la bannière",
"xpack.canvas.addCanvasElementTrigger.description": "Une nouvelle action apparaît dans le menu du panneau d'ajout Canvas",
"xpack.canvas.addCanvasElementTrigger.title": "Menu Ajouter un panneau",
"xpack.canvas.appDescription": "Vos données méritent une présentation irréprochable.",
"xpack.canvas.argAddPopover.addAriaLabel": "Ajouter un argument",
"xpack.canvas.argFormAdvancedFailure.applyButtonLabel": "Appliquer",
"xpack.canvas.argFormAdvancedFailure.resetButtonLabel": "Réinitialiser",
Expand Down Expand Up @@ -12690,7 +12689,6 @@
"xpack.canvas.expressionTypes.argTypes.seriesStyle.styleLabel": "Style",
"xpack.canvas.expressionTypes.argTypes.seriesStyleLabel": "Définir le style d'une série nommée sélectionnée",
"xpack.canvas.expressionTypes.argTypes.seriesStyleTitle": "Style de la série",
"xpack.canvas.featureCatalogue.canvasSubtitle": "Concevez des présentations irréprochables.",
"xpack.canvas.features.reporting.pdf": "Générer des rapports PDF",
"xpack.canvas.features.reporting.pdfFeatureName": "Reporting",
"xpack.canvas.formatMsg.toaster.errorStatusMessage": "Erreur {errStatus} {errStatusText} : {errMessage}.",
Expand Down
2 changes: 0 additions & 2 deletions x-pack/plugins/translations/translations/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -12485,7 +12485,6 @@
"xpack.banners.settings.textContent.title": "バナーテキスト",
"xpack.canvas.addCanvasElementTrigger.description": "新しいアクションは、キャンバスのパネルの追加メニューに表示されます",
"xpack.canvas.addCanvasElementTrigger.title": "パネルの追加メニュー",
"xpack.canvas.appDescription": "データを完璧に美しく表現します。",
"xpack.canvas.argAddPopover.addAriaLabel": "引数を追加",
"xpack.canvas.argFormAdvancedFailure.applyButtonLabel": "適用",
"xpack.canvas.argFormAdvancedFailure.resetButtonLabel": "リセット",
Expand Down Expand Up @@ -12674,7 +12673,6 @@
"xpack.canvas.expressionTypes.argTypes.seriesStyle.styleLabel": "スタイル",
"xpack.canvas.expressionTypes.argTypes.seriesStyleLabel": "選択された名前付きの数列のスタイルを設定",
"xpack.canvas.expressionTypes.argTypes.seriesStyleTitle": "数列スタイル",
"xpack.canvas.featureCatalogue.canvasSubtitle": "詳細まで正確な表示を設計します。",
"xpack.canvas.features.reporting.pdf": "PDFレポートを生成",
"xpack.canvas.features.reporting.pdfFeatureName": "レポート",
"xpack.canvas.formatMsg.toaster.errorStatusMessage": "エラー {errStatus} {errStatusText}: {errMessage}",
Expand Down
2 changes: 0 additions & 2 deletions x-pack/plugins/translations/translations/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -12250,7 +12250,6 @@
"xpack.banners.settings.textContent.title": "横幅广告文本",
"xpack.canvas.addCanvasElementTrigger.description": "一项新操作将在 Canvas 添加面板菜单中显示出来",
"xpack.canvas.addCanvasElementTrigger.title": "添加面板菜单",
"xpack.canvas.appDescription": "以最佳像素展示您的数据。",
"xpack.canvas.argAddPopover.addAriaLabel": "添加参数",
"xpack.canvas.argFormAdvancedFailure.applyButtonLabel": "应用",
"xpack.canvas.argFormAdvancedFailure.resetButtonLabel": "重置",
Expand Down Expand Up @@ -12435,7 +12434,6 @@
"xpack.canvas.expressionTypes.argTypes.seriesStyle.styleLabel": "样式",
"xpack.canvas.expressionTypes.argTypes.seriesStyleLabel": "设置选定已命名序列的样式",
"xpack.canvas.expressionTypes.argTypes.seriesStyleTitle": "序列样式",
"xpack.canvas.featureCatalogue.canvasSubtitle": "设计像素级完美的演示文稿。",
"xpack.canvas.features.reporting.pdf": "生成 PDF 报告",
"xpack.canvas.features.reporting.pdfFeatureName": "Reporting",
"xpack.canvas.formatMsg.toaster.errorStatusMessage": "错误 {errStatus} {errStatusText}:{errMessage}",
Expand Down
7 changes: 7 additions & 0 deletions x-pack/test/functional/apps/canvas/datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export default function canvasExpressionTest({ getService, getPageObjects }: Ftr
await kibanaServer.importExport.load(
'test/functional/fixtures/kbn_archiver/kibana_sample_data_flights_index_pattern.json'
);
// canvas application is only available when installation contains canvas workpads
await kibanaServer.importExport.load(
'x-pack/test/functional/fixtures/kbn_archiver/canvas/default'
);

await kibanaServer.uiSettings.update({
defaultIndex: 'kibana_sample_data_flights',
Expand All @@ -46,6 +50,9 @@ export default function canvasExpressionTest({ getService, getPageObjects }: Ftr
await kibanaServer.importExport.unload(
'test/functional/fixtures/kbn_archiver/kibana_sample_data_flights_index_pattern.json'
);
await kibanaServer.importExport.unload(
'x-pack/test/functional/fixtures/kbn_archiver/canvas/default'
);
});

describe('esdocs', function () {
Expand Down
8 changes: 8 additions & 0 deletions x-pack/test/functional/apps/canvas/embeddables/maps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,21 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('maps in canvas', function () {
before(async () => {
await kibanaServer.savedObjects.cleanStandardList();
// canvas application is only available when installation contains canvas workpads
await kibanaServer.importExport.load(
'x-pack/test/functional/fixtures/kbn_archiver/canvas/default'
);
// open canvas home
await canvas.goToListingPage();
// create new workpad
await canvas.createNewWorkpad();
await canvas.setWorkpadName('maps tests');
});

after(async () => {
await kibanaServer.savedObjects.cleanStandardList();
});

describe('by-value', () => {
it('creates new map embeddable', async () => {
const originalEmbeddableCount = await canvas.getEmbeddableCount();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await kibanaServer.importExport.load(
'test/functional/fixtures/kbn_archiver/dashboard/current/kibana'
);
// canvas application is only available when installation contains canvas workpads
await kibanaServer.importExport.load(
'x-pack/test/functional/fixtures/kbn_archiver/canvas/default'
);
// open canvas home
await canvas.goToListingPage();
// create new workpad
Expand Down
7 changes: 7 additions & 0 deletions x-pack/test/functional/apps/spaces/enter_space.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export default function enterSpaceFunctionalTests({
describe('Enter Space', function () {
this.tags('includeFirefox');
before(async () => {
// canvas application is only available when installation contains canvas workpads
await kibanaServer.importExport.load(
'x-pack/test/functional/fixtures/kbn_archiver/canvas/default'
);
await spacesService.create({
id: 'another-space',
name: 'Another Space',
Expand All @@ -45,6 +49,9 @@ export default function enterSpaceFunctionalTests({
await PageObjects.security.forceLogout();
});
after(async () => {
await kibanaServer.importExport.unload(
'x-pack/test/functional/fixtures/kbn_archiver/canvas/default'
);
await spacesService.delete('another-space');
await kibanaServer.savedObjects.cleanStandardList();
});
Expand Down
10 changes: 10 additions & 0 deletions x-pack/test/functional_search/tests/solution_navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default function searchSolutionNavigation({
const { common, solutionNavigation } = getPageObjects(['common', 'solutionNavigation']);
const spaces = getService('spaces');
const browser = getService('browser');
const kibanaServer = getService('kibanaServer');

describe('Search Solution Navigation', () => {
let cleanUp: () => Promise<unknown>;
Expand All @@ -28,9 +29,18 @@ export default function searchSolutionNavigation({
// Create a space with the search solution and navigate to its home page
({ cleanUp, space: spaceCreated } = await spaces.create({ solution: 'es' }));
await browser.navigateTo(spaces.getRootUrl(spaceCreated.id));

// canvas application is only available when installation contains canvas workpads
await kibanaServer.importExport.load(
'x-pack/test/functional/fixtures/kbn_archiver/canvas/default'
);
});

after(async () => {
await kibanaServer.importExport.unload(
'x-pack/test/functional/fixtures/kbn_archiver/canvas/default'
);

// Clean up space created
await cleanUp();
});
Expand Down

0 comments on commit 60811de

Please sign in to comment.