Unverified Commit b4274486 authored by Diksha Thakur's avatar Diksha Thakur Committed by GitHub

feat: Adding schema description to search result items (#468)

* Adding new component for schema name and attached description

* Adding underline to schema name

* Adding schema_description to TableResource

* Adding style in ResourceListItem component

* Modified unit test to incorporate schema desciption changes

* Reverted unwanted addition of schema_description in unrelated files

* Changed calling Schema Info Component and related unit test cases

* Changed python test to incorporate schema description

* Identation fixes

* Unit test cases for SchemaInfo component

* removing unnecessary imports

* Changing unit test name
parent 8d5bda39
......@@ -21,6 +21,7 @@ def map_table_result(result: Dict) -> Dict:
'description': result.get('description', None),
'database': result.get('database', None),
'schema': result.get('schema', None),
'schema_description': result.get('schema_description', None),
'badges': result.get('badges', None),
'last_updated_timestamp': result.get('last_updated_timestamp', None),
}
......
......@@ -20,6 +20,7 @@ $divider: $gray15 !default;
$stroke: $gray20 !default;
$stroke-light: $gray10 !default;
$stroke-focus: $gray60 !default;
$stroke-underline: $gray40 !default;
// Typography
......
import * as React from 'react';
import { OverlayTrigger, Popover } from 'react-bootstrap';
import './styles.scss';
export interface SchemaInfoProps{
schema: string;
table: string;
desc: string;
placement?: string;
}
const SchemaInfo: React.SFC<SchemaInfoProps> = ({ schema, table, desc, placement}) => {
const popoverHoverFocus = (
<Popover id="popover-trigger-hover-focus">
<strong>{ schema }:</strong> { desc }
</Popover>
);
return (
<>
<OverlayTrigger
trigger={['hover', 'focus']}
placement={ placement }
overlay={popoverHoverFocus}
>
<span className="underline">{ schema }</span>
</OverlayTrigger>.{ table }
</>
);
};
SchemaInfo.defaultProps = {
placement: 'bottom',
};
export default SchemaInfo;
@import 'variables';
.underline {
box-shadow: 0px 1px 0px $stroke-underline;
&:hover,
&:focus {
background: $btn-default-bg-hover;
}
}
import * as React from 'react';
import { shallow } from 'enzyme';
import { OverlayTrigger, Popover } from 'react-bootstrap';
import SchemaInfo, { SchemaInfoProps } from "components/common/ResourceListItem/SchemaInfo";
describe('SchemaInfo', () => {
const setup = (propOverrides?: Partial<SchemaInfoProps>) => {
const props: SchemaInfoProps = {
schema: 'tableSchema',
table: 'tableName',
desc: 'schemaDescription',
placement: 'bottom',
...propOverrides
};
const wrapper = shallow(<SchemaInfo {...props} />);
return { props, wrapper };
};
describe('render', () => {
let props: SchemaInfoProps;
let wrapper;
beforeAll(() => {
const setupResult = setup();
props = setupResult.props;
wrapper = setupResult.wrapper;
});
it('renders OverlayTrigger with correct placement', () => {
expect(wrapper.find(OverlayTrigger).props().placement).toEqual(props.placement);
});
it('renders OverlayTrigger with correct popover', () => {
const expectedPopover = (
<Popover id="popover-trigger-hover-focus">
<strong>{ props.schema }:</strong> { props.desc }
</Popover>
);
expect(wrapper.find(OverlayTrigger).props().overlay).toEqual(expectedPopover);
});
it('renders OverlayTrigger with correct schema name', () => {
expect(wrapper.find(OverlayTrigger).find('.underline').text()).toEqual(props.schema);
});
it('renders correct table name', () => {
expect(wrapper.children().at(1).text()).toEqual('.');
expect(wrapper.children().at(2).text()).toEqual(props.table);
});
});
});
......@@ -4,6 +4,7 @@ import { shallow } from 'enzyme';
import { Link } from 'react-router-dom';
import BookmarkIcon from 'components/common/Bookmark/BookmarkIcon';
import SchemaInfo from 'components/common/ResourceListItem/SchemaInfo';
import TableListItem, { TableListItemProps } from '.';
import { ResourceType, Badge, TagType } from 'interfaces';
......@@ -36,6 +37,7 @@ describe('TableListItem', () => {
badges: [ { tag_name: 'badgeName', tag_type: TagType.BADGE } ],
name: 'tableName',
schema: 'tableSchema',
schema_description: 'schemaDescription',
},
...propOverrides
};
......@@ -93,13 +95,57 @@ describe('TableListItem', () => {
it('renders start correct icon', () => {
const startIcon = resourceInfo.find('.resource-icon');
expect(startIcon.exists()).toBe(true);
expect(startIcon.props().className).toEqual(wrapper.instance().generateResourceIconClass(props.table.database));
});
it('renders table name', () => {
expect(resourceInfo.find('.resource-name').children().at(0).text()).toEqual('tableSchema.tableName');
describe('if props.table has schema description', () => {
let schemaInfo;
beforeAll(() => {
schemaInfo = resourceInfo.find(SchemaInfo);
});
it('renders table name schema and description', () => {
expect(schemaInfo.props()).toMatchObject({
schema: props.table.schema,
table: props.table.name,
desc: props.table.schema_description,
});
});
});
describe('if props.table not have schema description', () => {
it('if schema description is empty string', () => {
const { props, wrapper } = setup({ table: {
type: ResourceType.table,
cluster: '',
database: 'testdb',
description: 'I am the description',
key: '',
last_updated_timestamp: 1553829681,
badges: [ { tag_name: 'badgeName', tag_type: TagType.BADGE } ],
name: 'tableName',
schema: 'tableSchema',
schema_description: '',
}});
expect(wrapper.find('.resource-name').children().at(0).text()).toEqual('tableSchema.tableName');
});
it('if schema description is null', () => {
const { props, wrapper } = setup({ table: {
type: ResourceType.table,
cluster: '',
database: 'testdb',
description: 'I am the description',
key: '',
last_updated_timestamp: 1553829681,
badges: [ { tag_name: 'badgeName', tag_type: TagType.BADGE } ],
name: 'tableName',
schema: 'tableSchema',
schema_description: null,
}});
expect(wrapper.find('.resource-name').children().at(0).text()).toEqual('tableSchema.tableName');
});
});
it('renders a bookmark icon in the resource name with correct props', () => {
......@@ -151,6 +197,7 @@ describe('TableListItem', () => {
badges: null,
name: 'tableName',
schema: 'tableSchema',
schema_description: 'schemaDescription',
}});
expect(wrapper.find('.resource-badges').children()).toHaveLength(1);
});
......@@ -165,6 +212,7 @@ describe('TableListItem', () => {
badges: [],
name: 'tableName',
schema: 'tableSchema',
schema_description: 'schemaDescription',
}});
expect(wrapper.find('.resource-badges').children()).toHaveLength(1);
});
......
......@@ -10,6 +10,7 @@ import BookmarkIcon from 'components/common/Bookmark/BookmarkIcon';
import { getSourceDisplayName, getSourceIconClass } from 'config/config-utils';
import BadgeList from 'components/common/BadgeList';
import SchemaInfo from 'components/common/ResourceListItem/SchemaInfo';
export interface TableListItemProps {
table: TableResource;
......@@ -38,7 +39,11 @@ class TableListItem extends React.Component<TableListItemProps, {}> {
<div className="resource-info-text my-auto">
<div className="resource-name title-2">
<div className="truncated">
{ `${table.schema}.${table.name}`}
{
table.schema_description &&
<SchemaInfo schema={ table.schema } table = { table.name } desc={ table.schema_description }/>
}
{ !table.schema_description && `${table.schema}.${table.name}` }
</div>
<BookmarkIcon bookmarkKey={ table.key } resourceType={ table.type } />
</div>
......
......@@ -85,4 +85,5 @@
.title-2 {
color: $resource-title-color;
}
}
......@@ -38,6 +38,7 @@ export interface TableResource extends Resource {
last_updated_timestamp?: number;
name: string;
schema: string;
schema_description?: string;
badges?: Badge[];
};
......
......@@ -27,6 +27,7 @@ MOCK_TABLE_RESULTS = {
'last_updated_timestamp': 1527283287,
'name': 'test_table',
'schema': 'test_schema',
'schema_description': 'test_schema_description',
'tags': [],
'badges': []
}
......@@ -43,6 +44,7 @@ MOCK_PARSED_TABLE_RESULTS = [
'last_updated_timestamp': 1527283287,
'name': 'test_table',
'schema': 'test_schema',
'schema_description': 'test_schema_description',
'badges': []
}
]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment