Skip to content

Commit

Permalink
Add assistant capabilities to control rendering components (#267) (#303)
Browse files Browse the repository at this point in the history
* Add capabilities to check subscription active status to control assistant feature UI

Signed-off-by: Songkan Tang <[email protected]>

* Fix text2viz feature flag check in server/plugin.ts

Signed-off-by: Songkan Tang <[email protected]>

* Use assistant isSubscriptionActive capabilities to control text2viz UI

Signed-off-by: Songkan Tang <[email protected]>

* Add changelog

Signed-off-by: Songkan Tang <[email protected]>

* Add default app not activation page for text2viz if subscription is not activated

Signed-off-by: Songkan Tang <[email protected]>

* Rename assistant feature UI capabilities to a more general name

Signed-off-by: Songkan Tang <[email protected]>

* Rename changelog

Signed-off-by: Songkan Tang <[email protected]>

* Rephrase app not found page

Signed-off-by: Songkan Tang <[email protected]>

* Remove switcher registration in favor of developers adding it per their requirement

Signed-off-by: Songkan Tang <[email protected]>

---------

Signed-off-by: Songkan Tang <[email protected]>
(cherry picked from commit 4ec4f92)
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
1 parent 33fdde4 commit 66341e9
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 61 deletions.
125 changes: 72 additions & 53 deletions public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,50 +125,63 @@ export class AssistantPlugin
});

