You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by er...@apache.org on 2020/11/24 20:14:22 UTC
[incubator-superset] branch master updated: feat: add certification
info to table selector (#11785)
This is an automated email from the ASF dual-hosted git repository.
erikrit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push:
new c0224aa feat: add certification info to table selector (#11785)
c0224aa is described below
commit c0224aa92819e45f86dabf693da9fe7aaba9391a
Author: Erik Ritter <er...@airbnb.com>
AuthorDate: Tue Nov 24 12:13:52 2020 -0800
feat: add certification info to table selector (#11785)
---
.../javascripts/components/TableSelector_spec.jsx | 3 ++-
.../src/components/CertifiedIconWithTooltip.tsx | 9 +++++++-
superset-frontend/src/components/TableSelector.tsx | 27 ++++++++++++++++------
superset/connectors/sqla/models.py | 7 ++++++
superset/views/core.py | 5 ++++
tests/core_tests.py | 7 +++---
6 files changed, 46 insertions(+), 12 deletions(-)
diff --git a/superset-frontend/spec/javascripts/components/TableSelector_spec.jsx b/superset-frontend/spec/javascripts/components/TableSelector_spec.jsx
index 96b1d2e..320e4f5 100644
--- a/superset-frontend/spec/javascripts/components/TableSelector_spec.jsx
+++ b/superset-frontend/spec/javascripts/components/TableSelector_spec.jsx
@@ -60,11 +60,12 @@ const schemaOptions = {
};
const selectedSchema = { label: 'main', title: 'main', value: 'main' };
const selectedTable = {
+ extra: null,
label: 'birth_names',
schema: 'main',
title: 'birth_names',
- value: 'birth_names',
type: undefined,
+ value: 'birth_names',
};
async function mountAndWait(props = mockedProps) {
diff --git a/superset-frontend/src/components/CertifiedIconWithTooltip.tsx b/superset-frontend/src/components/CertifiedIconWithTooltip.tsx
index e96b35f..e4132dc 100644
--- a/superset-frontend/src/components/CertifiedIconWithTooltip.tsx
+++ b/superset-frontend/src/components/CertifiedIconWithTooltip.tsx
@@ -24,11 +24,13 @@ import TooltipWrapper from 'src/components/TooltipWrapper';
interface CertifiedIconWithTooltipProps {
certifiedBy?: string;
details?: string;
+ size?: number;
}
function CertifiedIconWithTooltip({
certifiedBy,
details,
+ size = 24,
}: CertifiedIconWithTooltipProps) {
return (
<TooltipWrapper
@@ -40,7 +42,12 @@ function CertifiedIconWithTooltip({
</>
}
>
- <Icon color={supersetTheme.colors.primary.base} name="certified" />
+ <Icon
+ color={supersetTheme.colors.primary.base}
+ height={size}
+ width={size}
+ name="certified"
+ />
</TooltipWrapper>
);
}
diff --git a/superset-frontend/src/components/TableSelector.tsx b/superset-frontend/src/components/TableSelector.tsx
index 4c59359..c5c3a52 100644
--- a/superset-frontend/src/components/TableSelector.tsx
+++ b/superset-frontend/src/components/TableSelector.tsx
@@ -29,6 +29,7 @@ import FormLabel from 'src/components/FormLabel';
import DatabaseSelector from './DatabaseSelector';
import RefreshLabel from './RefreshLabel';
+import CertifiedIconWithTooltip from './CertifiedIconWithTooltip';
const FieldTitle = styled.p`
color: ${({ theme }) => theme.colors.secondary.light2};
@@ -65,7 +66,14 @@ const TableSelectorWrapper = styled.div`
`;
const TableLabel = styled.span`
+ align-items: center;
+ display: flex;
white-space: nowrap;
+
+ > svg,
+ > small {
+ margin-right: ${({ theme }) => theme.gridUnit}px;
+ }
`;
interface TableSelectorProps {
@@ -146,6 +154,7 @@ const TableSelector: FunctionComponent<TableSelectorProps> = ({
label: o.label,
title: o.title,
type: o.type,
+ extra: o?.extra,
}));
setTableLoading(false);
setTableOptions(options);
@@ -244,13 +253,16 @@ const TableSelector: FunctionComponent<TableSelectorProps> = ({
function renderTableOption(option: any) {
return (
<TableLabel title={option.label}>
- <span className="m-r-5">
- <small className="text-muted">
- <i
- className={`fa fa-${option.type === 'view' ? 'eye' : 'table'}`}
- />
- </small>
- </span>
+ {option.extra?.certification && (
+ <CertifiedIconWithTooltip
+ certifiedBy={option.extra.certification.certified_by}
+ details={option.extra.certification.details}
+ size={20}
+ />
+ )}
+ <small className="text-muted">
+ <i className={`fa fa-${option.type === 'view' ? 'eye' : 'table'}`} />
+ </small>
{option.label}
</TableLabel>
);
@@ -308,6 +320,7 @@ const TableSelector: FunctionComponent<TableSelectorProps> = ({
// @ts-ignore
value={currentTableName}
optionRenderer={renderTableOption}
+ valueRenderer={renderTableOption}
/>
);
} else if (formMode) {
diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py
index c75c081..e19c1b9 100644
--- a/superset/connectors/sqla/models.py
+++ b/superset/connectors/sqla/models.py
@@ -700,6 +700,13 @@ class SqlaTable( # pylint: disable=too-many-public-methods,too-many-instance-at
data_["is_sqllab_view"] = self.is_sqllab_view
return data_
+ @property
+ def extra_dict(self) -> Dict[str, Any]:
+ try:
+ return json.loads(self.extra)
+ except (TypeError, json.JSONDecodeError):
+ return {}
+
def values_for_column(self, column_name: str, limit: int = 10000) -> List[Any]:
"""Runs query against sqla to retrieve some
sample values for the given column.
diff --git a/superset/views/core.py b/superset/views/core.py
index e12e50c..e5730e5 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -981,6 +981,8 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
max_tables = max_items * len(tables) // total_items
max_views = max_items * len(views) // total_items
+ dataset_tables = {table.name: table for table in database.tables}
+
table_options = [
{
"value": tn.table,
@@ -988,6 +990,9 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
"label": get_datasource_label(tn),
"title": get_datasource_label(tn),
"type": "table",
+ "extra": dataset_tables[f"{tn.schema}.{tn.table}"].extra_dict
+ if (f"{tn.schema}.{tn.table}" in dataset_tables)
+ else None,
}
for tn in tables[:max_tables]
]
diff --git a/tests/core_tests.py b/tests/core_tests.py
index 87b698f..94f3c29 100644
--- a/tests/core_tests.py
+++ b/tests/core_tests.py
@@ -155,7 +155,7 @@ class TestCore(SupersetTestCase):
response = json.loads(rv.data.decode("utf-8"))
self.assertEqual(rv.status_code, 200)
- expeted_response = {
+ expected_response = {
"options": [
{
"label": "ab_role",
@@ -163,11 +163,12 @@ class TestCore(SupersetTestCase):
"title": "ab_role",
"type": "table",
"value": "ab_role",
+ "extra": None,
}
],
"tableLength": 1,
}
- self.assertEqual(response, expeted_response)
+ self.assertEqual(response, expected_response)
def test_get_superset_tables_not_found(self):
self.login(username="admin")
@@ -862,7 +863,7 @@ class TestCore(SupersetTestCase):
def test_get_select_star_not_allowed(self):
"""
- Database API: Test get select star not allowed
+ Database API: Test get select star not allowed
"""
self.login(username="gamma")
example_db = utils.get_example_database()