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

[MD]Add column service to index pattern & Register data source column #2542

Merged
merged 1 commit into from
Oct 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
* [MD] Support legacy client for data source ([#2204](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2204))
* [Plugin Helpers] Facilitate version changes ([#2398](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2398))
* [MD] Display error toast for create index pattern with data source ([#2506](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2506))
* [Multi DataSource] UX enhacement on index pattern management stack ([#2505](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2505))
* [Multi DataSource] UX enhancement on index pattern management stack ([#2505](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2505))
* [Multi DataSource] UX enhancement on Data source management stack ([#2521](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2521))
* [Multi DataSource] UX enhancement on Index Pattern management stack ([#2527](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2527))
* [Multi DataSource] Add data source column into index pattern table ([#2542](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2542))

### 🐛 Bug Fixes
* [Vis Builder] Fixes auto bounds for timeseries bar chart visualization ([2401](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2401))
* [Vis Builder] Fixes visualization shift when editing agg ([2401](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2401))
Expand Down
6 changes: 3 additions & 3 deletions src/plugins/data_source/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { DataSourcePublicPlugin } from './plugin';
import { DataSourcePlugin } from './plugin';

// This exports static code and TypeScript types,
// as well as, OpenSearch Dashboards Platform `plugin()` initializer.
export function plugin() {
return new DataSourcePublicPlugin();
return new DataSourcePlugin();
}

export { DataSourcePublicPluginSetup, DataSourcePublicPluginStart } from './types';
export { DataSourcePluginSetup, DataSourcePluginStart } from './types';
9 changes: 4 additions & 5 deletions src/plugins/data_source/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
*/

import { CoreSetup, CoreStart, Plugin } from '../../../core/public';
import { DataSourcePublicPluginSetup, DataSourcePublicPluginStart } from './types';
import { DataSourcePluginSetup, DataSourcePluginStart } from './types';

export class DataSourcePublicPlugin
implements Plugin<DataSourcePublicPluginSetup, DataSourcePublicPluginStart> {
public setup(core: CoreSetup): DataSourcePublicPluginSetup {
export class DataSourcePlugin implements Plugin<DataSourcePluginSetup, DataSourcePluginStart> {
public setup(core: CoreSetup): DataSourcePluginSetup {
return {};
}

public start(core: CoreStart): DataSourcePublicPluginStart {
public start(core: CoreStart): DataSourcePluginStart {
return {};
}

Expand Down
4 changes: 2 additions & 2 deletions src/plugins/data_source/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface DataSourcePublicPluginSetup {}
export interface DataSourcePluginSetup {}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface DataSourcePublicPluginStart {}
export interface DataSourcePluginStart {}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "opensearchDashboards",
"server": false,
"ui": true,
"requiredPlugins": ["management", "dataSource"],
"requiredPlugins": ["management", "dataSource", "indexPatternManagement"],
"optionalPlugins": [],
"requiredBundles": ["opensearchDashboardsReact"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { i18n } from '@osd/i18n';
import { HttpStart, SavedObjectsStart } from 'opensearch-dashboards/public';
import { EuiBadge, EuiLink } from '@elastic/eui';
import React from 'react';
import {
IndexPatternTableColumn,
IndexPatternTableRecord,
} from '../../../../index_pattern_management/public';
import { getDataSources } from '../utils';
import { DataSourceTableItem } from '../../types';

type DataSourceColumnItem = DataSourceTableItem & { relativeUrl: string };
type DataSourceMap = Map<string, DataSourceColumnItem> | undefined;

export class DataSourceColumn implements IndexPatternTableColumn<DataSourceMap> {
public readonly id: string = 'data_source';
public data: DataSourceMap;

public euiColumn = {
field: 'referenceId',
name: i18n.translate('dataSource.management.dataSourceColumn', {
defaultMessage: 'Data Source',
}),
render: (referenceId: string, index: IndexPatternTableRecord) => {
if (!referenceId) {
return null;
}

const dataSource = this.data?.get(referenceId);
if (!dataSource) {
// Index pattern has the referenceId but data source not found.
return <EuiBadge color="danger">Deleted</EuiBadge>;
}

const { title, relativeUrl } = dataSource;
return <EuiLink href={relativeUrl}>{title}</EuiLink>;
},
};

constructor(
private readonly savedObjectPromise: Promise<SavedObjectsStart>,
private readonly httpPromise: Promise<HttpStart>
) {}

public loadData = async () => {
const savedObject = await this.savedObjectPromise;
const { basePath } = await this.httpPromise;

return getDataSources(savedObject.client).then((dataSources?: DataSourceTableItem[]) => {
this.data = dataSources
?.map((dataSource) => {
return {
...dataSource,
relativeUrl: basePath.prepend(
`/app/management/opensearch-dashboards/dataSources/${encodeURIComponent(
dataSource.id
)}`
),
};
})
?.reduce(
(map, dataSource) => map.set(dataSource.id, dataSource),
new Map<string, DataSourceColumnItem>()
);
return this.data;
});
};
}
15 changes: 14 additions & 1 deletion src/plugins/data_source_management/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,35 @@ import { CoreSetup, CoreStart, Plugin } from '../../../core/public';
import { PLUGIN_NAME } from '../common';

import { ManagementSetup } from '../../management/public';
import { IndexPatternManagementSetup } from '../../index_pattern_management/public';
import { DataSourceColumn } from './components/data_source_column/data_source_column';

export interface DataSourceManagementSetupDependencies {
management: ManagementSetup;
indexPatternManagement: IndexPatternManagementSetup;
}

const DSM_APP_ID = 'dataSources';

export class DataSourceManagementPlugin
implements Plugin<void, void, DataSourceManagementSetupDependencies> {
public setup(core: CoreSetup, { management }: DataSourceManagementSetupDependencies) {
public setup(
core: CoreSetup,
{ management, indexPatternManagement }: DataSourceManagementSetupDependencies
) {
const opensearchDashboardsSection = management.sections.section.opensearchDashboards;

if (!opensearchDashboardsSection) {
throw new Error('`opensearchDashboards` management section not found.');
}

const savedObjectPromise = core
.getStartServices()
.then(([coreStart]) => coreStart.savedObjects);
const httpPromise = core.getStartServices().then(([coreStart]) => coreStart.http);
const column = new DataSourceColumn(savedObjectPromise, httpPromise);
indexPatternManagement.columns.register(column);

opensearchDashboardsSection.registerApp({
id: DSM_APP_ID,
title: PLUGIN_NAME,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import { FormattedMessage } from '@osd/i18n/react';
import { withRouter, RouteComponentProps } from 'react-router-dom';
import React, { useState, useEffect } from 'react';
import { i18n } from '@osd/i18n';
import { useMount } from 'react-use';
import { useEffectOnce, useMount } from 'react-use';
import {
reactRouterNavigate,
useOpenSearchDashboards,
Expand Down Expand Up @@ -112,6 +112,9 @@ export const IndexPatternTable = ({ canSave, history }: Props) => {
const [remoteClustersExist, setRemoteClustersExist] = useState<boolean>(false);
const [isLoadingSources, setIsLoadingSources] = useState<boolean>(!dataSourceEnabled);
const [isLoadingIndexPatterns, setIsLoadingIndexPatterns] = useState<boolean>(true);
const [isColumnDataLoaded, setIsColumnDataLoaded] = useState(false);

const { columns: columnRegistry } = indexPatternManagementStart;

useMount(() => {
setBreadcrumbs(getListBreadcrumbs());
Expand Down Expand Up @@ -153,6 +156,11 @@ export const IndexPatternTable = ({ canSave, history }: Props) => {
);
};

const loadColumnData = async () => {
await Promise.all(columnRegistry.getAll().map((column) => column.loadData()));
setIsColumnDataLoaded(true);
};

useEffect(() => {
if (!dataSourceEnabled) {
getIndices({ http, pattern: '*', searchClient }).then((dataSources) => {
Expand All @@ -165,6 +173,10 @@ export const IndexPatternTable = ({ canSave, history }: Props) => {
}
}, [http, creationOptions, searchClient, dataSourceEnabled]);

useEffectOnce(() => {
loadColumnData();
});

chrome.docTitle.change(title);

const columns = [
Expand Down Expand Up @@ -197,6 +209,13 @@ export const IndexPatternTable = ({ canSave, history }: Props) => {
dataType: 'string' as const,
sortable: ({ sort }: { sort: string }) => sort,
},
...columnRegistry.getAll().map((column) => {
return {
...column.euiColumn,
sortable: false,
'data-test-subj': `indexPatternTableColumn-${column.id}`,
};
}),
];

const createButton = canSave ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,22 @@ export async function getIndexPatterns(
.map((pattern) => {
const id = pattern.id;
const title = pattern.get('title');
const references = pattern.references;
const isDefault = defaultIndex === id;

const tags = (indexPatternManagementStart as IndexPatternManagementStart).list.getIndexPatternTags(
pattern,
isDefault
);
const reference = Array.isArray(references) ? references[0] : undefined;
const referenceId = reference?.id;

return {
id,
title,
default: isDefault,
tags,
referenceId,
// the prepending of 0 at the default pattern takes care of prioritization
// so the sorting will but the default index on top
// or on bottom of a the table
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/index_pattern_management/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,4 @@ export {

export { DefaultFormatEditor } from './components/field_editor/components/field_format_editor';

export { MlCardState } from './types';
export { MlCardState, IndexPatternTableColumn, IndexPatternTableRecord } from './types';
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import { i18n } from '@osd/i18n';
import { I18nProvider } from '@osd/i18n/react';
import { StartServicesAccessor } from 'src/core/public';

import { EuiIconType } from '@elastic/eui/src/components/icon/icon';
import { OpenSearchDashboardsContextProvider } from '../../../opensearch_dashboards_react/public';
import { ManagementAppMountParams } from '../../../management/public';
import {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { IndexPatternTableColumn } from '../../types';

export interface IndexPatternTableColumnServiceSetup {
/**
* register given column in the registry.
*/
register: (column: IndexPatternTableColumn<unknown>) => void;
}

export interface IndexPatternTableColumnServiceStart {
/**
* return all {@link IndexPatternTableColumn | columns} currently registered.
*/
getAll: () => Array<IndexPatternTableColumn<unknown>>;
}

export class IndexPatternTableColumnService {
private readonly columns = new Map<string, IndexPatternTableColumn<unknown>>();

setup(): IndexPatternTableColumnServiceSetup {
return {
register: (column) => {
if (this.columns.has(column.id)) {
throw new Error(`Index Pattern Table Column with id '${column.id}' already exists`);
}
AMoo-Miki marked this conversation as resolved.
Show resolved Hide resolved
this.columns.set(column.id, column);
},
};
}

start(): IndexPatternTableColumnServiceStart {
return {
getAll: () => [...this.columns.values()],
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export * from './column_service';
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
TruncateFormatEditor,
UrlFormatEditor,
} from '../components/field_editor/components/field_format_editor';
import { IndexPatternTableColumnService } from './column_service';

interface SetupDependencies {
httpClient: HttpSetup;
Expand All @@ -62,12 +63,14 @@ export class IndexPatternManagementService {
indexPatternListConfig: IndexPatternListManager;
fieldFormatEditors: FieldFormatEditors;
environmentService: EnvironmentService;
columnService: IndexPatternTableColumnService;

constructor() {
this.indexPatternCreationManager = new IndexPatternCreationManager();
this.indexPatternListConfig = new IndexPatternListManager();
this.fieldFormatEditors = new FieldFormatEditors();
this.environmentService = new EnvironmentService();
this.columnService = new IndexPatternTableColumnService();
}

public setup({ httpClient }: SetupDependencies) {
Expand Down Expand Up @@ -98,6 +101,7 @@ export class IndexPatternManagementService {
list: indexPatternListConfigSetup,
fieldFormatEditors: fieldFormatEditorsSetup,
environment: this.environmentService.setup(),
columns: this.columnService.setup(),
};
}

Expand All @@ -106,6 +110,7 @@ export class IndexPatternManagementService {
creation: this.indexPatternCreationManager.start(),
list: this.indexPatternListConfig.start(),
fieldFormatEditors: this.fieldFormatEditors.start(),
columns: this.columnService.start(),
};
}

Expand Down
Loading