mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-14 10:18:23 +00:00
fix(ui): show system badge for system tags (#10654)
* fix(ui): show system badge for system tags * rename file to coding standards * fix cypress failure * update badge styling to details * update badge styling added unit tests
This commit is contained in:
parent
5a9173df0f
commit
774a3346c0
@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path fill="#37352F" d="M18.071 8.571v-2.82A5.76 5.76 0 0 0 12.32 0h-.497A5.76 5.76 0 0 0 6.07 5.751v2.82A2.571 2.571 0 0 0 3.5 11.143v7.971A4.894 4.894 0 0 0 8.386 24h7.371a4.894 4.894 0 0 0 4.886-4.886v-7.971A2.572 2.572 0 0 0 18.07 8.57ZM7.786 5.751a4.037 4.037 0 0 1 4.037-4.037h.497a4.037 4.037 0 0 1 4.037 4.037v2.82H7.786v-2.82Zm11.143 13.363a3.172 3.172 0 0 1-3.172 3.172H8.386a3.171 3.171 0 0 1-3.172-3.172v-7.971a.857.857 0 0 1 .857-.857h12a.857.857 0 0 1 .858.857v7.971Z"/><path fill="#37352F" d="M12.929 16.045v2.811a.857.857 0 0 1-1.714 0v-2.811a1.714 1.714 0 1 1 1.714 0Z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill="currentColor" d="M18.071 8.571v-2.82A5.76 5.76 0 0 0 12.32 0h-.497A5.76 5.76 0 0 0 6.07 5.751v2.82A2.571 2.571 0 0 0 3.5 11.143v7.971A4.894 4.894 0 0 0 8.386 24h7.371a4.894 4.894 0 0 0 4.886-4.886v-7.971A2.572 2.572 0 0 0 18.07 8.57ZM7.786 5.751a4.037 4.037 0 0 1 4.037-4.037h.497a4.037 4.037 0 0 1 4.037 4.037v2.82H7.786v-2.82Zm11.143 13.363a3.172 3.172 0 0 1-3.172 3.172H8.386a3.171 3.171 0 0 1-3.172-3.172v-7.971a.857.857 0 0 1 .857-.857h12a.857.857 0 0 1 .858.857v7.971Z"/><path fill="currentColor" d="M12.929 16.045v2.811a.857.857 0 0 1-1.714 0v-2.811a1.714 1.714 0 1 1 1.714 0Z"/></svg>
|
Before Width: | Height: | Size: 666 B After Width: | Height: | Size: 684 B |
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2023 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Typography } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import React, { ReactNode } from 'react';
|
||||
import './badge.style.less';
|
||||
|
||||
interface AppBadgeProps {
|
||||
label: string;
|
||||
icon?: ReactNode;
|
||||
color?: string;
|
||||
className?: string;
|
||||
bgColor?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Badge like component.
|
||||
* Accepts `label` as required prop
|
||||
* @param props
|
||||
* {
|
||||
* label - Render text between Badge
|
||||
* className - To customize look & feel of the badge
|
||||
* icon - Renders icon before label
|
||||
* color - Controls color of font or Icon
|
||||
* bgColor - Controls color of badge itself
|
||||
* }
|
||||
* @returns Badge component
|
||||
*/
|
||||
const AppBadge = ({
|
||||
label,
|
||||
className,
|
||||
icon,
|
||||
color,
|
||||
bgColor,
|
||||
}: AppBadgeProps) => {
|
||||
return (
|
||||
<span
|
||||
className={classNames('app-badge d-flex', className)}
|
||||
data-testid="badge-container"
|
||||
style={{ color, backgroundColor: bgColor }}>
|
||||
{icon && (
|
||||
<span className="m-r-xss" data-testid="badge-icon">
|
||||
{icon}
|
||||
</span>
|
||||
)}
|
||||
<Typography.Text>{label}</Typography.Text>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default AppBadge;
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2023 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import AppBadge from './Badge.component';
|
||||
|
||||
describe('<Badge /> component', () => {
|
||||
it('should render badge with label is label is passed', () => {
|
||||
const { getByText } = render(<AppBadge label="test" />);
|
||||
|
||||
expect(getByText('test')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render badge without icon if icon is not passed', () => {
|
||||
const { queryByTestId } = render(<AppBadge label="test" />);
|
||||
|
||||
expect(queryByTestId('badge-icon')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render badge with icon if icon is passed', () => {
|
||||
const { queryByTestId, getByText } = render(
|
||||
<AppBadge icon="test-icon" label="test" />
|
||||
);
|
||||
|
||||
expect(queryByTestId('badge-icon')).toBeInTheDocument();
|
||||
expect(getByText('test-icon')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should apply className to container if provided', () => {
|
||||
const { queryByTestId } = render(
|
||||
<AppBadge className="test-className" icon="test-icon" label="test" />
|
||||
);
|
||||
|
||||
expect(queryByTestId('badge-container')).toHaveClass('test-className');
|
||||
});
|
||||
|
||||
it('should apply color property to container element if provided', () => {
|
||||
const { queryByTestId } = render(<AppBadge color="#000" label="test" />);
|
||||
|
||||
expect(queryByTestId('badge-container')).toHaveStyle({ color: '#000' });
|
||||
});
|
||||
|
||||
it('should apply bgColor property to container element if provided', () => {
|
||||
const { queryByTestId } = render(<AppBadge bgColor="#000" label="test" />);
|
||||
|
||||
expect(queryByTestId('badge-container')).toHaveStyle({
|
||||
'background-color': '#000',
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2023 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@import url('../../../styles/variables.less');
|
||||
|
||||
.app-badge {
|
||||
background-color: #06a4a4;
|
||||
border-radius: 13px;
|
||||
padding: 4px 8px;
|
||||
color: #fff;
|
||||
|
||||
.ant-typography {
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 10px;
|
||||
line-height: 12px;
|
||||
}
|
||||
}
|
@ -544,6 +544,30 @@ describe('Test TagsPage page', () => {
|
||||
expect(tagCategoryHeading).toHaveValue('newPII');
|
||||
});
|
||||
|
||||
it('User tag should be load', async () => {
|
||||
const { container } = render(<TagsPage />);
|
||||
|
||||
const tagsComponent = await screen.findByTestId('tags-container');
|
||||
const classification = await screen.findAllByText('PersonalData');
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(classification[0]);
|
||||
});
|
||||
|
||||
act(async () => {
|
||||
const tagEditIcon = await findAllByTestId(container, 'tag-edit-icon');
|
||||
|
||||
expect(tagEditIcon[0]).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(tagEditIcon[0]);
|
||||
});
|
||||
|
||||
const tagName = await screen.findByText('test_tag');
|
||||
|
||||
expect(tagName).toBeInTheDocument();
|
||||
expect(tagsComponent).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('Render Sad Paths', () => {
|
||||
it('Show error message on failing of deleteClassification API', async () => {
|
||||
(deleteClassification as jest.Mock).mockImplementation(() =>
|
||||
|
@ -24,7 +24,9 @@ import {
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { ColumnsType } from 'antd/lib/table';
|
||||
import { ReactComponent as LockIcon } from 'assets/svg/closed-lock.svg';
|
||||
import { AxiosError } from 'axios';
|
||||
import AppBadge from 'components/common/Badge/Badge.component';
|
||||
import Description from 'components/common/description/Description';
|
||||
import ErrorPlaceHolder from 'components/common/error-with-placeholder/ErrorPlaceHolder';
|
||||
import LeftPanelCard from 'components/common/LeftPanelCard/LeftPanelCard';
|
||||
@ -44,7 +46,7 @@ import {
|
||||
import TagsLeftPanelSkeleton from 'components/Skeleton/Tags/TagsLeftPanelSkeleton.component';
|
||||
import { LOADING_STATE } from 'enums/common.enum';
|
||||
import { compare } from 'fast-json-patch';
|
||||
import { isEmpty, isUndefined, toLower, trim } from 'lodash';
|
||||
import { capitalize, isEmpty, isUndefined, toLower, trim } from 'lodash';
|
||||
import { FormErrorData } from 'Models';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -692,7 +694,7 @@ const TagsPage = () => {
|
||||
{classifications &&
|
||||
classifications.map((category: Classification) => (
|
||||
<div
|
||||
className={`tw-group tw-text-grey-body tw-cursor-pointer tw-my-1 tw-text-body tw-py-1 tw-px-3 tw-flex tw-justify-between ${getActiveCatClass(
|
||||
className={`tw-group align-center content-box cursor-pointer tw-text-grey-body tw-text-body tw-flex p-y-xss p-x-sm m-y-xss ${getActiveCatClass(
|
||||
category.name,
|
||||
currentClassification?.name
|
||||
)}`}
|
||||
@ -705,9 +707,10 @@ const TagsPage = () => {
|
||||
ellipsis={{ rows: 1, tooltip: true }}>
|
||||
{getEntityName(category as unknown as EntityReference)}
|
||||
</Typography.Paragraph>
|
||||
|
||||
{getCountBadge(
|
||||
category.termCount,
|
||||
'tw-self-center',
|
||||
'self-center m-l-auto',
|
||||
currentClassification?.name === category.name
|
||||
)}
|
||||
</div>
|
||||
@ -866,7 +869,7 @@ const TagsPage = () => {
|
||||
data-testid="classification-name">
|
||||
{getEntityName(currentClassification)}
|
||||
</Typography.Text>
|
||||
{currentClassification.provider === ProviderType.User && (
|
||||
{currentClassification.provider === ProviderType.User ? (
|
||||
<Tooltip
|
||||
title={
|
||||
classificationPermissions.EditAll
|
||||
@ -890,6 +893,12 @@ const TagsPage = () => {
|
||||
/>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<AppBadge
|
||||
className="m--t-xss"
|
||||
icon={<LockIcon height={12} />}
|
||||
label={capitalize(currentClassification.provider)}
|
||||
/>
|
||||
)}
|
||||
</Space>
|
||||
)}
|
||||
|
@ -134,6 +134,30 @@ export const MOCK_TAGS = {
|
||||
provider: 'system',
|
||||
mutuallyExclusive: false,
|
||||
},
|
||||
{
|
||||
id: '43f1e354-eefa-4c63-94bc-c618badaf6ee',
|
||||
name: 'test_tag',
|
||||
fullyQualifiedName: 'PersonalData.test_tag',
|
||||
description: 'test_tag',
|
||||
classification: {
|
||||
id: '7968b3a3-ee7c-4bf9-9bf1-ff8322c6b53f',
|
||||
type: 'classification',
|
||||
name: 'PersonalData',
|
||||
fullyQualifiedName: 'PersonalData',
|
||||
description: 'Hello testing',
|
||||
deleted: false,
|
||||
href: 'http://localhost:8585/api/v1/classifications/7968b3a3-ee7c-4bf9-9bf1-ff8322c6b53f',
|
||||
},
|
||||
version: 0.1,
|
||||
updatedAt: 1678959133696,
|
||||
updatedBy: 'admin',
|
||||
href: 'http://localhost:8585/api/v1/tags/43f1e354-eefa-4c63-94bc-c618badaf6ee',
|
||||
usageCount: 0,
|
||||
deprecated: false,
|
||||
deleted: false,
|
||||
provider: 'user',
|
||||
mutuallyExclusive: false,
|
||||
},
|
||||
],
|
||||
paging: {
|
||||
after: 'UGVyc29uYWxEYXRhLnRlc3R0YWc4OQ==',
|
||||
|
@ -186,6 +186,7 @@
|
||||
.activeCategory {
|
||||
border-left: 2px solid @primary;
|
||||
background: @primary-light;
|
||||
padding-left: 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
|
@ -129,6 +129,9 @@
|
||||
.m-l-lg {
|
||||
margin-left: @margin-lg;
|
||||
}
|
||||
.m-l-auto {
|
||||
margin-left: auto;
|
||||
}
|
||||
.m-t-0 {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
@ -524,3 +527,11 @@
|
||||
.col-gap-md {
|
||||
column-gap: 1rem;
|
||||
}
|
||||
// Box sizing
|
||||
|
||||
.border-box {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.content-box {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ export const getCountBadge = (
|
||||
return (
|
||||
<span
|
||||
className={classNames(
|
||||
'tw-py-px tw-px-1 tw-mx-1 tw-border tw-rounded tw-text-xs tw-min-w-badgeCount tw-text-center',
|
||||
'tw-py-px p-x-xss m-x-xss tw-border tw-rounded tw-text-xs tw-min-w-badgeCount text-center',
|
||||
clsBG,
|
||||
className
|
||||
)}>
|
||||
|
Loading…
x
Reference in New Issue
Block a user