Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ML] Fixing missing data visualizer links #103932

9 changes: 5 additions & 4 deletions x-pack/plugins/data_visualizer/public/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
import { lazyLoadModules } from '../lazy_load_bundle';
import type { FileDataVisualizerSpec, IndexDataVisualizerSpec } from '../application';

export async function getFileDataVisualizerComponent(): Promise<FileDataVisualizerSpec> {
export async function getFileDataVisualizerComponent(): Promise<() => FileDataVisualizerSpec> {
const modules = await lazyLoadModules();
return modules.FileDataVisualizer;
return () => modules.FileDataVisualizer;
}
export async function getIndexDataVisualizerComponent(): Promise<IndexDataVisualizerSpec> {

export async function getIndexDataVisualizerComponent(): Promise<() => IndexDataVisualizerSpec> {
const modules = await lazyLoadModules();
return modules.IndexDataVisualizer;
return () => modules.IndexDataVisualizer;
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ export const FilebeatConfigFlyout: FC<Props> = ({
<EuiFlyoutFooter>
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiButtonEmpty iconType="cross" onClick={closeFlyout} flush="left">
<EuiButtonEmpty
iconType="cross"
onClick={closeFlyout}
flush="left"
data-test-subj="fileBeatConfigFlyoutCloseButton"
>
<FormattedMessage
id="xpack.dataVisualizer.fileBeatConfigFlyout.closeButton"
defaultMessage="Close"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
* 2.0.
*/

export { ResultsLinks } from './results_links';
export { ResultsLinks, ResultLink } from './results_links';
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,27 @@ import { FindFileStructureResponse } from '../../../../../../file_upload/common'
import type { FileUploadPluginStart } from '../../../../../../file_upload/public';
import { useDataVisualizerKibana } from '../../../kibana_context';

type LinkType = 'file' | 'index';

export interface ResultLink {
id: string;
type: LinkType;
title: string;
icon: string;
description: string;
getUrl(params?: any): Promise<string>;
canDisplay(params?: any): Promise<boolean>;
dataTestSubj?: string;
}

interface Props {
fieldStats: FindFileStructureResponse['field_stats'];
index: string;
indexPatternId: string;
timeFieldName?: string;
createIndexPattern: boolean;
showFilebeatFlyout(): void;
additionalLinks: ResultLink[];
}

interface GlobalState {
Expand All @@ -41,6 +55,7 @@ export const ResultsLinks: FC<Props> = ({
timeFieldName,
createIndexPattern,
showFilebeatFlyout,
additionalLinks,
}) => {
const {
services: { fileUpload },
Expand All @@ -55,6 +70,7 @@ export const ResultsLinks: FC<Props> = ({
const [discoverLink, setDiscoverLink] = useState('');
const [indexManagementLink, setIndexManagementLink] = useState('');
const [indexPatternManagementLink, setIndexPatternManagementLink] = useState('');
const [generatedLinks, setGeneratedLinks] = useState<Record<string, string>>({});

const {
services: {
Expand Down Expand Up @@ -100,6 +116,23 @@ export const ResultsLinks: FC<Props> = ({

getDiscoverUrl();

Promise.all(
additionalLinks.map(async ({ canDisplay, getUrl }) => {
if ((await canDisplay({ indexPatternId })) === false) {
return null;
}
return getUrl({ globalState, indexPatternId });
})
).then((urls) => {
const linksById = urls.reduce((acc, url, i) => {
if (url !== null) {
acc[additionalLinks[i].id] = url;
}
return acc;
}, {} as Record<string, string>);
setGeneratedLinks(linksById);
});

if (!unmounted) {
setIndexManagementLink(
getUrlForApp('management', { path: '/data/index_management/indices' })
Expand Down Expand Up @@ -231,6 +264,19 @@ export const ResultsLinks: FC<Props> = ({
onClick={showFilebeatFlyout}
/>
</EuiFlexItem>
{additionalLinks
.filter(({ id }) => generatedLinks[id] !== undefined)
.map((link) => (
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xxl" type={link.icon} />}
data-test-subj="fileDataVisLink"
title={link.title}
description={link.description}
href={generatedLinks[link.id]}
/>
</EuiFlexItem>
))}
</EuiFlexGroup>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ export class FileDataVisualizerView extends Component {
hideBottomBar={this.hideBottomBar}
savedObjectsClient={this.savedObjectsClient}
fileUpload={this.props.fileUpload}
resultsLinks={this.props.resultsLinks}
/>

{bottomBarVisible && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,7 @@ export class ImportView extends Component {
timeFieldName={timeFieldName}
createIndexPattern={createIndexPattern}
showFilebeatFlyout={this.showFilebeatFlyout}
additionalLinks={this.props.resultsLinks ?? []}
/>

{isFilebeatFlyoutVisible && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ import { getCoreStart, getPluginsStart } from '../../kibana_services';

// @ts-ignore
import { FileDataVisualizerView } from './components/file_data_visualizer_view/index';
import { ResultLink } from '../common/components/results_links';

interface Props {
additionalLinks?: ResultLink[];
}

export type FileDataVisualizerSpec = typeof FileDataVisualizer;
export const FileDataVisualizer: FC = () => {
export const FileDataVisualizer: FC<Props> = ({ additionalLinks }) => {
const coreStart = getCoreStart();
const { data, maps, embeddable, share, security, fileUpload } = getPluginsStart();
const services = {
Expand All @@ -33,6 +38,7 @@ export const FileDataVisualizer: FC = () => {
savedObjectsClient={coreStart.savedObjects.client}
http={coreStart.http}
fileUpload={fileUpload}
resultsLinks={additionalLinks}
/>
</KibanaContextProvider>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,26 @@ import type { IndexPattern } from '../../../../../../../../src/plugins/data/comm
import { useDataVisualizerKibana } from '../../../kibana_context';
import { useUrlState } from '../../../common/util/url_state';
import { LinkCard } from '../../../common/components/link_card';
import { ResultLink } from '../../../common/components/results_links';

interface Props {
indexPattern: IndexPattern;
searchString?: string | { [key: string]: any };
searchQueryLanguage?: string;
additionalLinks: ResultLink[];
}

// @todo: Add back create job card in a follow up PR
export const ActionsPanel: FC<Props> = ({ indexPattern, searchString, searchQueryLanguage }) => {
export const ActionsPanel: FC<Props> = ({
indexPattern,
searchString,
searchQueryLanguage,
additionalLinks,
}) => {
const [globalState] = useUrlState('_g');

const [discoverLink, setDiscoverLink] = useState('');
const [generatedLinks, setGeneratedLinks] = useState<Record<string, string>>({});

const {
services: {
application: { capabilities },
Expand Down Expand Up @@ -76,17 +84,56 @@ export const ActionsPanel: FC<Props> = ({ indexPattern, searchString, searchQuer
}
};

Promise.all(
additionalLinks.map(async ({ canDisplay, getUrl }) => {
if ((await canDisplay({ indexPatternId })) === false) {
return null;
}
return getUrl({ globalState, indexPatternId });
})
).then((urls) => {
const linksById = urls.reduce((acc, url, i) => {
if (url !== null) {
acc[additionalLinks[i].id] = url;
}
return acc;
}, {} as Record<string, string>);
setGeneratedLinks(linksById);
});

getDiscoverUrl();
return () => {
unmounted = true;
};
}, [indexPattern, searchString, searchQueryLanguage, globalState, capabilities, getUrlGenerator]);
}, [
indexPattern,
searchString,
searchQueryLanguage,
globalState,
capabilities,
getUrlGenerator,
additionalLinks,
]);

// Note we use display:none for the DataRecognizer section as it needs to be
// passed the recognizerResults object, and then run the recognizer check which
// controls whether the recognizer section is ultimately displayed.
return (
<div data-test-subj="dataVisualizerActionsPanel">
{additionalLinks
.filter(({ id }) => generatedLinks[id] !== undefined)
.map((link) => (
<>
<LinkCard
href={generatedLinks[link.id]}
icon={link.icon}
description={link.description}
title={link.title}
data-test-subj={link.dataTestSubj}
/>
<EuiSpacer size="m" />
</>
))}
{discoverLink && (
<>
<EuiTitle size="s">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import { HelpMenu } from '../../../common/components/help_menu';
import { TimeBuckets } from '../../services/time_buckets';
import { extractSearchData } from '../../utils/saved_search_utils';
import { DataVisualizerIndexPatternManagement } from '../index_pattern_management';
import { ResultLink } from '../../../common/components/results_links';

interface DataVisualizerPageState {
overallStats: OverallStats;
Expand Down Expand Up @@ -120,6 +121,7 @@ export const getDefaultDataVisualizerListState = (): Required<DataVisualizerInde
export interface IndexDataVisualizerViewProps {
currentIndexPattern: IndexPattern;
currentSavedSearch: SavedSearchSavedObject | null;
additionalLinks?: ResultLink[];
}
const restorableDefaults = getDefaultDataVisualizerListState();

Expand All @@ -138,7 +140,7 @@ export const IndexDataVisualizerView: FC<IndexDataVisualizerViewProps> = (dataVi
dataVisualizerProps.currentSavedSearch
);

const { currentIndexPattern } = dataVisualizerProps;
const { currentIndexPattern, additionalLinks } = dataVisualizerProps;

useEffect(() => {
if (dataVisualizerProps?.currentSavedSearch !== undefined) {
Expand Down Expand Up @@ -886,6 +888,7 @@ export const IndexDataVisualizerView: FC<IndexDataVisualizerViewProps> = (dataVi
indexPattern={currentIndexPattern}
searchQueryLanguage={searchQueryLanguage}
searchString={searchString}
additionalLinks={additionalLinks ?? []}
/>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@ import {
} from '../common/util/url_state';
import { useDataVisualizerKibana } from '../kibana_context';
import { IndexPattern } from '../../../../../../src/plugins/data/common/index_patterns/index_patterns';
import { ResultLink } from '../common/components/results_links';

export type IndexDataVisualizerSpec = typeof IndexDataVisualizer;

export interface DataVisualizerUrlStateContextProviderProps {
IndexDataVisualizerComponent: FC<IndexDataVisualizerViewProps>;
additionalLinks: ResultLink[];
}

export const DataVisualizerUrlStateContextProvider: FC<DataVisualizerUrlStateContextProviderProps> = ({
IndexDataVisualizerComponent,
additionalLinks,
}) => {
const {
services: {
Expand Down Expand Up @@ -168,6 +171,7 @@ export const DataVisualizerUrlStateContextProvider: FC<DataVisualizerUrlStateCon
<IndexDataVisualizerComponent
currentIndexPattern={currentIndexPattern}
currentSavedSearch={currentSavedSearch}
additionalLinks={additionalLinks}
/>
) : (
<div />
Expand All @@ -176,7 +180,7 @@ export const DataVisualizerUrlStateContextProvider: FC<DataVisualizerUrlStateCon
);
};

export const IndexDataVisualizer: FC = () => {
export const IndexDataVisualizer: FC<{ additionalLinks: ResultLink[] }> = ({ additionalLinks }) => {
const coreStart = getCoreStart();
const {
data,
Expand Down Expand Up @@ -204,6 +208,7 @@ export const IndexDataVisualizer: FC = () => {
<KibanaContextProvider services={{ ...services }}>
<DataVisualizerUrlStateContextProvider
IndexDataVisualizerComponent={IndexDataVisualizerView}
additionalLinks={additionalLinks}
/>
</KibanaContextProvider>
);
Expand Down
7 changes: 6 additions & 1 deletion x-pack/plugins/data_visualizer/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@ export function plugin() {

export { DataVisualizerPluginStart } from './plugin';

export type { IndexDataVisualizerViewProps } from './application';
export type {
FileDataVisualizerSpec,
IndexDataVisualizerSpec,
IndexDataVisualizerViewProps,
} from './application';
export type { ResultLink } from './application/common/components/results_links';
Loading