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

Refactor association table in create page #4

Draft
wants to merge 3 commits into
base: 2.17/support-DQC
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export interface AssociationDataSourceModalProps {
savedObjects: SavedObjectsStart;
assignedConnections: DataSourceConnection[];
closeModal: () => void;
handleAssignDataSourceConnections: (connections: DataSourceConnection[]) => Promise<void>;
handleAssignDataSourceConnections: (connections: DataSourceConnection[]) => Promise<void> | void;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my perspective, can remove Promise<void>?

Copy link
Author

@Kapian1234 Kapian1234 Aug 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const handleAssignDataSourceConnections = async ( in detail page may need this

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can try to remove it. The type should work fine. Because we doesn't await handleAssignDataSourceConnections inside modal component.

}

export const AssociationDataSourceModal = ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,20 @@ import { AssociationDataSourceModalTab } from '../../../common/constants';

interface OpenSearchConnectionTableProps {
isDashboardAdmin: boolean;
connectionType: string;
connectionType?: string;
dataSourceConnections: DataSourceConnection[];
handleUnassignDataSources: (dataSources: DataSourceConnection[]) => Promise<void>;
inCreatePage?: boolean;
handleUnassignDataSources: (dataSources: DataSourceConnection[]) => Promise<void> | void;
getSelectedItems?: (dataSources: DataSourceConnection[]) => void;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer rename to onSelectedItemsChange

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

}

export const OpenSearchConnectionTable = ({
isDashboardAdmin,
connectionType,
dataSourceConnections,
handleUnassignDataSources,
getSelectedItems,
inCreatePage = false,
}: OpenSearchConnectionTableProps) => {
const [selectedItems, setSelectedItems] = useState<DataSourceConnection[]>([]);
const [modalVisible, setModalVisible] = useState(false);
Expand All @@ -50,6 +54,12 @@ export const OpenSearchConnectionTable = ({
Record<string, React.ReactNode>
>({});

useEffect(() => {
if (inCreatePage && getSelectedItems) {
getSelectedItems(selectedItems);
}
}, [selectedItems, getSelectedItems, inCreatePage]);

useEffect(() => {
// Reset selected items when connectionType changes
setSelectedItems([]);
Expand Down Expand Up @@ -162,7 +172,7 @@ export const OpenSearchConnectionTable = ({
width: '25%',
field: 'name',
name: i18n.translate('workspace.detail.dataSources.table.title', {
defaultMessage: 'Title',
defaultMessage: 'Data source',
}),
truncateText: true,
render: (name: string, record) => {
Expand Down Expand Up @@ -274,7 +284,11 @@ export const OpenSearchConnectionTable = ({
type: 'icon',
onClick: (item: DataSourceConnection) => {
setSelectedItems([item]);
setModalVisible(true);
if (inCreatePage) {
handleUnassignDataSources([item]);
} else {
setModalVisible(true);
}
},
'data-test-subj': 'workspace-detail-dataSources-table-actions-remove',
},
Expand All @@ -291,23 +305,36 @@ export const OpenSearchConnectionTable = ({

return (
<>
<EuiInMemoryTable
items={filteredDataSources}
itemId="id"
columns={columns}
selection={selection}
search={search}
key={connectionType}
isSelectable={true}
itemIdToExpandedRowMap={itemIdToExpandedRowMap}
isExpandable={true}
pagination={{
initialPageSize: 10,
pageSizeOptions: [10, 20, 30],
}}
/>
{inCreatePage ? (
<EuiInMemoryTable
items={filteredDataSources}
itemId="id"
columns={columns}
selection={selection}
key={connectionType}
isSelectable={true}
itemIdToExpandedRowMap={itemIdToExpandedRowMap}
isExpandable={true}
/>
) : (
<EuiInMemoryTable
items={filteredDataSources}
itemId="id"
columns={columns}
selection={selection}
search={search}
key={connectionType}
isSelectable={true}
itemIdToExpandedRowMap={itemIdToExpandedRowMap}
isExpandable={true}
pagination={{
initialPageSize: 10,
pageSizeOptions: [10, 20, 30],
}}
/>
)}
<EuiSpacer />
{modalVisible && (
{modalVisible && !inCreatePage && (
<EuiConfirmModal
data-test-subj="workspaceForm-cancelModal"
title={i18n.translate('workspace.detail.dataSources.modal.title', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,85 +4,122 @@
*/

import React from 'react';
import { fireEvent, render, act } from '@testing-library/react';
import { fireEvent, render, act, waitFor } from '@testing-library/react';
import { SelectDataSourcePanel, SelectDataSourcePanelProps } from './select_data_source_panel';
import { coreMock } from '../../../../../core/public/mocks';
import * as utils from '../../utils';

const dataSources = [
const currentAssignedDataSources = [
{
id: 'id1',
title: 'title1',
name: 'title1',
description: 'ds-1-description',
type: 'OpenSearch',
connectionType: 0,
},
{
id: 'id2',
name: 'title2',
description: 'ds-1-description',
type: 'S3GLUE',
connectionType: 0,
},
{ id: 'id2', title: 'title2' },
];

jest.mock('../../utils', () => ({
getDataSourcesList: jest.fn().mockResolvedValue(dataSources),
}));
const dataSources = [
{
id: 'id3',
title: 'title3',
description: 'ds-3-description',
auth: '',
dataSourceEngineType: '',
workspaces: [],
},
{
id: 'id4',
title: 'title4',
description: 'ds-4-description',
auth: '',
dataSourceEngineType: '',
workspaces: [],
},
];

jest.spyOn(utils, 'getDataSourcesList').mockResolvedValue(dataSources);

const mockCoreStart = coreMock.createStart();

const setup = ({
savedObjects = mockCoreStart.savedObjects,
selectedDataSources = [],
assignedDataSources = [],
onChange = jest.fn(),
errors = undefined,
isDashboardAdmin = true,
}: Partial<SelectDataSourcePanelProps>) => {
return render(
<SelectDataSourcePanel
onChange={onChange}
savedObjects={savedObjects}
selectedDataSources={selectedDataSources}
assignedDataSources={assignedDataSources}
errors={errors}
isDashboardAdmin={isDashboardAdmin}
/>
);
};

describe('SelectDataSourcePanel', () => {
it('should render consistent data sources when selected data sources passed', () => {
const { getByText } = setup({ selectedDataSources: dataSources });
const { getByText } = setup({ assignedDataSources: currentAssignedDataSources });

expect(getByText(dataSources[0].title)).toBeInTheDocument();
expect(getByText(dataSources[1].title)).toBeInTheDocument();
expect(getByText(currentAssignedDataSources[0].name)).toBeInTheDocument();
expect(getByText(currentAssignedDataSources[1].name)).toBeInTheDocument();
});

it('should call onChange when clicking add new data source button', () => {
it('should call onChange when updating data sources', async () => {
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', {
configurable: true,
value: 600,
});
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', {
configurable: true,
value: 600,
});
const onChangeMock = jest.fn();
const { getByTestId } = setup({ onChange: onChangeMock });
const { getByTestId, getAllByText, getByText } = setup({
onChange: onChangeMock,
assignedDataSources: [],
});

expect(onChangeMock).not.toHaveBeenCalled();
fireEvent.click(getByTestId('workspaceForm-select-dataSource-addNew'));
fireEvent.click(getByTestId('workspace-creator-dataSources-assign-button'));

await waitFor(() => {
expect(getByText(dataSources[0].title)).toBeInTheDocument();
});

fireEvent.click(getAllByText(dataSources[0].title)[0]);
fireEvent.click(getByText('Associate data sources'));
expect(onChangeMock).toHaveBeenCalledWith([
{
id: '',
title: '',
connectionType: 0,
description: 'ds-3-description',
id: 'id3',
name: 'title3',
relatedConnections: [],
type: '',
},
]);
});

it('should call onChange when updating selected data sources in combo box', async () => {
const onChangeMock = jest.fn();
const { getByTitle, getByText } = setup({
onChange: onChangeMock,
selectedDataSources: [{ id: '', title: '' }],
});
expect(onChangeMock).not.toHaveBeenCalled();
await act(() => {
fireEvent.click(getByText('Select'));
});
fireEvent.click(getByTitle(dataSources[0].title));
expect(onChangeMock).toHaveBeenCalledWith([{ id: 'id1', title: 'title1' }]);
});

it('should call onChange when deleting selected data source', async () => {
const onChangeMock = jest.fn();
const { getByLabelText } = setup({
const { getByTestId } = setup({
onChange: onChangeMock,
selectedDataSources: [{ id: '', title: '' }],
assignedDataSources: [{ id: '', name: '', type: '', connectionType: 0 }],
});
expect(onChangeMock).not.toHaveBeenCalled();
await act(() => {
fireEvent.click(getByLabelText('Delete data source'));
fireEvent.click(getByTestId('workspace-detail-dataSources-table-actions-remove'));
});
expect(onChangeMock).toHaveBeenCalledWith([]);
});
Expand Down
Loading
Loading