if (this.config.text2viz.enabled) {
setupDeps.embeddable.registerEmbeddableFactory(
NLQ_VISUALIZATION_EMBEDDABLE_TYPE,
new NLQVisualizationEmbeddableFactory()
);
const checkSubscriptionAndRegisterText2VizButton = async () => {
const [coreStart] = await core.getStartServices();
const assistantEnabled = coreStart.application.capabilities?.assistant?.enabled === true;
if (assistantEnabled) {
setupDeps.embeddable.registerEmbeddableFactory(
NLQ_VISUALIZATION_EMBEDDABLE_TYPE,
new NLQVisualizationEmbeddableFactory()
);

setupDeps.visualizations.registerAlias({
name: 'text2viz',
aliasPath: '#/',
aliasApp: VIS_NLQ_APP_ID,
title: i18n.translate('dashboardAssistant.feature.text2viz.title', {
defaultMessage: 'Natural language',
}),
description: i18n.translate('dashboardAssistant.feature.text2viz.description', {
defaultMessage: 'Generate visualization with a natural language question.',
}),
icon: 'chatRight',
stage: 'experimental',
promotion: {
buttonText: i18n.translate('dashboardAssistant.feature.text2viz.promotion.buttonText', {
defaultMessage: 'Natural language previewer',
}),
description: i18n.translate('dashboardAssistant.feature.text2viz.promotion.description', {
defaultMessage:
'Not sure which visualization to choose? Generate visualization previews with a natural language question.',
}),
},
appExtensions: {
visualizations: {
docTypes: [VIS_NLQ_SAVED_OBJECT],
toListItem: ({ id, attributes, updated_at: updatedAt }) => ({
description: attributes?.description,
editApp: VIS_NLQ_APP_ID,
editUrl: `/edit/${encodeURIComponent(id)}`,
icon: 'chatRight',
id,
savedObjectType: VIS_NLQ_SAVED_OBJECT,
title: attributes?.title,
typeTitle: 'NLQ',
updated_at: updatedAt,
stage: 'experimental',
setupDeps.visualizations.registerAlias({
name: 'text2viz',
aliasPath: '#/',
aliasApp: VIS_NLQ_APP_ID,
title: i18n.translate('dashboardAssistant.feature.text2viz.title', {
defaultMessage: 'Natural language',
}),
},
},
});
description: i18n.translate('dashboardAssistant.feature.text2viz.description', {
defaultMessage: 'Generate visualization with a natural language question.',
}),
icon: 'chatRight',
stage: 'experimental',
promotion: {
buttonText: i18n.translate(
'dashboardAssistant.feature.text2viz.promotion.buttonText',
{
defaultMessage: 'Natural language previewer',
}
),
description: i18n.translate(
'dashboardAssistant.feature.text2viz.promotion.description',
{
defaultMessage:
'Not sure which visualization to choose? Generate visualization previews with a natural language question.',
}
),
},
appExtensions: {
visualizations: {
docTypes: [VIS_NLQ_SAVED_OBJECT],
toListItem: ({ id, attributes, updated_at: updatedAt }) => ({
description: attributes?.description,
editApp: VIS_NLQ_APP_ID,
editUrl: `/edit/${encodeURIComponent(id)}`,
icon: 'chatRight',
id,
savedObjectType: VIS_NLQ_SAVED_OBJECT,
title: attributes?.title,
typeTitle: 'NLQ',
updated_at: updatedAt,
stage: 'experimental',
}),
},
},
});
}
};
checkSubscriptionAndRegisterText2VizButton();

core.application.register({
id: TEXT2VIZ_APP_ID,
Expand All @@ -178,18 +191,24 @@ export class AssistantPlugin
navLinkStatus: AppNavLinkStatus.hidden,
mount: async (params: AppMountParameters) => {
const [coreStart, pluginsStart] = await core.getStartServices();
params.element.classList.add('text2viz-wrapper');
const { renderText2VizApp } = await import('./text2viz');
const unmount = renderText2VizApp(params, {
...pluginsStart,
...coreStart,
setHeaderActionMenu: params.setHeaderActionMenu,
});
const assistantEnabled = coreStart.application.capabilities?.assistant?.enabled === true;
if (assistantEnabled) {
params.element.classList.add('text2viz-wrapper');
const { renderText2VizApp } = await import('./text2viz');
const unmount = renderText2VizApp(params, {
...pluginsStart,
...coreStart,
setHeaderActionMenu: params.setHeaderActionMenu,
});

return () => {
unmount();
params.element.classList.remove('text2viz-wrapper');
};
return () => {
unmount();
params.element.classList.remove('text2viz-wrapper');
};
} else {
const { renderAppNotFound } = await import('./text2viz');
return renderAppNotFound(params);
}
},
});
}
Expand Down
30 changes: 30 additions & 0 deletions public/text2viz.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { Route, Router, Switch } from 'react-router-dom';

import { EuiEmptyPrompt, EuiPage, EuiPageBody, EuiPageContent, EuiText } from '@elastic/eui';
import { AppMountParameters } from '../../../src/core/public';
import { Text2Viz } from './components/visualization/text2viz';
import { OpenSearchDashboardsContextProvider } from '../../../src/plugins/opensearch_dashboards_react/public';
Expand All @@ -30,3 +31,32 @@ export const renderText2VizApp = (params: AppMountParameters, services: StartSer
ReactDOM.unmountComponentAtNode(params.element);
};
};

export const renderAppNotFound = (params: AppMountParameters) => {
ReactDOM.render(
<EuiPage style={{ minHeight: '100%' }} data-test-subj="appNotFoundPageContent">
<EuiPageBody component="main">
<EuiPageContent verticalPosition="center" horizontalPosition="center">
<EuiEmptyPrompt
iconType="alert"
iconColor="danger"
title={<h2>Application Not Found</h2>}
body={
<EuiText size="s">
<p>
No application was found at this URL. Please check your app status to enable this
feature.
</p>
</EuiText>
}
/>
</EuiPageContent>
</EuiPageBody>
</EuiPage>,

params.element
);
return () => {
ReactDOM.unmountComponentAtNode(params.element);
};
};
13 changes: 13 additions & 0 deletions server/capabilities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export const capabilitiesProvider = () => ({
observability: {
show: true,
},
assistant: {
enabled: true,
},
});
17 changes: 9 additions & 8 deletions server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import { registerText2VizRoutes } from './routes/text2viz_routes';
import { AssistantService } from './services/assistant_service';
import { registerAgentRoutes } from './routes/agent_routes';
import { registerSummaryAssistantRoutes } from './routes/summary_routes';
import { capabilitiesProvider } from './vis_type_nlq/capabilities_provider';
import { capabilitiesProvider as visNLQCapabilitiesProvider } from './vis_type_nlq/capabilities_provider';
import { visNLQSavedObjectType } from './vis_type_nlq/saved_object_type';
import { capabilitiesProvider } from './capabilities';

export class AssistantPlugin implements Plugin<AssistantPluginSetup, AssistantPluginStart> {
private readonly logger: Logger;
Expand Down Expand Up @@ -61,16 +62,16 @@ export class AssistantPlugin implements Plugin<AssistantPluginSetup, AssistantPl
// Register router for text to visualization
if (config.text2viz.enabled) {
registerText2VizRoutes(router, assistantServiceSetup);
registerSummaryAssistantRoutes(router, assistantServiceSetup);
core.capabilities.registerProvider(capabilitiesProvider);
core.capabilities.registerProvider(visNLQCapabilitiesProvider);
core.savedObjects.registerType(visNLQSavedObjectType);
}

core.capabilities.registerProvider(() => ({
observability: {
show: true,
},
}));
// Register router for alert insight
if (config.alertInsight.enabled) {
registerSummaryAssistantRoutes(router, assistantServiceSetup);
}

core.capabilities.registerProvider(capabilitiesProvider);

const registerMessageParser = (messageParser: MessageParser) => {
const findItem = this.messageParsers.find((item) => item.id === messageParser.id);
Expand Down

0 comments on commit 66341e9

Please sign in to comment.