This is an automated email from the ASF dual-hosted git repository.
hugh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 85251f8cae fix: Tags Page Polish (#25403)
85251f8cae is described below
commit 85251f8cae6fa2d6a77a73697fb0575cd37c1c92
Author: Hugh A. Miles II <[email protected]>
AuthorDate: Fri Sep 29 22:13:26 2023 -0400
fix: Tags Page Polish (#25403)
Co-authored-by: Lily Kuang <[email protected]>
---
.../src/features/allEntities/AllEntitiesTable.tsx | 112 +++++++++++++++++----
superset-frontend/src/pages/AllEntities/index.tsx | 9 +-
.../src/pages/DashboardList/index.tsx | 2 +-
superset/daos/tag.py | 16 ++-
superset/tags/schemas.py | 14 +--
5 files changed, 116 insertions(+), 37 deletions(-)
diff --git a/superset-frontend/src/features/allEntities/AllEntitiesTable.tsx
b/superset-frontend/src/features/allEntities/AllEntitiesTable.tsx
index 79e1c11ecc..75491c5baa 100644
--- a/superset-frontend/src/features/allEntities/AllEntitiesTable.tsx
+++ b/superset-frontend/src/features/allEntities/AllEntitiesTable.tsx
@@ -22,18 +22,33 @@ import { t, styled, logging } from '@superset-ui/core';
import TableView, { EmptyWrapperType } from 'src/components/TableView';
import { addDangerToast } from 'src/components/MessageToasts/actions';
import Loading from 'src/components/Loading';
+import { TagsList } from 'src/components/Tags';
+import FacePile from 'src/components/FacePile';
+import Tag from 'src/types/TagType';
+import Owner from 'src/types/Owner';
+import { EmptyStateBig } from 'src/components/EmptyState';
import { fetchObjects } from '../tags/tags';
+const MAX_TAGS_TO_SHOW = 3;
+
const AllEntitiesTableContainer = styled.div`
text-align: left;
border-radius: ${({ theme }) => theme.gridUnit * 1}px 0;
- margin: 0 ${({ theme }) => theme.gridUnit * 4}px;
.table {
table-layout: fixed;
}
.td {
width: 33%;
}
+ .entity-title {
+ font-family: Inter;
+ font-size: ${({ theme }) => theme.typography.sizes.m}px;
+ font-weight: ${({ theme }) => theme.typography.weights.medium};
+ line-height: 17px;
+ letter-spacing: 0px;
+ text-align: left;
+ margin: ${({ theme }) => theme.gridUnit * 4}px 0;
+ }
`;
interface TaggedObject {
@@ -44,6 +59,8 @@ interface TaggedObject {
changed_on: moment.MomentInput;
created_by: number | undefined;
creator: string;
+ owners: Owner[];
+ tags: Tag[];
}
interface TaggedObjects {
@@ -54,10 +71,12 @@ interface TaggedObjects {
interface AllEntitiesTableProps {
search?: string;
+ setShowTagModal: (show: boolean) => void;
}
export default function AllEntitiesTable({
search = '',
+ setShowTagModal,
}: AllEntitiesTableProps) {
type objectType = 'dashboard' | 'chart' | 'query';
@@ -66,8 +85,19 @@ export default function AllEntitiesTable({
chart: [],
query: [],
});
+ const [isLoading, setLoading] = useState<boolean>(true);
+ const showListViewObjs =
+ objects.dashboard.length > 0 ||
+ objects.chart.length > 0 ||
+ objects.query.length > 0;
useEffect(() => {
+ if (search === '') {
+ return;
+ }
+
+ setLoading(true);
+
fetchObjects(
{ tags: search, types: null },
(data: TaggedObject[]) => {
@@ -77,6 +107,7 @@ export default function AllEntitiesTable({
objects[object_type].push(object);
});
setObjects(objects);
+ setLoading(false);
},
(error: Response) => {
addDangerToast('Error Fetching Tagged Objects');
@@ -89,7 +120,10 @@ export default function AllEntitiesTable({
const data = objects[type].map((o: TaggedObject) => ({
[type]: <a href={o.url}>{o.name}</a>,
modified: moment.utc(o.changed_on).fromNow(),
+ tags: o.tags,
+ owners: o.owners,
}));
+
return (
<TableView
className="table-condensed"
@@ -99,27 +133,69 @@ export default function AllEntitiesTable({
columns={[
{
accessor: type,
- Header: type.charAt(0).toUpperCase() + type.slice(1),
+ Header: 'Title',
+ },
+ {
+ Cell: ({
+ row: {
+ original: { tags = [] },
+ },
+ }: {
+ row: {
+ original: {
+ tags: Tag[];
+ };
+ };
+ }) => (
+ // Only show custom type tags
+ <TagsList
+ tags={tags.filter(
+ (tag: Tag) =>
+ tag.type === 'TagTypes.custom' || tag.type === 1,
+ )}
+ maxTags={MAX_TAGS_TO_SHOW}
+ />
+ ),
+ Header: t('Tags'),
+ accessor: 'tags',
+ disableSortBy: true,
+ },
+ {
+ Cell: ({
+ row: {
+ original: { owners = [] },
+ },
+ }: any) => <FacePile users={owners} />,
+ Header: t('Owners'),
+ accessor: 'owners',
+ disableSortBy: true,
+ size: 'xl',
},
- { accessor: 'modified', Header: 'Modified' },
]}
/>
);
};
- if (objects) {
- return (
- <AllEntitiesTableContainer>
- <h3>{t('Dashboards')}</h3>
- {renderTable('dashboard')}
- <hr />
- <h3>{t('Charts')}</h3>
- {renderTable('chart')}
- <hr />
- <h3>{t('Queries')}</h3>
- {renderTable('query')}
- </AllEntitiesTableContainer>
- );
- }
- return <Loading />;
+ if (isLoading) return <Loading />;
+ return (
+ <AllEntitiesTableContainer>
+ {showListViewObjs ? (
+ <>
+ <div className="entity-title">{t('Dashboards')}</div>
+ {renderTable('dashboard')}
+ <div className="entity-title">{t('Charts')}</div>
+ {renderTable('chart')}
+ <div className="entity-title">{t('Queries')}</div>
+ {renderTable('query')}
+ </>
+ ) : (
+ <EmptyStateBig
+ image="dashboard.svg"
+ title={t('No entities have this tag currently assigned')}
+ buttonAction={() => setShowTagModal(true)}
+ buttonText={t('Add tag to entities')}
+ />
+ )}
+ </AllEntitiesTableContainer>
+ );
}
diff --git a/superset-frontend/src/pages/AllEntities/index.tsx
b/superset-frontend/src/pages/AllEntities/index.tsx
index eaa8e35703..63d5883537 100644
--- a/superset-frontend/src/pages/AllEntities/index.tsx
+++ b/superset-frontend/src/pages/AllEntities/index.tsx
@@ -57,7 +57,7 @@ const AllEntitiesContainer = styled.div`
margin-bottom: ${theme.gridUnit * 1}px;
}
.entities {
- margin: ${theme.gridUnit * 7.5}px; 0px;
+ margin: ${theme.gridUnit * 6}px; 0px;
}
`}
`;
@@ -88,6 +88,7 @@ function AllEntities() {
const [tag, setTag] = useState<Tag | null>(null);
const [showTagModal, setShowTagModal] = useState<boolean>(false);
const { addSuccessToast, addDangerToast } = useToasts();
+
const editableTitleProps = {
title: tag?.name || '',
placeholder: 'testing',
@@ -166,10 +167,14 @@ function AllEntities() {
menuDropdownProps={{
disabled: true,
}}
+ showMenuDropdown={false}
/>
</AllEntitiesNav>
<div className="entities">
- <AllEntitiesTable search={tag?.name || ''} />
+ <AllEntitiesTable
+ search={tag?.name || ''}
+ setShowTagModal={setShowTagModal}
+ />
</div>
</AllEntitiesContainer>
);
diff --git a/superset-frontend/src/pages/DashboardList/index.tsx
b/superset-frontend/src/pages/DashboardList/index.tsx
index 29bb51b961..d7760ffbbc 100644
--- a/superset-frontend/src/pages/DashboardList/index.tsx
+++ b/superset-frontend/src/pages/DashboardList/index.tsx
@@ -86,7 +86,7 @@ interface DashboardListProps {
};
}
-interface Dashboard {
+export interface Dashboard {
changed_by_name: string;
changed_on_delta_humanized: string;
changed_by: string;
diff --git a/superset/daos/tag.py b/superset/daos/tag.py
index c063657ea0..b6872a5376 100644
--- a/superset/daos/tag.py
+++ b/superset/daos/tag.py
@@ -175,16 +175,6 @@ class TagDAO(BaseDAO[Tag]):
returns a list of tagged objects filtered by tag names and object types
if no filters applied returns all tagged objects
"""
- # id = fields.Int()
- # type = fields.String()
- # name = fields.String()
- # url = fields.String()
- # changed_on = fields.DateTime()
- # created_by = fields.Nested(UserSchema)
- # creator = fields.String(
-
- # filter types
-
results: list[dict[str, Any]] = []
# dashboards
@@ -211,6 +201,8 @@ class TagDAO(BaseDAO[Tag]):
"changed_on": obj.changed_on,
"created_by": obj.created_by_fk,
"creator": obj.creator(),
+ "tags": obj.tags,
+ "owners": obj.owners,
}
for obj in dashboards
)
@@ -238,6 +230,8 @@ class TagDAO(BaseDAO[Tag]):
"changed_on": obj.changed_on,
"created_by": obj.created_by_fk,
"creator": obj.creator(),
+ "tags": obj.tags,
+ "owners": obj.owners,
}
for obj in charts
)
@@ -265,6 +259,8 @@ class TagDAO(BaseDAO[Tag]):
"changed_on": obj.changed_on,
"created_by": obj.created_by_fk,
"creator": obj.creator(),
+ "tags": obj.tags,
+ "owners": [obj.creator()],
}
for obj in saved_queries
)
diff --git a/superset/tags/schemas.py b/superset/tags/schemas.py
index 571a2a03c9..75fdc2410a 100644
--- a/superset/tags/schemas.py
+++ b/superset/tags/schemas.py
@@ -38,6 +38,12 @@ openapi_spec_methods_override = {
}
+class TagGetResponseSchema(Schema):
+ id = fields.Int()
+ name = fields.String()
+ type = fields.String()
+
+
class TaggedObjectEntityResponseSchema(Schema):
id = fields.Int()
type = fields.String()
@@ -46,12 +52,8 @@ class TaggedObjectEntityResponseSchema(Schema):
changed_on = fields.DateTime()
created_by = fields.Nested(UserSchema(exclude=["username"]))
creator = fields.String()
-
-
-class TagGetResponseSchema(Schema):
- id = fields.Int()
- name = fields.String()
- type = fields.String()
+ tags = fields.List(fields.Nested(TagGetResponseSchema))
+ owners = fields.List(fields.Nested(UserSchema))
class TagObjectSchema(Schema):