mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-11 18:11:59 +00:00
ui(fix): supported ellipses in tags and remove old componet (#12525)
* supported ellipses in tags and remove old componnet * fix unit test * support tags to take entire width as per content * chanegs as per comments * fix cypress issue * fix cypress issue
This commit is contained in:
parent
19e70d4ca6
commit
4a8f19a275
@ -541,7 +541,7 @@ export const addNewTagToEntity = (entityObj, term) => {
|
|||||||
);
|
);
|
||||||
cy.wait(500);
|
cy.wait(500);
|
||||||
cy.get(
|
cy.get(
|
||||||
'[data-testid="Classification-tags-0"] [data-testid="entity-tags"] [data-testid="add-tag"]'
|
'[data-testid="classification-tags-0"] [data-testid="entity-tags"] [data-testid="add-tag"]'
|
||||||
)
|
)
|
||||||
.eq(0)
|
.eq(0)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
@ -559,7 +559,7 @@ export const addNewTagToEntity = (entityObj, term) => {
|
|||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
cy.get('[data-testid="Classification-tags-0"] [data-testid="tags-container"]')
|
cy.get('[data-testid="classification-tags-0"] [data-testid="tags-container"]')
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.contains(name)
|
.contains(name)
|
||||||
.should('exist');
|
.should('exist');
|
||||||
|
@ -40,7 +40,7 @@ const checkTags = (tag, checkForParentEntity) => {
|
|||||||
.contains(tag);
|
.contains(tag);
|
||||||
} else {
|
} else {
|
||||||
cy.get(
|
cy.get(
|
||||||
'[data-testid="Classification-tags-0"] [data-testid="tags-container"] [data-testid="entity-tags"] '
|
'[data-testid="classification-tags-0"] [data-testid="tags-container"] [data-testid="entity-tags"] '
|
||||||
)
|
)
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.contains(tag);
|
.contains(tag);
|
||||||
@ -65,7 +65,7 @@ const removeTags = (checkForParentEntity) => {
|
|||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
} else {
|
} else {
|
||||||
cy.get('[data-testid="Classification-tags-0"] [data-testid="edit-button"]')
|
cy.get('[data-testid="classification-tags-0"] [data-testid="edit-button"]')
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.trigger('mouseover')
|
.trigger('mouseover')
|
||||||
.click();
|
.click();
|
||||||
@ -130,24 +130,24 @@ describe('Check if tags addition and removal flow working properly from tables',
|
|||||||
|
|
||||||
if (entityDetails.entity === 'mlmodels') {
|
if (entityDetails.entity === 'mlmodels') {
|
||||||
cy.get(
|
cy.get(
|
||||||
`[data-testid="feature-card-${entityDetails.fieldName}"] [data-testid="Classification-tags-0"]`
|
`[data-testid="feature-card-${entityDetails.fieldName}"] [data-testid="classification-tags-0"]`
|
||||||
).then(($container) => {
|
).then(($container) => {
|
||||||
if ($container.find('[data-testid="add-tag"]').length === 0) {
|
if ($container.find('[data-testid="add-tag"]').length === 0) {
|
||||||
removeTags(false);
|
removeTags(false);
|
||||||
}
|
}
|
||||||
cy.get(
|
cy.get(
|
||||||
`[data-testid="feature-card-${entityDetails.fieldName}"] [data-testid="Classification-tags-0"] [data-testid="add-tag"]`
|
`[data-testid="feature-card-${entityDetails.fieldName}"] [data-testid="classification-tags-0"] [data-testid="add-tag"]`
|
||||||
).click();
|
).click();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
cy.get(
|
cy.get(
|
||||||
'.ant-table-tbody [data-testid="Classification-tags-0"] [data-testid="tags-container"]'
|
'.ant-table-tbody [data-testid="classification-tags-0"] [data-testid="tags-container"]'
|
||||||
).then(($container) => {
|
).then(($container) => {
|
||||||
if ($container.find('[data-testid="add-tag"]').length === 0) {
|
if ($container.find('[data-testid="add-tag"]').length === 0) {
|
||||||
removeTags(false);
|
removeTags(false);
|
||||||
}
|
}
|
||||||
cy.get(
|
cy.get(
|
||||||
'.ant-table-tbody [data-testid="Classification-tags-0"] [data-testid="tags-container"] [data-testid="add-tag"]'
|
'.ant-table-tbody [data-testid="classification-tags-0"] [data-testid="tags-container"] [data-testid="add-tag"]'
|
||||||
).click();
|
).click();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -667,7 +667,7 @@ describe('Glossary page should work properly', () => {
|
|||||||
|
|
||||||
// Add glossary tag to entity for mutually exclusive
|
// Add glossary tag to entity for mutually exclusive
|
||||||
cy.get(
|
cy.get(
|
||||||
'[data-testid="entity-right-panel"] [data-testid="glossary-container"] > [data-testid="entity-tags"]'
|
'[data-testid="entity-right-panel"] [data-testid="glossary-container"] > [data-testid="entity-tags"] [data-testid="add-tag"]'
|
||||||
).click();
|
).click();
|
||||||
// Select 1st term
|
// Select 1st term
|
||||||
cy.get('[data-testid="tag-selector"]').click().type(term1);
|
cy.get('[data-testid="tag-selector"]').click().type(term1);
|
||||||
@ -691,7 +691,7 @@ describe('Glossary page should work properly', () => {
|
|||||||
|
|
||||||
// Add non mutually exclusive tags
|
// Add non mutually exclusive tags
|
||||||
cy.get(
|
cy.get(
|
||||||
'[data-testid="entity-right-panel"] [data-testid="glossary-container"] > [data-testid="entity-tags"]'
|
'[data-testid="entity-right-panel"] [data-testid="glossary-container"] > [data-testid="entity-tags"] [data-testid="add-tag"]'
|
||||||
).click();
|
).click();
|
||||||
|
|
||||||
// Select 1st term
|
// Select 1st term
|
||||||
@ -714,7 +714,7 @@ describe('Glossary page should work properly', () => {
|
|||||||
|
|
||||||
// Add tag to schema table
|
// Add tag to schema table
|
||||||
const firstColumn =
|
const firstColumn =
|
||||||
'[data-testid="Glossary-tags-0"] > [data-testid="tags-wrapper"] > [data-testid="glossary-container"] > [data-testid="entity-tags"]';
|
'[data-testid="glossary-tags-0"] > [data-testid="tags-wrapper"] > [data-testid="glossary-container"] > [data-testid="entity-tags"] [data-testid="add-tag"]';
|
||||||
cy.get(firstColumn).scrollIntoView();
|
cy.get(firstColumn).scrollIntoView();
|
||||||
cy.get(firstColumn).click();
|
cy.get(firstColumn).click();
|
||||||
|
|
||||||
@ -729,7 +729,7 @@ describe('Glossary page should work properly', () => {
|
|||||||
cy.get('[data-testid="saveAssociatedTag"]').scrollIntoView().click();
|
cy.get('[data-testid="saveAssociatedTag"]').scrollIntoView().click();
|
||||||
verifyResponseStatusCode('@countTag', 200);
|
verifyResponseStatusCode('@countTag', 200);
|
||||||
cy.get(
|
cy.get(
|
||||||
'[data-testid="Glossary-tags-0"] > [data-testid="tags-wrapper"] > [data-testid="glossary-container"]'
|
'[data-testid="glossary-tags-0"] > [data-testid="tags-wrapper"] > [data-testid="glossary-container"]'
|
||||||
)
|
)
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.should('contain', term3);
|
.should('contain', term3);
|
||||||
@ -785,7 +785,7 @@ describe('Glossary page should work properly', () => {
|
|||||||
interceptURL('PATCH', '/api/v1/tables/*', 'removeSchemaTags');
|
interceptURL('PATCH', '/api/v1/tables/*', 'removeSchemaTags');
|
||||||
|
|
||||||
cy.get(
|
cy.get(
|
||||||
'[data-testid="Glossary-tags-0"] > [data-testid="tags-wrapper"] > [data-testid="glossary-container"]'
|
'[data-testid="glossary-tags-0"] > [data-testid="tags-wrapper"] > [data-testid="glossary-container"]'
|
||||||
)
|
)
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.trigger('mouseover')
|
.trigger('mouseover')
|
||||||
@ -800,7 +800,7 @@ describe('Glossary page should work properly', () => {
|
|||||||
verifyResponseStatusCode('@removeSchemaTags', 200);
|
verifyResponseStatusCode('@removeSchemaTags', 200);
|
||||||
|
|
||||||
cy.get(
|
cy.get(
|
||||||
'[data-testid="Glossary-tags-0"] > [data-testid="tags-wrapper"] > [data-testid="glossary-container"]'
|
'[data-testid="glossary-tags-0"] > [data-testid="tags-wrapper"] > [data-testid="glossary-container"]'
|
||||||
)
|
)
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.should('not.contain', name)
|
.should('not.contain', name)
|
||||||
|
@ -71,7 +71,9 @@ export const ExtraInfoLabel = ({
|
|||||||
<>
|
<>
|
||||||
<Divider className="self-center m-x-sm" type="vertical" />
|
<Divider className="self-center m-x-sm" type="vertical" />
|
||||||
<Typography.Text className="self-center text-xs whitespace-nowrap">
|
<Typography.Text className="self-center text-xs whitespace-nowrap">
|
||||||
|
{!isEmpty(label) && (
|
||||||
<span className="text-grey-muted">{`${label}: `}</span>
|
<span className="text-grey-muted">{`${label}: `}</span>
|
||||||
|
)}
|
||||||
<span className="font-medium">{value}</span>
|
<span className="font-medium">{value}</span>
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
</>
|
</>
|
||||||
|
@ -140,10 +140,6 @@ jest.mock('../Modals/ModalWithMarkdownEditor/ModalWithMarkdownEditor', () => ({
|
|||||||
.mockReturnValue(<p> ModalWithMarkdownEditor</p>),
|
.mockReturnValue(<p> ModalWithMarkdownEditor</p>),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('components/Tag/Tags/tags', () => {
|
|
||||||
return jest.fn().mockImplementation(({ tag }) => <span>{tag.tagFQN}</span>);
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.mock('utils/TableUtils', () => ({
|
jest.mock('utils/TableUtils', () => ({
|
||||||
getAllTagsList: jest.fn().mockImplementation(() => Promise.resolve([])),
|
getAllTagsList: jest.fn().mockImplementation(() => Promise.resolve([])),
|
||||||
getTagsHierarchy: jest.fn().mockReturnValue([]),
|
getTagsHierarchy: jest.fn().mockReturnValue([]),
|
||||||
|
@ -107,14 +107,6 @@ jest.mock(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
jest.mock('components/Tag/TagsViewer/tags-viewer', () => {
|
|
||||||
return jest.fn().mockReturnValue(<p>TagViewer</p>);
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.mock('components/Tag/Tags/tags', () => {
|
|
||||||
return jest.fn().mockReturnValue(<p>Tag</p>);
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.mock('../../utils/TagsUtils', () => ({
|
jest.mock('../../utils/TagsUtils', () => ({
|
||||||
getAllTagsList: jest.fn(() => Promise.resolve([])),
|
getAllTagsList: jest.fn(() => Promise.resolve([])),
|
||||||
getTagsHierarchy: jest.fn().mockReturnValue([]),
|
getTagsHierarchy: jest.fn().mockReturnValue([]),
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import TagsContainerV2 from 'components/Tag/TagsContainerV2/TagsContainerV2';
|
import TagsContainerV2 from 'components/Tag/TagsContainerV2/TagsContainerV2';
|
||||||
import { EntityField } from 'constants/Feeds.constants';
|
import { EntityField } from 'constants/Feeds.constants';
|
||||||
|
import { lowerCase } from 'lodash';
|
||||||
import EntityTasks from 'pages/TasksPage/EntityTasks/EntityTasks.component';
|
import EntityTasks from 'pages/TasksPage/EntityTasks/EntityTasks.component';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { TableTagsComponentProps, TableUnion } from './TableTags.interface';
|
import { TableTagsComponentProps, TableUnion } from './TableTags.interface';
|
||||||
@ -33,7 +34,9 @@ const TableTags = <T extends TableUnion>({
|
|||||||
entityType,
|
entityType,
|
||||||
}: TableTagsComponentProps<T>) => {
|
}: TableTagsComponentProps<T>) => {
|
||||||
return (
|
return (
|
||||||
<div className="hover-icon-group" data-testid={`${type}-tags-${index}`}>
|
<div
|
||||||
|
className="hover-icon-group"
|
||||||
|
data-testid={`${lowerCase(type)}-tags-${index}`}>
|
||||||
<div
|
<div
|
||||||
className={classNames('d-flex justify-content flex-col items-start')}
|
className={classNames('d-flex justify-content flex-col items-start')}
|
||||||
data-testid="tags-wrapper">
|
data-testid="tags-wrapper">
|
||||||
|
@ -106,7 +106,7 @@ describe('Test EntityTableTags Component', () => {
|
|||||||
wrapper: MemoryRouter,
|
wrapper: MemoryRouter,
|
||||||
});
|
});
|
||||||
|
|
||||||
const tagContainer = await screen.findByTestId('Classification-tags-0');
|
const tagContainer = await screen.findByTestId('classification-tags-0');
|
||||||
|
|
||||||
expect(tagContainer).toBeInTheDocument();
|
expect(tagContainer).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
@ -127,7 +127,7 @@ describe('Test EntityTableTags Component', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const tagContainer = await screen.findByTestId('Classification-tags-0');
|
const tagContainer = await screen.findByTestId('classification-tags-0');
|
||||||
|
|
||||||
expect(tagContainer).toBeInTheDocument();
|
expect(tagContainer).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
@ -147,7 +147,7 @@ describe('Test EntityTableTags Component', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const tagContainer = await screen.findByTestId('Classification-tags-0');
|
const tagContainer = await screen.findByTestId('classification-tags-0');
|
||||||
const tagPersonal = await screen.findByTestId('tag-PersonalData.Personal');
|
const tagPersonal = await screen.findByTestId('tag-PersonalData.Personal');
|
||||||
|
|
||||||
expect(tagContainer).toBeInTheDocument();
|
expect(tagContainer).toBeInTheDocument();
|
||||||
@ -170,7 +170,7 @@ describe('Test EntityTableTags Component', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const tagContainer = await screen.findByTestId('Classification-tags-0');
|
const tagContainer = await screen.findByTestId('classification-tags-0');
|
||||||
const entityTasks = screen.queryByText('EntityTasks');
|
const entityTasks = screen.queryByText('EntityTasks');
|
||||||
|
|
||||||
expect(tagContainer).toBeInTheDocument();
|
expect(tagContainer).toBeInTheDocument();
|
||||||
@ -193,7 +193,7 @@ describe('Test EntityTableTags Component', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const tagContainer = await screen.findByTestId('Classification-tags-0');
|
const tagContainer = await screen.findByTestId('classification-tags-0');
|
||||||
const entityTasks = screen.queryByText('EntityTasks');
|
const entityTasks = screen.queryByText('EntityTasks');
|
||||||
|
|
||||||
expect(tagContainer).toBeInTheDocument();
|
expect(tagContainer).toBeInTheDocument();
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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');
|
|
||||||
|
|
||||||
.tags-component-container {
|
|
||||||
.tag-container-style {
|
|
||||||
display: flex;
|
|
||||||
gap: 4px;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 500;
|
|
||||||
cursor: pointer;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 1px 8px;
|
|
||||||
margin: 0 4px 1px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
border: none;
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.outlined {
|
|
||||||
border: none;
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.plus-more-tag.ant-tag {
|
|
||||||
color: @link-color;
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2022 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 { TAG_START_WITH } from 'constants/Tag.constants';
|
|
||||||
import { TagLabel } from '../../../generated/type/tagLabel';
|
|
||||||
|
|
||||||
export type TagProps = {
|
|
||||||
className?: string;
|
|
||||||
editable?: boolean;
|
|
||||||
type?: 'contained' | 'outlined' | 'label' | 'border';
|
|
||||||
startWith?: TAG_START_WITH;
|
|
||||||
tag: TagLabel;
|
|
||||||
showOnlyName?: boolean;
|
|
||||||
style?: React.CSSProperties;
|
|
||||||
};
|
|
@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2022 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 { Tag, Tooltip, Typography } from 'antd';
|
|
||||||
import { ReactComponent as IconTag } from 'assets/svg/classification.svg';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import { FQN_SEPARATOR_CHAR } from 'constants/char.constants';
|
|
||||||
import { ROUTES } from 'constants/constants';
|
|
||||||
import { TagSource } from 'generated/type/tagLabel';
|
|
||||||
import React, { FunctionComponent, useMemo } from 'react';
|
|
||||||
import { useHistory } from 'react-router-dom';
|
|
||||||
import { getTagDisplay, getTagTooltip } from 'utils/TagsUtils';
|
|
||||||
import { ReactComponent as IconPage } from '../../../assets/svg/ic-flat-doc.svg';
|
|
||||||
import { ReactComponent as PlusIcon } from '../../../assets/svg/plus-primary.svg';
|
|
||||||
|
|
||||||
import { TAG_START_WITH } from 'constants/Tag.constants';
|
|
||||||
import { TagProps } from './tags.interface';
|
|
||||||
import './Tags.less';
|
|
||||||
|
|
||||||
const Tags: FunctionComponent<TagProps> = ({
|
|
||||||
className,
|
|
||||||
editable,
|
|
||||||
tag,
|
|
||||||
startWith,
|
|
||||||
type = 'contained',
|
|
||||||
showOnlyName = false,
|
|
||||||
|
|
||||||
style,
|
|
||||||
}: TagProps) => {
|
|
||||||
const history = useHistory();
|
|
||||||
|
|
||||||
const isGlossaryTag = useMemo(
|
|
||||||
() => tag.source === TagSource.Glossary,
|
|
||||||
[tag.source]
|
|
||||||
);
|
|
||||||
|
|
||||||
const startIcon = useMemo(() => {
|
|
||||||
switch (startWith) {
|
|
||||||
case TAG_START_WITH.PLUS:
|
|
||||||
return (
|
|
||||||
<PlusIcon
|
|
||||||
className="flex-shrink"
|
|
||||||
height={16}
|
|
||||||
name="plus"
|
|
||||||
width={16}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
case TAG_START_WITH.SOURCE_ICON:
|
|
||||||
return isGlossaryTag ? (
|
|
||||||
<IconPage
|
|
||||||
className="flex-shrink"
|
|
||||||
data-testid="glossary-icon"
|
|
||||||
height={12}
|
|
||||||
name="glossary-icon"
|
|
||||||
width={12}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<IconTag
|
|
||||||
className="flex-shrink"
|
|
||||||
data-testid="tags-icon"
|
|
||||||
height={12}
|
|
||||||
name="tag-icon"
|
|
||||||
width={12}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
return startWith;
|
|
||||||
}
|
|
||||||
}, [startWith, isGlossaryTag]);
|
|
||||||
|
|
||||||
const tagChip = useMemo(() => {
|
|
||||||
const tagName = showOnlyName
|
|
||||||
? tag.tagFQN.split(FQN_SEPARATOR_CHAR).slice(-2).join(FQN_SEPARATOR_CHAR)
|
|
||||||
: tag.tagFQN;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Tag
|
|
||||||
className={classNames('tag-container-style', type, className)}
|
|
||||||
data-testid="tags"
|
|
||||||
icon={startIcon}
|
|
||||||
style={style}
|
|
||||||
onClick={() => {
|
|
||||||
if (tag.source && startWith !== TAG_START_WITH.PLUS) {
|
|
||||||
tag.source === TagSource.Glossary
|
|
||||||
? history.push(
|
|
||||||
`${ROUTES.GLOSSARY}/${encodeURIComponent(tag.tagFQN)}`
|
|
||||||
)
|
|
||||||
: history.push(`${ROUTES.TAGS}/${tag.tagFQN.split('.')[0]}`);
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
<Typography.Paragraph
|
|
||||||
className="m-0"
|
|
||||||
data-testid={
|
|
||||||
startWith === TAG_START_WITH.PLUS ? 'add-tag' : `tag-${tag.tagFQN}`
|
|
||||||
}
|
|
||||||
style={{
|
|
||||||
display: 'inline-block',
|
|
||||||
whiteSpace: 'normal',
|
|
||||||
wordBreak: 'break-all',
|
|
||||||
color: 'inherit',
|
|
||||||
}}>
|
|
||||||
{getTagDisplay(tagName)}
|
|
||||||
</Typography.Paragraph>
|
|
||||||
</Tag>
|
|
||||||
);
|
|
||||||
}, [startIcon, tag, editable]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="tags-component-container">
|
|
||||||
{startWith === TAG_START_WITH.PLUS ? (
|
|
||||||
tagChip
|
|
||||||
) : (
|
|
||||||
<Tooltip
|
|
||||||
className="cursor-pointer"
|
|
||||||
mouseEnterDelay={1.5}
|
|
||||||
placement="bottomLeft"
|
|
||||||
title={getTagTooltip(tag.tagFQN, tag.description)}
|
|
||||||
trigger="hover">
|
|
||||||
{tagChip}
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Tags;
|
|
@ -155,20 +155,22 @@ const TagsContainerV2 = ({
|
|||||||
const addTagButton = useMemo(
|
const addTagButton = useMemo(
|
||||||
() =>
|
() =>
|
||||||
showAddTagButton ? (
|
showAddTagButton ? (
|
||||||
<span onClick={handleAddClick}>
|
<Col onClick={handleAddClick}>
|
||||||
<TagsV1 startWith={TAG_START_WITH.PLUS} tag={TAG_CONSTANT} />
|
<TagsV1 startWith={TAG_START_WITH.PLUS} tag={TAG_CONSTANT} />
|
||||||
</span>
|
</Col>
|
||||||
) : null,
|
) : null,
|
||||||
[showAddTagButton]
|
[showAddTagButton]
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderTags = useMemo(
|
const renderTags = useMemo(
|
||||||
() => (
|
() => (
|
||||||
|
<Col>
|
||||||
<TagsViewer
|
<TagsViewer
|
||||||
showNoDataPlaceholder={showNoDataPlaceholder}
|
showNoDataPlaceholder={showNoDataPlaceholder}
|
||||||
tags={tags?.[tagType] ?? []}
|
tags={tags?.[tagType] ?? []}
|
||||||
type="border"
|
type="border"
|
||||||
/>
|
/>
|
||||||
|
</Col>
|
||||||
),
|
),
|
||||||
[showNoDataPlaceholder, tags?.[tagType]]
|
[showNoDataPlaceholder, tags?.[tagType]]
|
||||||
);
|
);
|
||||||
@ -329,11 +331,11 @@ const TagsContainerV2 = ({
|
|||||||
{header}
|
{header}
|
||||||
|
|
||||||
{!isEditTags && (
|
{!isEditTags && (
|
||||||
<Space wrap data-testid="entity-tags" size={4}>
|
<Row data-testid="entity-tags">
|
||||||
{addTagButton}
|
{addTagButton}
|
||||||
{renderTags}
|
{renderTags}
|
||||||
{showInlineEditButton && editTagButton}
|
{showInlineEditButton && <Col>{editTagButton}</Col>}
|
||||||
</Space>
|
</Row>
|
||||||
)}
|
)}
|
||||||
{isEditTags && tagsSelectContainer}
|
{isEditTags && tagsSelectContainer}
|
||||||
|
|
||||||
|
@ -29,7 +29,12 @@ import './tagsV1.less';
|
|||||||
|
|
||||||
const color = '';
|
const color = '';
|
||||||
|
|
||||||
const TagsV1 = ({ tag, startWith, showOnlyName = false }: TagsV1Props) => {
|
const TagsV1 = ({
|
||||||
|
tag,
|
||||||
|
startWith,
|
||||||
|
className,
|
||||||
|
showOnlyName = false,
|
||||||
|
}: TagsV1Props) => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
const isGlossaryTag = useMemo(
|
const isGlossaryTag = useMemo(
|
||||||
@ -88,16 +93,17 @@ const TagsV1 = ({ tag, startWith, showOnlyName = false }: TagsV1Props) => {
|
|||||||
|
|
||||||
const tagContent = useMemo(
|
const tagContent = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<div className="d-flex">
|
<div className="d-flex w-full">
|
||||||
{tagColorBar}
|
{tagColorBar}
|
||||||
<span className="d-flex items-center p-x-xs">
|
<div className="d-flex items-center p-x-xs w-full">
|
||||||
<span className="m-r-xss">{startIcon}</span>
|
<span className="m-r-xss">{startIcon}</span>
|
||||||
<Typography.Paragraph
|
<Typography.Paragraph
|
||||||
|
ellipsis
|
||||||
className="m-0 tags-label"
|
className="m-0 tags-label"
|
||||||
data-testid={`tag-${tag.tagFQN}`}>
|
data-testid={`tag-${tag.tagFQN}`}>
|
||||||
{getTagDisplay(tagName)}
|
{getTagDisplay(tagName)}
|
||||||
</Typography.Paragraph>
|
</Typography.Paragraph>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
[startIcon, tagName, tag.tagFQN, tagColorBar]
|
[startIcon, tagName, tag.tagFQN, tagColorBar]
|
||||||
@ -106,14 +112,14 @@ const TagsV1 = ({ tag, startWith, showOnlyName = false }: TagsV1Props) => {
|
|||||||
const tagChip = useMemo(
|
const tagChip = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<Tag
|
<Tag
|
||||||
className={classNames('tag-chip tag-chip-content')}
|
className={classNames(className, 'tag-chip tag-chip-content')}
|
||||||
data-testid="tags"
|
data-testid="tags"
|
||||||
style={{ backgroundColor: reduceColorOpacity(color, 0.1) }}
|
style={{ backgroundColor: reduceColorOpacity(color, 0.1) }}
|
||||||
onClick={() => redirectLink()}>
|
onClick={() => redirectLink()}>
|
||||||
{tagContent}
|
{tagContent}
|
||||||
</Tag>
|
</Tag>
|
||||||
),
|
),
|
||||||
[color, tagContent]
|
[color, tagContent, className]
|
||||||
);
|
);
|
||||||
|
|
||||||
const addTagChip = useMemo(
|
const addTagChip = useMemo(
|
||||||
@ -131,9 +137,11 @@ const TagsV1 = ({ tag, startWith, showOnlyName = false }: TagsV1Props) => {
|
|||||||
[tagName]
|
[tagName]
|
||||||
);
|
);
|
||||||
|
|
||||||
return startWith === TAG_START_WITH.PLUS ? (
|
if (startWith === TAG_START_WITH.PLUS) {
|
||||||
addTagChip
|
return addTagChip;
|
||||||
) : (
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
mouseEnterDelay={1.5}
|
mouseEnterDelay={1.5}
|
||||||
|
@ -18,4 +18,5 @@ export type TagsV1Props = {
|
|||||||
tag: TagLabel;
|
tag: TagLabel;
|
||||||
startWith: TAG_START_WITH;
|
startWith: TAG_START_WITH;
|
||||||
showOnlyName?: boolean;
|
showOnlyName?: boolean;
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2022 Collate.
|
* Copyright 2023 Collate.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
@ -11,57 +11,58 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import { fireEvent, getByTestId, render } from '@testing-library/react';
|
||||||
fireEvent,
|
|
||||||
getByTestId,
|
|
||||||
queryByTestId,
|
|
||||||
render,
|
|
||||||
} from '@testing-library/react';
|
|
||||||
import { TAG_CONSTANT, TAG_START_WITH } from 'constants/Tag.constants';
|
import { TAG_CONSTANT, TAG_START_WITH } from 'constants/Tag.constants';
|
||||||
import { LabelType, State, TagSource } from 'generated/type/tagLabel';
|
import { LabelType, State, TagSource } from 'generated/type/tagLabel';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Tags from './tags';
|
import TagsV1 from './TagsV1.component';
|
||||||
|
|
||||||
const mockPush = jest.fn();
|
const mockPush = jest.fn();
|
||||||
|
|
||||||
jest.mock('components/common/rich-text-editor/RichTextEditorPreviewer', () => {
|
|
||||||
return jest.fn().mockReturnValue(<p>RichTextEditorPreviewer</p>);
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.mock('react-router-dom', () => ({
|
jest.mock('react-router-dom', () => ({
|
||||||
useHistory: jest.fn().mockImplementation(() => ({
|
useHistory: jest.fn().mockImplementation(() => ({
|
||||||
push: mockPush,
|
push: mockPush,
|
||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
jest.mock('../../../utils/TagsUtils', () => ({
|
||||||
|
getTagDisplay: jest.fn().mockReturnValue('tags'),
|
||||||
|
getTagTooltip: jest.fn().mockReturnValue(<p>ToolTip Data</p>),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('../../../utils/CommonUtils', () => ({
|
||||||
|
reduceColorOpacity: jest.fn().mockReturnValue('#00000'),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('Test tags Component', () => {
|
describe('Test tags Component', () => {
|
||||||
it('Component should render', () => {
|
it('Component should render', () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<Tags editable tag={{ ...TAG_CONSTANT, tagFQN: 'test' }} />
|
<TagsV1
|
||||||
|
startWith={TAG_START_WITH.SOURCE_ICON}
|
||||||
|
tag={{ ...TAG_CONSTANT, tagFQN: 'test' }}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
const tags = getByTestId(container, 'tags');
|
const tags = getByTestId(container, 'tags');
|
||||||
|
|
||||||
expect(tags).toBeInTheDocument();
|
expect(tags).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Component should render properly for add tag button', () => {
|
it('Component should render add tag button', () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<Tags
|
<TagsV1
|
||||||
startWith={TAG_START_WITH.PLUS}
|
startWith={TAG_START_WITH.PLUS}
|
||||||
tag={{ ...TAG_CONSTANT, tagFQN: 'add tag' }}
|
tag={{ ...TAG_CONSTANT, tagFQN: 'add tag' }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
const tags = getByTestId(container, 'tags');
|
const addTags = getByTestId(container, 'add-tag');
|
||||||
const remove = queryByTestId(container, 'remove-test-tag');
|
|
||||||
|
|
||||||
expect(tags).toBeInTheDocument();
|
expect(addTags).toBeInTheDocument();
|
||||||
expect(remove).toBeNull();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Clicking on tag with source Classification should redirect to the proper Classification page', () => {
|
it('Clicking on tag with source Classification should redirect to the proper Classification page', () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<Tags
|
<TagsV1
|
||||||
editable
|
startWith={TAG_START_WITH.SOURCE_ICON}
|
||||||
tag={{
|
tag={{
|
||||||
labelType: LabelType.Manual,
|
labelType: LabelType.Manual,
|
||||||
source: TagSource.Classification,
|
source: TagSource.Classification,
|
||||||
@ -80,8 +81,8 @@ describe('Test tags Component', () => {
|
|||||||
|
|
||||||
it('Clicking on tag with source Glossary should redirect to the proper glossary term page', () => {
|
it('Clicking on tag with source Glossary should redirect to the proper glossary term page', () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<Tags
|
<TagsV1
|
||||||
editable
|
startWith={TAG_START_WITH.SOURCE_ICON}
|
||||||
tag={{
|
tag={{
|
||||||
description: 'TestDescription',
|
description: 'TestDescription',
|
||||||
labelType: LabelType.Manual,
|
labelType: LabelType.Manual,
|
@ -14,6 +14,8 @@
|
|||||||
@import url('../../../styles/variables.less');
|
@import url('../../../styles/variables.less');
|
||||||
|
|
||||||
.tag-chip {
|
.tag-chip {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -26,10 +28,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tag-chip-content {
|
.tag-chip-content {
|
||||||
|
width: max-content;
|
||||||
margin: 0 5px 4px 0;
|
margin: 0 5px 4px 0;
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: rgba(0, 0, 0, 0.03);
|
background: @tag-background-color;
|
||||||
|
|
||||||
|
&.diff-added {
|
||||||
|
background: @success-background-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag-chip-add-button {
|
.tag-chip-add-button {
|
||||||
@ -40,14 +47,13 @@
|
|||||||
.tag-color-bar {
|
.tag-color-bar {
|
||||||
width: 5px;
|
width: 5px;
|
||||||
height: auto;
|
height: auto;
|
||||||
background: rgba(0, 0, 0, 0.03);
|
background: @tag-background-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tags-label {
|
.tags-label {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
white-space: normal;
|
font-size: 12px;
|
||||||
word-break: break-all;
|
font-weight: 500;
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
@ -11,15 +11,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Popover, Space, Tag, Typography } from 'antd';
|
import { Popover, Tag, Typography } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import Tags from 'components/Tag/Tags/tags';
|
|
||||||
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';
|
||||||
import { EntityTags } from 'Models';
|
import { EntityTags } from 'Models';
|
||||||
import React, { FunctionComponent, useCallback, useMemo } from 'react';
|
import React, { FunctionComponent, useCallback, useMemo } from 'react';
|
||||||
import { LIST_SIZE, NO_DATA_PLACEHOLDER } from '../../../constants/constants';
|
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 { TagsViewerProps } from './tags-viewer.interface';
|
import { TagsViewerProps } from './tags-viewer.interface';
|
||||||
import './tags-viewer.less';
|
import './tags-viewer.less';
|
||||||
|
|
||||||
@ -29,14 +29,9 @@ const TagsViewer: FunctionComponent<TagsViewerProps> = ({
|
|||||||
type = 'label',
|
type = 'label',
|
||||||
showNoDataPlaceholder = true,
|
showNoDataPlaceholder = true,
|
||||||
}: TagsViewerProps) => {
|
}: TagsViewerProps) => {
|
||||||
const tagChipStye = {
|
|
||||||
margin: '0 0 8px 0',
|
|
||||||
justifyContent: 'start',
|
|
||||||
};
|
|
||||||
|
|
||||||
const getTagsElement = useCallback(
|
const getTagsElement = useCallback(
|
||||||
(tag: EntityTags, index: number, style?: React.CSSProperties) => (
|
(tag: EntityTags, index: number) => (
|
||||||
<Tags
|
<TagsV1
|
||||||
className={classNames(
|
className={classNames(
|
||||||
{ 'diff-added tw-mx-1': tag?.added },
|
{ 'diff-added tw-mx-1': tag?.added },
|
||||||
{ 'diff-removed': tag?.removed }
|
{ 'diff-removed': tag?.removed }
|
||||||
@ -44,9 +39,7 @@ const TagsViewer: FunctionComponent<TagsViewerProps> = ({
|
|||||||
key={index}
|
key={index}
|
||||||
showOnlyName={tag.source === TagSource.Glossary}
|
showOnlyName={tag.source === TagSource.Glossary}
|
||||||
startWith={TAG_START_WITH.SOURCE_ICON}
|
startWith={TAG_START_WITH.SOURCE_ICON}
|
||||||
style={style}
|
|
||||||
tag={tag}
|
tag={tag}
|
||||||
type={type}
|
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
[type]
|
[type]
|
||||||
@ -58,17 +51,19 @@ const TagsViewer: FunctionComponent<TagsViewerProps> = ({
|
|||||||
[tags]
|
[tags]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (isEmpty(sortedTagsBySource) && showNoDataPlaceholder) {
|
||||||
return (
|
return (
|
||||||
<Space wrap size={4}>
|
|
||||||
{isEmpty(sortedTagsBySource) && showNoDataPlaceholder ? (
|
|
||||||
<Typography.Text className="text-grey-muted m-r-xss">
|
<Typography.Text className="text-grey-muted m-r-xss">
|
||||||
{NO_DATA_PLACEHOLDER}
|
{NO_DATA_PLACEHOLDER}
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
) : sizeCap > -1 ? (
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{sizeCap > -1 ? (
|
||||||
<>
|
<>
|
||||||
{sortedTagsBySource
|
{sortedTagsBySource.slice(0, sizeCap).map(getTagsElement)}
|
||||||
.slice(0, sizeCap)
|
|
||||||
.map((tag, index) => getTagsElement(tag, index))}
|
|
||||||
|
|
||||||
{sortedTagsBySource.slice(sizeCap).length > 0 && (
|
{sortedTagsBySource.slice(sizeCap).length > 0 && (
|
||||||
<Popover
|
<Popover
|
||||||
@ -76,7 +71,7 @@ const TagsViewer: FunctionComponent<TagsViewerProps> = ({
|
|||||||
<>
|
<>
|
||||||
{sortedTagsBySource.slice(sizeCap).map((tag, index) => (
|
{sortedTagsBySource.slice(sizeCap).map((tag, index) => (
|
||||||
<p className="text-left" key={index}>
|
<p className="text-left" key={index}>
|
||||||
{getTagsElement(tag, index, tagChipStye)}
|
{getTagsElement(tag, index)}
|
||||||
</p>
|
</p>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
@ -93,11 +88,9 @@ const TagsViewer: FunctionComponent<TagsViewerProps> = ({
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
sortedTagsBySource.map(getTagsElement)
|
||||||
{sortedTagsBySource.map((tag, index) => getTagsElement(tag, index))}
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</Space>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,10 +95,6 @@ jest.mock('components/Tag/TagsContainerV2/TagsContainerV2', () => {
|
|||||||
return jest.fn().mockReturnValue(<p>TagsContainerV2</p>);
|
return jest.fn().mockReturnValue(<p>TagsContainerV2</p>);
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('components/Tag/Tags/tags', () => {
|
|
||||||
return jest.fn().mockReturnValue(<p>Tags</p>);
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.mock('../FeedEditor/FeedEditor', () => {
|
jest.mock('../FeedEditor/FeedEditor', () => {
|
||||||
return jest.fn().mockReturnValue(<p>FeedEditor</p>);
|
return jest.fn().mockReturnValue(<p>FeedEditor</p>);
|
||||||
});
|
});
|
||||||
|
@ -476,3 +476,21 @@ a[href].link-text-grey,
|
|||||||
height: @entity-details-tab-height;
|
height: @entity-details-tab-height;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Diff style */
|
||||||
|
|
||||||
|
.diff-added {
|
||||||
|
background: @success-background-color;
|
||||||
|
color: @success-color;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-removed {
|
||||||
|
color: grey;
|
||||||
|
text-decoration: line-through;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-description {
|
||||||
|
color: @success-color;
|
||||||
|
}
|
||||||
|
@ -705,23 +705,6 @@ body .list-option.rdw-option-active {
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Diff style */
|
|
||||||
|
|
||||||
.diff-added {
|
|
||||||
background: rgba(0, 131, 118, 0.2);
|
|
||||||
color: #008376;
|
|
||||||
width: fit-content;
|
|
||||||
}
|
|
||||||
.diff-removed {
|
|
||||||
color: #008376;
|
|
||||||
color: grey;
|
|
||||||
text-decoration: line-through;
|
|
||||||
width: fit-content;
|
|
||||||
}
|
|
||||||
.diff-description {
|
|
||||||
color: #008376;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* react-slick */
|
/* react-slick */
|
||||||
|
|
||||||
.slick-dots {
|
.slick-dots {
|
||||||
|
@ -78,6 +78,8 @@
|
|||||||
@grey-bg-with-alpha: #7575751a;
|
@grey-bg-with-alpha: #7575751a;
|
||||||
@btn-shadow: none;
|
@btn-shadow: none;
|
||||||
@user-profile-background: rgba(9, 80, 197, 0.05);
|
@user-profile-background: rgba(9, 80, 197, 0.05);
|
||||||
|
@success-background-color: rgba(0, 131, 118, 0.2);
|
||||||
|
@tag-background-color: rgba(0, 0, 0, 0.03);
|
||||||
|
|
||||||
@navbar-height: 64px;
|
@navbar-height: 64px;
|
||||||
@sidebar-width: 60px;
|
@sidebar-width: 60px;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user