From d98ebd330cca2575d2491b8ee048841ac6d6e211 Mon Sep 17 00:00:00 2001 From: jfrancos-mai <99757211+jfrancos-mai@users.noreply.github.com> Date: Tue, 23 May 2023 17:11:21 +0000 Subject: [PATCH] fix(ui): SchemaDescriptionField 'read-more' doesn't affect table height (#7970) --- .../__tests__/SchemaDescriptionField.test.tsx | 75 ++++++++++++------- .../components/SchemaDescriptionField.tsx | 18 +++-- .../profile/features/TableOfMlFeatures.tsx | 7 +- .../Schema/utils/useDescriptionRenderer.tsx | 10 ++- 4 files changed, 73 insertions(+), 37 deletions(-) diff --git a/datahub-web-react/src/app/entity/dataset/profile/__tests__/SchemaDescriptionField.test.tsx b/datahub-web-react/src/app/entity/dataset/profile/__tests__/SchemaDescriptionField.test.tsx index 30255bf9e8..a7878b6a85 100644 --- a/datahub-web-react/src/app/entity/dataset/profile/__tests__/SchemaDescriptionField.test.tsx +++ b/datahub-web-react/src/app/entity/dataset/profile/__tests__/SchemaDescriptionField.test.tsx @@ -10,7 +10,13 @@ describe('SchemaDescriptionField', () => { const { getByText, getByRole, queryByText } = render( - {}} /> + {}} + description="test description updated" + isEdited + onUpdate={async () => {}} + />{' '} , ); @@ -24,6 +30,8 @@ describe('SchemaDescriptionField', () => { {}} description="test description" original="test description" isEdited @@ -44,42 +52,51 @@ describe('SchemaDescriptionField', () => { it('renders short messages without show more / show less', () => { const { getByText, queryByText } = render( - Promise.resolve()} />, + {}} + description="short description" + onUpdate={() => Promise.resolve()} + />, ); expect(getByText('short description')).toBeInTheDocument(); expect(queryByText('Read Less')).not.toBeInTheDocument(); expect(queryByText('Read More')).not.toBeInTheDocument(); }); - it('renders longer messages with show more / show less', () => { + describe('renders longer messages with show more / show less', () => { const longDescription = 'really long description over 80 characters, really long description over 80 characters, really long description over 80 characters, really long description over 80 characters, really long description over 80 characters'; - const { getByText, queryByText } = render( - Promise.resolve()} />, - ); - expect(getByText('Read More')).toBeInTheDocument(); - expect(queryByText(longDescription)).not.toBeInTheDocument(); + it('renders longer messages with show more when not expanded', () => { + const onClick = jest.fn(); + const { getByText, queryByText } = render( + Promise.resolve()} + />, + ); + expect(getByText('Read More')).toBeInTheDocument(); + expect(queryByText(longDescription)).not.toBeInTheDocument(); + fireEvent.click(getByText('Read More')); + expect(onClick).toHaveBeenCalled(); + }); - fireEvent( - getByText('Read More'), - new MouseEvent('click', { - bubbles: true, - cancelable: true, - }), - ); - - expect(getByText(longDescription)).toBeInTheDocument(); - expect(getByText('Read Less')).toBeInTheDocument(); - - fireEvent( - getByText('Read Less'), - new MouseEvent('click', { - bubbles: true, - cancelable: true, - }), - ); - - expect(getByText('Read More')).toBeInTheDocument(); - expect(queryByText(longDescription)).not.toBeInTheDocument(); + it('renders longer messages with show less when expanded', () => { + const onClick = jest.fn(); + const { getByText } = render( + Promise.resolve()} + />, + ); + expect(getByText(longDescription)).toBeInTheDocument(); + expect(getByText('Read Less')).toBeInTheDocument(); + fireEvent.click(getByText('Read Less')); + expect(onClick).toHaveBeenCalled(); + }); }); }); diff --git a/datahub-web-react/src/app/entity/dataset/profile/schema/components/SchemaDescriptionField.tsx b/datahub-web-react/src/app/entity/dataset/profile/schema/components/SchemaDescriptionField.tsx index d555513362..1d4f155f79 100644 --- a/datahub-web-react/src/app/entity/dataset/profile/schema/components/SchemaDescriptionField.tsx +++ b/datahub-web-react/src/app/entity/dataset/profile/schema/components/SchemaDescriptionField.tsx @@ -78,6 +78,8 @@ const StyledViewer = styled(Editor)` `; type Props = { + onExpanded: (expanded: boolean) => void; + expanded: boolean; description: string; original?: string | null; onUpdate: ( @@ -88,10 +90,16 @@ type Props = { const ABBREVIATED_LIMIT = 80; -export default function DescriptionField({ description, onUpdate, isEdited = false, original }: Props) { +export default function DescriptionField({ + expanded, + onExpanded: handleExpanded, + description, + onUpdate, + isEdited = false, + original, +}: Props) { const [showAddModal, setShowAddModal] = useState(false); const overLimit = removeMarkdown(description).length > 80; - const [expanded, setExpanded] = useState(!overLimit); const isSchemaEditable = React.useContext(SchemaEditableContext); const onCloseModal = () => setShowAddModal(false); const { urn, entityType } = useEntityData(); @@ -129,7 +137,7 @@ export default function DescriptionField({ description, onUpdate, isEdited = fal return ( - {expanded ? ( + {expanded || !overLimit ? ( <> {!!description && } {!!description && ( @@ -137,7 +145,7 @@ export default function DescriptionField({ description, onUpdate, isEdited = fal {overLimit && ( { - setExpanded(false); + handleExpanded(false); }} > Read Less @@ -155,7 +163,7 @@ export default function DescriptionField({ description, onUpdate, isEdited = fal <> { - setExpanded(true); + handleExpanded(true); }} > Read More diff --git a/datahub-web-react/src/app/entity/mlFeatureTable/profile/features/TableOfMlFeatures.tsx b/datahub-web-react/src/app/entity/mlFeatureTable/profile/features/TableOfMlFeatures.tsx index cf0bb808b3..1c3cbf1def 100644 --- a/datahub-web-react/src/app/entity/mlFeatureTable/profile/features/TableOfMlFeatures.tsx +++ b/datahub-web-react/src/app/entity/mlFeatureTable/profile/features/TableOfMlFeatures.tsx @@ -40,6 +40,7 @@ export default function TableOfMlFeatures({ features }: Props) { const entityRegistry = useEntityRegistry(); const [tagHoveredIndex, setTagHoveredIndex] = useState(undefined); + const [expandedRows, setExpandedRows] = useState({}); const onTagTermCell = (record: any, rowIndex: number | undefined) => ({ onMouseEnter: () => { @@ -66,8 +67,12 @@ export default function TableOfMlFeatures({ features }: Props) { title: 'Description', dataIndex: 'description', key: 'description', - render: (_, feature: MlFeature | MlPrimaryKey) => ( + render: (_, feature: MlFeature | MlPrimaryKey, index: number) => ( { + setExpandedRows((prev) => ({ ...prev, [index]: expanded })); + }} + expanded={!!expandedRows[index]} description={feature?.editableProperties?.description || feature?.properties?.description || ''} original={feature?.properties?.description} isEdited={!!feature?.editableProperties?.description} diff --git a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/utils/useDescriptionRenderer.tsx b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/utils/useDescriptionRenderer.tsx index 75d5d1e7ef..d80143f4bb 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/utils/useDescriptionRenderer.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/utils/useDescriptionRenderer.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import DOMPurify from 'dompurify'; import { EditableSchemaMetadata, SchemaField, SubResourceType } from '../../../../../../../types.generated'; import DescriptionField from '../../../../../dataset/profile/schema/components/SchemaDescriptionField'; @@ -12,13 +12,14 @@ export default function useDescriptionRenderer(editableSchemaMetadata: EditableS const refetch = useRefetch(); const schemaRefetch = useSchemaRefetch(); const [updateDescription] = useUpdateDescriptionMutation(); + const [expandedRows, setExpandedRows] = useState({}); const refresh: any = () => { refetch?.(); schemaRefetch?.(); }; - return (description: string, record: SchemaField): JSX.Element => { + return (description: string, record: SchemaField, index: number): JSX.Element => { const relevantEditableFieldInfo = editableSchemaMetadata?.editableSchemaFieldInfo.find( (candidateEditableFieldInfo) => pathMatchesNewPath(candidateEditableFieldInfo.fieldPath, record.fieldPath), ); @@ -26,8 +27,12 @@ export default function useDescriptionRenderer(editableSchemaMetadata: EditableS const sanitizedDescription = DOMPurify.sanitize(displayedDescription); const original = record.description ? DOMPurify.sanitize(record.description) : undefined; + const handleExpandedRows = (expanded) => setExpandedRows((prev) => ({ ...prev, [index]: expanded })); + return (