chore(ui): add layoutType in tags container (#13230)

* chore(ui): add layoutType in tags container

* chore: address comment

---------

Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
Sachin Chaurasiya 2023-09-19 19:33:12 +05:30 committed by GitHub
parent a424c37a34
commit af6cd905e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 25 deletions

View File

@ -15,7 +15,7 @@ import { ThreadType } from 'generated/api/feed/createThread';
import { TagSource } from 'generated/type/tagLabel'; import { TagSource } from 'generated/type/tagLabel';
import { EntityTags } from 'Models'; import { EntityTags } from 'Models';
import { ReactElement } from 'react'; import { ReactElement } from 'react';
import { DisplayType } from '../TagsViewer/TagsViewer.interface'; import { DisplayType, LayoutType } from '../TagsViewer/TagsViewer.interface';
export type TagsContainerV2Props = { export type TagsContainerV2Props = {
permission: boolean; permission: boolean;
@ -29,6 +29,7 @@ export type TagsContainerV2Props = {
showInlineEditButton?: boolean; showInlineEditButton?: boolean;
children?: ReactElement; children?: ReactElement;
displayType?: DisplayType; displayType?: DisplayType;
layoutType?: LayoutType;
onSelectionChange?: (selectedTags: EntityTags[]) => Promise<void>; onSelectionChange?: (selectedTags: EntityTags[]) => Promise<void>;
onThreadLinkSelect?: (value: string, threadType?: ThreadType) => void; onThreadLinkSelect?: (value: string, threadType?: ThreadType) => void;
}; };

View File

@ -35,6 +35,7 @@ import { ReactComponent as IconRequest } from '../../../assets/svg/request-icon.
import TagSelectForm from '../TagsSelectForm/TagsSelectForm.component'; import TagSelectForm from '../TagsSelectForm/TagsSelectForm.component';
import TagsV1 from '../TagsV1/TagsV1.component'; import TagsV1 from '../TagsV1/TagsV1.component';
import TagsViewer from '../TagsViewer/TagsViewer'; import TagsViewer from '../TagsViewer/TagsViewer';
import { LayoutType } from '../TagsViewer/TagsViewer.interface';
import { TagsContainerV2Props } from './TagsContainerV2.interface'; import { TagsContainerV2Props } from './TagsContainerV2.interface';
const TagsContainerV2 = ({ const TagsContainerV2 = ({
@ -45,6 +46,7 @@ const TagsContainerV2 = ({
entityFqn, entityFqn,
tagType, tagType,
displayType, displayType,
layoutType,
showHeader = true, showHeader = true,
showBottomEditButton, showBottomEditButton,
showInlineEditButton, showInlineEditButton,
@ -59,19 +61,19 @@ const TagsContainerV2 = ({
const [isEditTags, setIsEditTags] = useState(false); const [isEditTags, setIsEditTags] = useState(false);
const [tags, setTags] = useState<TableTagsProps>(); const [tags, setTags] = useState<TableTagsProps>();
const isGlossaryType = useMemo( const {
() => tagType === TagSource.Glossary, isGlossaryType,
[tagType] showAddTagButton,
); selectedTagsInternal,
isHoriZontalLayout,
const showAddTagButton = useMemo( } = useMemo(
() => permission && isEmpty(tags?.[tagType]), () => ({
[permission, tags?.[tagType]] isGlossaryType: tagType === TagSource.Glossary,
); showAddTagButton: permission && isEmpty(tags?.[tagType]),
selectedTagsInternal: tags?.[tagType].map(({ tagFQN }) => tagFQN),
const selectedTagsInternal = useMemo( isHoriZontalLayout: layoutType === LayoutType.HORIZONTAL,
() => tags?.[tagType].map(({ tagFQN }) => tagFQN), }),
[tags, tagType] [tagType, permission, tags?.[tagType], tags, layoutType]
); );
const fetchGlossaryList = useCallback( const fetchGlossaryList = useCallback(
@ -167,12 +169,13 @@ const TagsContainerV2 = ({
<Col span={24}> <Col span={24}>
<TagsViewer <TagsViewer
displayType={displayType} displayType={displayType}
layoutType={layoutType}
showNoDataPlaceholder={showNoDataPlaceholder} showNoDataPlaceholder={showNoDataPlaceholder}
tags={tags?.[tagType] ?? []} tags={tags?.[tagType] ?? []}
/> />
</Col> </Col>
), ),
[displayType, showNoDataPlaceholder, tags?.[tagType]] [displayType, showNoDataPlaceholder, tags?.[tagType], layoutType]
); );
const tagsSelectContainer = useMemo(() => { const tagsSelectContainer = useMemo(() => {
@ -313,6 +316,33 @@ const TagsContainerV2 = ({
[permission, tags, tagType, handleAddClick] [permission, tags, tagType, handleAddClick]
); );
const horizontalLayout = useMemo(() => {
return (
<Space>
{showAddTagButton ? (
<div onClick={handleAddClick}>
<TagsV1 startWith={TAG_START_WITH.PLUS} tag={TAG_CONSTANT} />
</div>
) : null}
<TagsViewer
displayType={displayType}
layoutType={layoutType}
showNoDataPlaceholder={showNoDataPlaceholder}
tags={tags?.[tagType] ?? []}
/>
{showInlineEditButton ? editTagButton : null}
</Space>
);
}, [
showAddTagButton,
displayType,
layoutType,
showNoDataPlaceholder,
tags?.[tagType],
showInlineEditButton,
handleAddClick,
]);
useEffect(() => { useEffect(() => {
setTags(getFilterTags(selectedTags)); setTags(getFilterTags(selectedTags));
}, [selectedTags]); }, [selectedTags]);
@ -323,13 +353,16 @@ const TagsContainerV2 = ({
data-testid={isGlossaryType ? 'glossary-container' : 'tags-container'}> data-testid={isGlossaryType ? 'glossary-container' : 'tags-container'}>
{header} {header}
{!isEditTags && ( {!isEditTags &&
<Row data-testid="entity-tags"> (isHoriZontalLayout ? (
{addTagButton} horizontalLayout
{renderTags} ) : (
{showInlineEditButton && <Col>{editTagButton}</Col>} <Row data-testid="entity-tags">
</Row> {addTagButton}
)} {renderTags}
{showInlineEditButton && <Col>{editTagButton}</Col>}
</Row>
))}
{isEditTags && tagsSelectContainer} {isEditTags && tagsSelectContainer}
<Space align="baseline" className="m-t-xs w-full" size="middle"> <Space align="baseline" className="m-t-xs w-full" size="middle">

View File

@ -17,6 +17,7 @@ export interface TagsViewerProps {
tags: EntityTags[]; tags: EntityTags[];
sizeCap?: number; sizeCap?: number;
displayType?: DisplayType; displayType?: DisplayType;
layoutType?: LayoutType;
showNoDataPlaceholder?: boolean; showNoDataPlaceholder?: boolean;
} }
@ -24,3 +25,8 @@ export enum DisplayType {
READ_MORE = 'read-more', READ_MORE = 'read-more',
POPOVER = 'popover', POPOVER = 'popover',
} }
export enum LayoutType {
HORIZONTAL = 'horizontal',
VERTICAL = 'vertical',
}

View File

@ -11,7 +11,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Button, Popover, Tag, Typography } from 'antd'; import { Button, Popover, Space, Tag, Typography } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import { TAG_START_WITH } from 'constants/Tag.constants'; import { TAG_START_WITH } from 'constants/Tag.constants';
import { isEmpty, sortBy, uniqBy } from 'lodash'; import { isEmpty, sortBy, uniqBy } from 'lodash';
@ -27,12 +27,17 @@ import { LIST_SIZE, NO_DATA_PLACEHOLDER } from '../../../constants/constants';
import { TagSource } from '../../../generated/type/tagLabel'; import { TagSource } from '../../../generated/type/tagLabel';
import TagsV1 from '../TagsV1/TagsV1.component'; import TagsV1 from '../TagsV1/TagsV1.component';
import './tags-viewer.less'; import './tags-viewer.less';
import { DisplayType, TagsViewerProps } from './TagsViewer.interface'; import {
DisplayType,
LayoutType,
TagsViewerProps,
} from './TagsViewer.interface';
const TagsViewer: FunctionComponent<TagsViewerProps> = ({ const TagsViewer: FunctionComponent<TagsViewerProps> = ({
tags, tags,
sizeCap = LIST_SIZE, sizeCap = LIST_SIZE,
displayType = DisplayType.POPOVER, displayType = DisplayType.POPOVER,
layoutType = LayoutType.VERTICAL,
showNoDataPlaceholder = true, showNoDataPlaceholder = true,
}: TagsViewerProps) => { }: TagsViewerProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -135,7 +140,9 @@ const TagsViewer: FunctionComponent<TagsViewerProps> = ({
return ( return (
<> <>
{sortedTagsBySource.slice(0, sizeCap).map(getTagsElement)} <Space direction={layoutType} size={0}>
{sortedTagsBySource.slice(0, sizeCap).map(getTagsElement)}
</Space>
{displayType === DisplayType.POPOVER {displayType === DisplayType.POPOVER
? popoverRenderElement ? popoverRenderElement
: readMoreRenderElement} : readMoreRenderElement}