Skip to content

Commit

Permalink
update workspace pages and hooks to integrate with data connection
Browse files Browse the repository at this point in the history
Signed-off-by: tygao <tygao@amazon.com>
  • Loading branch information
raintygao committed Sep 13, 2024
1 parent 15e1abe commit 64d6c94
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 23 deletions.
1 change: 1 addition & 0 deletions src/plugins/workspace/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export type DataSource = Pick<
export enum DataSourceConnectionType {
OpenSearchConnection,
DirectQueryConnection,
DataConnection,
}

export interface DataSourceConnection {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export const WorkspaceCreator = (props: WorkspaceCreatorProps) => {
return id;
});
const selectedDataConnectionIds = (selectedDataSourceConnections ?? [])
.filter(({ connectionType }) => connectionType === DATA_CONNECTION_SAVED_OBJECT_TYPE)
.filter(({ type }) => type === DATA_CONNECTION_SAVED_OBJECT_TYPE)
.map(({ id }) => {
return id;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ import { HttpStart, NotificationsStart, SavedObjectsStart } from '../../../../..
import { AssociationDataSourceModalMode } from '../../../common/constants';
import { Logos } from '../../../../../core/common';
import { DirectQueryConnectionIcon } from '../workspace_form';
import { DataConnectionIcon } from '../workspace_form';

import { DATA_CONNECTION_SAVED_OBJECT_TYPE } from '../../../../data_source/common/data_connections';

const ConnectionIcon = ({
connection: { connectionType, type },
Expand All @@ -45,6 +48,9 @@ const ConnectionIcon = ({
if (connectionType === DataSourceConnectionType.DirectQueryConnection) {
return <DirectQueryConnectionIcon type={type} />;
}
if (type === DATA_CONNECTION_SAVED_OBJECT_TYPE) {
return <DataConnectionIcon type={type} />;
}
return null;
};

Expand Down Expand Up @@ -143,6 +149,14 @@ const convertConnectionsToOptions = ({
) {
return [];
}

if (connection.type === DATA_CONNECTION_SAVED_OBJECT_TYPE) {
if (showDirectQueryConnections) {
return [connection];
}
return [];
}

if (showDirectQueryConnections) {
if (!connection.relatedConnections || connection.relatedConnections.length === 0) {
return [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { i18n } from '@osd/i18n';
import { DataSourceConnection, DataSourceConnectionType } from '../../../common/types';
import { AssociationDataSourceModalMode } from '../../../common/constants';
import { DataSourceConnectionTable } from '../workspace_form';

import { DATA_CONNECTION_SAVED_OBJECT_TYPE } from '../../../../data_source/common/data_connections';
interface WorkspaceDetailConnectionTableProps {
isDashboardAdmin: boolean;
connectionType: string;
Expand All @@ -35,7 +35,8 @@ export const WorkspaceDetailConnectionTable = ({
return dataSourceConnections.filter((dsc) =>
connectionType === AssociationDataSourceModalMode.OpenSearchConnections
? dsc.connectionType === DataSourceConnectionType.OpenSearchConnection
: dsc?.relatedConnections && dsc.relatedConnections?.length > 0
: dsc.type === DATA_CONNECTION_SAVED_OBJECT_TYPE ||
(dsc?.relatedConnections && dsc.relatedConnections?.length > 0)
);
}, [connectionType, dataSourceConnections]);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { EuiIcon } from '@elastic/eui';

export const DataConnectionIcon = ({ type }: { type?: string }) => {
switch (type) {
default:
return <EuiIcon type="wrench" />;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export { WorkspacePermissionSettingPanel } from './workspace_permission_setting_
export { WorkspaceCancelModal } from './workspace_cancel_modal';
export { WorkspaceNameField, WorkspaceDescriptionField } from './fields';
export { DirectQueryConnectionIcon } from './direct_query_connection_icon';
export { DataConnectionIcon } from './data_connection_icon';
export { DataSourceConnectionTable } from './data_source_connection_table';

export { WorkspaceFormSubmitData, WorkspaceFormProps, WorkspaceFormDataState } from './types';
Expand Down
42 changes: 26 additions & 16 deletions src/plugins/workspace/public/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import {
SECURITY_ANALYTICS_OVERVIEW_PAGE_ID,
} from '../../../plugins/content_management/public';
import { WORKSPACE_DATA_SOURCE_AND_CONNECTION_OBJECT_TYPES } from '../common/constants';
import { DATA_SOURCE_SAVED_OBJECT_TYPE } from '../../data_source/common/data_sources';
import { DATA_CONNECTION_SAVED_OBJECT_TYPE } from '../../data_source/common/data_connections';

export const isUseCaseFeatureConfig = (featureConfig: string) =>
featureConfig.startsWith(USE_CASE_PREFIX);
Expand Down Expand Up @@ -222,6 +224,7 @@ export const getDataSourcesList = (
return client
.find({
type: WORKSPACE_DATA_SOURCE_AND_CONNECTION_OBJECT_TYPES,
// type: 'data-source',
fields: ['id', 'title', 'auth', 'description', 'dataSourceEngineType'],
perPage: 10000,
workspaces: targetWorkspaces,
Expand Down Expand Up @@ -272,16 +275,18 @@ export const getDirectQueryConnections = async (dataSourceId: string, http: Http
export const convertDataSourcesToOpenSearchConnections = (
dataSources: DataSource[]
): DataSourceConnection[] =>
dataSources.map((ds) => {
return {
id: ds.id,
type: ds.dataSourceEngineType,
connectionType: DataSourceConnectionType.OpenSearchConnection,
name: ds.title,
description: ds.description,
relatedConnections: [],
};
});
dataSources
.filter((ds) => ds.type === DATA_SOURCE_SAVED_OBJECT_TYPE)
.map((ds) => {
return {
id: ds.id,
type: ds.dataSourceEngineType,
connectionType: DataSourceConnectionType.OpenSearchConnection,
name: ds.title,
description: ds.description,
relatedConnections: [],
};
});

export const fulfillRelatedConnections = (
connections: DataSourceConnection[],
Expand All @@ -304,11 +309,16 @@ export const mergeDataSourcesWithConnections = (
directQueryConnections: DataSourceConnection[]
): DataSourceConnection[] => {
const openSearchConnections = convertDataSourcesToOpenSearchConnections(dataSources);

return [
const dataConnections = dataSources
.filter((ds) => ds.type === DATA_CONNECTION_SAVED_OBJECT_TYPE)
.map((ds) => ({ ...ds, name: ds.id }));
const result = [
...fulfillRelatedConnections(openSearchConnections, directQueryConnections),
...directQueryConnections,
].sort((a, b) => a.name.localeCompare(b.name));
...dataConnections,
].sort((a, b) => a?.name?.localeCompare(b?.name));

return result;
};

// If all connected data sources are serverless, will only allow to select essential use case.
Expand Down Expand Up @@ -508,16 +518,16 @@ export const fetchDataSourceConnectionsByDataSourceIds = async (
};

export const fetchDataSourceConnections = async (
assignedDataSources: DataSource[],
dataSources: DataSource[],
http: HttpSetup | undefined,
notifications: NotificationsStart | undefined
) => {
try {
const directQueryConnections = await fetchDataSourceConnectionsByDataSourceIds(
assignedDataSources.map((ds) => ds.id),
dataSources.filter((ds) => ds.type === DATA_SOURCE_SAVED_OBJECT_TYPE).map((ds) => ds.id),
http
);
return mergeDataSourcesWithConnections(assignedDataSources, directQueryConnections);
return mergeDataSourcesWithConnections(dataSources, directQueryConnections);
} catch (error) {
notifications?.toasts.addDanger(
i18n.translate('workspace.detail.dataSources.error.message', {
Expand Down
5 changes: 5 additions & 0 deletions src/plugins/workspace/server/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ const workspacePermissions = schema.recordOf(
);

const dataSourceIds = schema.arrayOf(schema.string());
const dataConnectionIds = schema.arrayOf(schema.string());

const settingsSchema = schema.object({
permissions: schema.maybe(workspacePermissions),
dataSources: schema.maybe(dataSourceIds),
dataConnections: schema.maybe(dataConnectionIds),
});

const featuresSchema = schema.arrayOf(schema.string(), {
Expand Down Expand Up @@ -203,6 +205,7 @@ export function registerRoutes({
const principals = permissionControlClient?.getPrincipalsFromRequest(req);
const createPayload: Omit<WorkspaceAttributeWithPermission, 'id'> & {
dataSources?: string[];
dataConnections?: string[];
} = attributes;

if (isPermissionControlEnabled) {
Expand All @@ -217,6 +220,7 @@ export function registerRoutes({
}

createPayload.dataSources = settings.dataSources;
createPayload.dataConnections = settings.dataConnections;

const result = await client.create(
{
Expand Down Expand Up @@ -255,6 +259,7 @@ export function registerRoutes({
...attributes,
...(isPermissionControlEnabled ? { permissions: settings.permissions } : {}),
...{ dataSources: settings.dataSources },
...{ dataConnections: settings.dataConnections },
}
);
return res.ok({ body: result });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -498,10 +498,10 @@ export class WorkspaceSavedObjectsClientWrapper {
if (
isDataSourceAdmin &&
options?.type &&
(options.type === DATA_SOURCE_SAVED_OBJECT_TYPE ||
(validateIsWorkspaceDataSourceAndConnectionObjectType(options.type) ||
(Array.isArray(options.type) &&
options.type.length === 1 &&
options.type[0] === DATA_SOURCE_SAVED_OBJECT_TYPE))
validateIsWorkspaceDataSourceAndConnectionObjectType(options.type[0])))
) {
return await wrapperOptions.client.find<T>(options);
}
Expand Down Expand Up @@ -589,7 +589,7 @@ export class WorkspaceSavedObjectsClientWrapper {
options: SavedObjectsBaseOptions = {}
) => {
// Only dashboard admin can assign data source to workspace
if (type === DATA_SOURCE_SAVED_OBJECT_TYPE) {
if (validateIsWorkspaceDataSourceAndConnectionObjectType(type)) {
throw generateOSDAdminPermissionError();
}
// In current version, only the type is data-source that will call addToWorkspaces
Expand All @@ -603,7 +603,7 @@ export class WorkspaceSavedObjectsClientWrapper {
options: SavedObjectsBaseOptions = {}
) => {
// Only dashboard admin can unassign data source to workspace
if (type === DATA_SOURCE_SAVED_OBJECT_TYPE) {
if (validateIsWorkspaceDataSourceAndConnectionObjectType(type)) {
throw generateOSDAdminPermissionError();
}
// In current version, only the type is data-source will that call deleteFromWorkspaces
Expand Down

0 comments on commit 64d6c94

Please sign in to comment.