Skip to content

Commit

Permalink
[Feature] Data sources associated objects tab (opensearch-project#1470)
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Liang <[email protected]>
  • Loading branch information
RyanL1997 authored Feb 27, 2024
1 parent 403eece commit 187b112
Show file tree
Hide file tree
Showing 5 changed files with 339 additions and 1 deletion.
9 changes: 9 additions & 0 deletions common/types/data_connections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ export interface PermissionsConfigurationProps {
hasSecurityAccess: boolean;
}

export interface AssociatedObject {
id: string;
name: string;
database: string;
type: string;
createdByIntegration: string;
accelerations: string;
}

export type Role = EuiComboBoxOptionOption;

export type DatasourceType = 'S3GLUE' | 'PROMETHEUS';
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,48 @@ exports[`Data Connection Page test Renders Prometheus data connection page with
Connection configuration
</span>
</button>
<button
aria-controls="random_html_id"
aria-selected="false"
class="euiTab"
id="associated_objects"
role="tab"
type="button"
>
<span
class="euiTab__content"
>
Associated Objects
</span>
</button>
<button
aria-controls="random_html_id"
aria-selected="false"
class="euiTab"
id="accelerations"
role="tab"
type="button"
>
<span
class="euiTab__content"
>
Accelerations
</span>
</button>
<button
aria-controls="random_html_id"
aria-selected="false"
class="euiTab"
id="installed_integrations"
role="tab"
type="button"
>
<span
class="euiTab__content"
>
Installed integrations
</span>
</button>
</div>
<div
aria-labelledby="access_control"
Expand Down Expand Up @@ -782,6 +824,48 @@ exports[`Data Connection Page test Renders S3 data connection page with data 1`]
Connection configuration
</span>
</button>
<button
aria-controls="random_html_id"
aria-selected="false"
class="euiTab"
id="associated_objects"
role="tab"
type="button"
>
<span
class="euiTab__content"
>
Associated Objects
</span>
</button>
<button
aria-controls="random_html_id"
aria-selected="false"
class="euiTab"
id="accelerations"
role="tab"
type="button"
>
<span
class="euiTab__content"
>
Accelerations
</span>
</button>
<button
aria-controls="random_html_id"
aria-selected="false"
class="euiTab"
id="installed_integrations"
role="tab"
type="button"
>
<span
class="euiTab__content"
>
Installed integrations
</span>
</button>
</div>
<div
aria-labelledby="access_control"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

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

export const AccelerationsRecommendationCallout = () => {
return (
<EuiCallOut
title="Accelerations recommended for tables. Setup acceleration or configure integrations"
iconType="iInCircle"
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useEffect, useState } from 'react';
import {
EuiInMemoryTable,
EuiLink,
EuiPanel,
EuiFlexGroup,
EuiFlexItem,
EuiText,
EuiHorizontalRule,
EuiButton,
EuiSpacer,
EuiEmptyPrompt,
} from '@elastic/eui';
import { AssociatedObject } from 'common/types/data_connections';
import { AccelerationsRecommendationCallout } from './accelerations_recommendation_callout';

interface AssociatedObjectsTabProps {
associatedObjects: AssociatedObject[];
}

export const AssociatedObjectsTab: React.FC<AssociatedObjectsTabProps> = ({
associatedObjects,
}) => {
const [lastUpdated, setLastUpdated] = useState('');

// TODO: FINISH THE REFRESH LOGIC
const fetchAssociatedObjects = async () => {
// Placeholder for data fetching logic
// After fetching data:
// setAssociatedObjects(fetchedData);
const now = new Date();
setLastUpdated(now.toUTCString()); // Update last updated time
};

useEffect(() => {
fetchAssociatedObjects();
}, []);

const AssociatedObjectsHeader = () => {
return (
<EuiFlexGroup direction="row">
<EuiFlexItem>
<EuiText size="m">
<h2 className="panel-title">Associated objects</h2>
Manage objects associated with this data sources.
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<div style={{ textAlign: 'right' }}>
<EuiText color="subdued" style={{ fontSize: 'small' }}>
Last updated at:
</EuiText>
<EuiText color="subdued" style={{ fontSize: 'small' }}>
{lastUpdated}
</EuiText>
</div>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
data-test-subj="freshButton"
iconType="refresh"
onClick={fetchAssociatedObjects}
>
Refresh
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
);
};

const noDataMessage = (
<EuiEmptyPrompt
title={<h2>You have no associated objects</h2>}
body={<p>Add or config tables from your data source or use Query Workbench.</p>}
actions={
<EuiButton
color="primary"
fill
onClick={() => window.open('https://example.com', '_blank')}
iconType="popout"
iconSide="left"
>
Query Workbench
</EuiButton>
}
/>
);

const columns = [
{
field: 'name',
name: 'Name',
sortable: true,
'data-test-subj': 'nameCell',
render: (name: string) => (
<EuiLink href="https://example.com" target="_blank">
{name}
</EuiLink>
),
},
{
field: 'database',
name: 'Database',
truncateText: true,
render: (database: string) => (
<EuiLink href="https://example.com" target="_blank">
{database}
</EuiLink>
),
},
{
field: 'type',
name: 'Type',
sortable: true,
},
{
field: 'createdByIntegration',
name: 'Created by Integration',
sortable: true,
},
{
field: 'accelerations',
name: 'Accelerations',
sortable: true,
},
{
name: 'Actions',
actions: [
{
name: 'Edit',
description: 'Edit this object',
type: 'icon',
icon: 'discoverApp',
onClick: (item: AssociatedObject) => console.log('Edit', item),
},
{
name: 'Delete',
description: 'Delete this object',
type: 'icon',
icon: 'bolt',
onClick: (item: AssociatedObject) => console.log('Delete', item),
},
],
},
];

const search = {
box: {
incremental: true,
schema: {
fields: { name: { type: 'string' }, database: { type: 'string' } },
},
},
};

const pagination = {
initialPageSize: 10,
pageSizeOptions: [10, 25, 50],
};

const sorting = {
sort: {
field: 'name',
direction: 'asc',
},
};

return (
<>
<EuiSpacer />
<EuiPanel>
<AssociatedObjectsHeader />
<EuiHorizontalRule />
<AccelerationsRecommendationCallout />
<EuiSpacer />
{associatedObjects.length > 0 ? (
<EuiInMemoryTable
items={associatedObjects}
columns={columns}
search={search}
pagination={pagination}
sorting={sorting}
noItemsMessage={associatedObjects.length === 0 ? noDataMessage : undefined}
/>
) : (
noDataMessage
)}
</EuiPanel>
<EuiSpacer />
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { AccessControlTab } from './access_control_tab';
import { ConnectionDetails } from './connection_details';
import { DatasourceType } from '../../../../../common/types/data_connections';
import { DatasourceTypeToDisplayName } from '../../../../../common/constants/data_connections';
import { AssociatedObjectsTab } from './associated_objects_tab';

interface DatasourceDetails {
allowedRoles: string[];
Expand Down Expand Up @@ -132,7 +133,7 @@ export const DataConnection = (props: any) => {
properties: data.properties,
});
})
.catch((err) => {
.catch((_err) => {
setHasAccess(false);
});
}, [chrome, http]);
Expand Down Expand Up @@ -165,6 +166,37 @@ export const DataConnection = (props: any) => {
/>
),
},
{
id: 'associated_objects',
name: 'Associated Objects',
disabled: false,
content: (
<AssociatedObjectsTab
associatedObjects={
[
// {
// id: '1',
// name: 'Table_name_1',
// database: 'db1',
// type: 'Table',
// createdByIntegration: 'xx',
// accelerations: 'xxx_skipping',
// },
]
}
/>
),
},
{
id: 'accelerations',
name: 'Accelerations',
disabled: false,
},
{
id: 'installed_integrations',
name: 'Installed integrations',
disabled: false,
},
];

const QueryOrAccelerateData = () => {
Expand Down

0 comments on commit 187b112

Please sign in to comment.