Fixed issue: UI: Glossary details page improvements#6834" (#6879)

* Fixed issue: UI: Glossary details page improvements#6834"

* added data-testid

* fixed input box re-render issue

* fixed failing cypress for glossary

* addressing comments

* fixed failing cypress

* updated glossary test and cypress

* fixed glossary test
This commit is contained in:
Shailesh Parmar 2022-08-26 16:08:02 +05:30 committed by GitHub
parent 0ad7e0af1b
commit 87f8bcc4fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 351 additions and 233 deletions

View File

@ -201,6 +201,7 @@ describe('Glossary page should work properly', () => {
cy.get('@description').type(newDescription);
cy.get('[data-testid="save"]').click();
cy.get('.tw-modal-container').should('not.exist');
cy.wait(1000);
cy.get('[data-testid="viewer-container"]')
.contains(newDescription)
.should('be.visible');
@ -215,11 +216,11 @@ describe('Glossary page should work properly', () => {
cy.wait(500);
cy.get('[data-testid="inactive-link"]').contains(term).should('be.visible');
// updating synonyms
cy.get('[data-testid="edit-synonyms"]')
cy.get('[data-testid="section-synonyms"]')
.scrollIntoView()
.should('be.visible')
.click();
cy.get('[data-testid="synonyms"]')
.scrollIntoView()
.should('be.visible')
@ -228,7 +229,7 @@ describe('Glossary page should work properly', () => {
cy.get('@synonyms').type(uSynonyms);
cy.get('[data-testid="saveAssociatedTag"]').should('be.visible').click();
cy.wait(100);
cy.get('[data-testid="synonyms-card-container"]')
cy.get('[data-testid="synonyms-container"]')
.as('synonyms-container')
.should('be.visible');
@ -237,16 +238,17 @@ describe('Glossary page should work properly', () => {
});
// updating References
cy.get('[data-testid="edit-referencfe"]').should('exist').click();
cy.get('[data-testid="section-references"] [data-testid="add-button"]')
.should('exist')
.click();
cy.get('.tw-modal-container').should('be.visible');
cy.get('[data-testid="references"] > :nth-child(1) > .button-comp')
cy.get('[data-testid="references"] .button-comp')
.should('be.visible')
.click();
cy.get('#name-1').should('be.visible').type(newRef.name);
cy.get('#url-1').should('be.visible').type(newRef.url);
cy.get('[data-testid="saveButton"]').should('be.visible').click();
cy.get('[data-testid="references-card-container"]')
.scrollIntoView()
cy.get('[data-testid="references-container"]')
.contains(newRef.name)
.should('be.visible')
.invoke('attr', 'href')
@ -269,6 +271,7 @@ describe('Glossary page should work properly', () => {
.contains('PersonalData.Personal')
.should('be.visible');
cy.wait(1000);
// updating description
cy.get('[data-testid="edit-description"]').should('be.visible').click();
cy.get('.tw-modal-container').should('be.visible');
@ -279,6 +282,9 @@ describe('Glossary page should work properly', () => {
cy.get('@description').type(newDescription);
cy.get('[data-testid="save"]').click();
cy.get('.tw-modal-container').should('not.exist');
cy.wait(1000);
cy.get('[data-testid="viewer-container"]')
.contains(newDescription)
.should('be.visible');
@ -335,6 +341,7 @@ describe('Glossary page should work properly', () => {
const entity = SEARCH_ENTITY_TABLE.table_3.term;
// go assets tab
goToAssetsTab(term);
cy.wait(1000);
cy.get('[data-testid="column"] > :nth-child(1) > a')
.contains(entity)
.should('be.visible')
@ -354,8 +361,10 @@ describe('Glossary page should work properly', () => {
.scrollIntoView()
.should('be.visible')
.click();
cy.get('[data-testid="saveAssociatedTag"]').scrollIntoView().click();
//Remove the added column tag from entity
cy.get(
':nth-child(1) > :nth-child(5) > [data-testid="tags-wrapper"] > :nth-child(1) > :nth-child(1) > [data-testid="tag-container"] > div > span.tw-text-primary > [data-testid="tags"]'
)
@ -367,7 +376,6 @@ describe('Glossary page should work properly', () => {
.scrollIntoView()
.should('be.visible')
.click();
cy.get(':nth-child(1) > .css-xb97g8')
.scrollIntoView()
.should('be.visible')

View File

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.0465 6.70756C12.7823 6.70756 12.568 6.92179 12.568 7.18605V13.8372C12.568 14.2402 12.2402 14.568 11.8372 14.568H2.16279C1.75984 14.568 1.43198 14.2402 1.43198 13.8372V4.16279C1.43198 3.75984 1.75984 3.43198 2.16279 3.43198H8.81395C9.07821 3.43198 9.29244 3.21774 9.29244 2.95349C9.29244 2.68923 9.07821 2.475 8.81395 2.475H2.16279C1.23212 2.475 0.475 3.23212 0.475 4.16279V13.8372C0.475 14.7679 1.23212 15.525 2.16279 15.525H11.8372C12.7679 15.525 13.525 14.7679 13.525 13.8372V7.18605C13.525 6.92179 13.3108 6.70756 13.0465 6.70756Z" fill="#7147E8" stroke="#7147E8" stroke-width="0.05"/>
<path d="M15.1809 1.70377L14.297 0.819838C13.8706 0.393387 13.1767 0.393387 12.7502 0.819838L5.67892 7.89112C5.61348 7.95656 5.56888 8.03991 5.55069 8.13066L5.10871 10.3404C5.07799 10.4941 5.12609 10.653 5.23693 10.7638C5.32572 10.8526 5.44532 10.9012 5.56838 10.9012C5.59898 10.9012 5.62973 10.8982 5.66029 10.8921L7.87008 10.4501C7.96083 10.4319 8.04418 10.3873 8.10962 10.3219L15.1809 3.2506C15.1809 3.2506 15.181 3.2506 15.181 3.25057C15.6074 2.82415 15.6074 2.13025 15.1809 1.70377ZM7.54707 9.55858L6.16596 9.83484L6.44222 8.45373L12.1977 2.69815L13.3026 3.80306L7.54707 9.55858ZM14.518 2.58767L13.9656 3.14013L12.8606 2.03522L13.4131 1.4828C13.474 1.42186 13.5731 1.42183 13.6341 1.48277L14.518 2.3667C14.5789 2.42761 14.5789 2.52677 14.518 2.58767Z" fill="#7147E8"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.5" y="0.5" width="15" height="15" rx="1.5" stroke="#7147E8"/>
<path d="M11.9175 8.6532H8.65222V11.9185C8.65222 12.2777 8.35835 12.5716 7.99916 12.5716C7.63998 12.5716 7.3461 12.2777 7.3461 11.9185V8.6532H4.0808C3.72161 8.6532 3.42773 8.35932 3.42773 8.00014C3.42773 7.64096 3.72161 7.34708 4.0808 7.34708H7.3461V4.08177C7.3461 3.72259 7.63998 3.42871 7.99916 3.42871C8.35835 3.42871 8.65222 3.72259 8.65222 4.08177V7.34708H11.9175C12.2767 7.34708 12.5706 7.64096 12.5706 8.00014C12.5706 8.35932 12.2767 8.6532 11.9175 8.6532Z" fill="#7147E8"/>
</svg>

After

Width:  |  Height:  |  Size: 658 B

View File

@ -19,8 +19,7 @@ import cryptoRandomString from 'crypto-random-string-with-promisify-polyfill';
import { cloneDeep, isEqual, isNil } from 'lodash';
import { EditorContentRef } from 'Models';
import React, { FunctionComponent, useCallback, useRef, useState } from 'react';
import { TERM_ALL } from '../../constants/constants';
import { ROUTES } from '../../constants/constants';
import { ROUTES, TERM_ALL } from '../../constants/constants';
import {
GlobalSettingOptions,
GlobalSettingsMenuCategory,

View File

@ -49,7 +49,12 @@ jest.mock('../../components/GlossaryTerms/GlossaryTermsV1.component', () => {
return jest.fn().mockReturnValue(<>Glossary-Term component</>);
});
jest.mock('../common/title-breadcrumb/title-breadcrumb.component', () => {
return jest.fn().mockReturnValue(<>TitleBreadcrumb</>);
});
jest.mock('antd', () => ({
Card: jest.fn().mockImplementation(({ children }) => <div>{children}</div>),
Col: jest.fn().mockImplementation(({ children }) => <div>{children}</div>),
Input: jest.fn().mockImplementation(({ children }) => <div>{children}</div>),
Row: jest.fn().mockImplementation(({ children }) => <div>{children}</div>),

View File

@ -162,8 +162,9 @@ const GlossaryV1 = ({
if (selectedKey !== key) {
handleChildLoading(true);
handleSelectedData(key);
setIsNameEditing(false);
}
setIsNameEditing(false);
};
const onDisplayNameChange = (value: string) => {
@ -349,7 +350,7 @@ const GlossaryV1 = ({
visible={showActions}
onVisibleChange={setShowActions}>
<Button
className="tw-rounded tw-flex tw-justify-center tw-w-8 tw-h-8 glossary-manage-button tw-mb-1 tw-flex"
className="tw-rounded tw-justify-center tw-w-8 tw-h-8 glossary-manage-button tw-mb-1 tw-flex"
data-testid="manage-button"
disabled={isHasAccess}
size="small"

View File

@ -12,6 +12,7 @@
*/
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Card as AntdCard } from 'antd';
import { AxiosError } from 'axios';
import classNames from 'classnames';
import { cloneDeep, debounce, includes, isEqual } from 'lodash';
@ -475,15 +476,17 @@ const GlossaryDetails = ({ isHasAccess, glossary, updateGlossary }: props) => {
<div className="tw-flex tw-gap-3">
<div className="tw-w-9/12">
<div className="tw-mb-4" data-testid="description-container">
<DescriptionV1
removeBlur
description={glossary?.description}
entityName={glossary?.displayName ?? glossary?.name}
isEdit={isDescriptionEditable}
onCancel={onCancel}
onDescriptionEdit={onDescriptionEdit}
onDescriptionUpdate={onDescriptionUpdate}
/>
<AntdCard className="glossary-card">
<DescriptionV1
removeBlur
description={glossary?.description}
entityName={glossary?.displayName ?? glossary?.name}
isEdit={isDescriptionEditable}
onCancel={onCancel}
onDescriptionEdit={onDescriptionEdit}
onDescriptionUpdate={onDescriptionUpdate}
/>
</AntdCard>
</div>
</div>
<div className="tw-w-3/12 tw-px-2">

View File

@ -42,7 +42,7 @@ jest.mock('../../components/tags-container/tags-container', () => {
return jest.fn().mockReturnValue(<>Tags-container component</>);
});
jest.mock('../../components/common/description/DescriptionV1', () => {
jest.mock('../common/description/DescriptionV1', () => {
return jest.fn().mockReturnValue(<>Description component</>);
});
@ -58,6 +58,47 @@ jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => {
return jest.fn().mockReturnValue(<p>RichTextEditorPreviewer</p>);
});
jest.mock('antd', () => ({
Card: jest
.fn()
.mockImplementation(({ children, ...props }) => (
<div {...props}>{children}</div>
)),
Col: jest
.fn()
.mockImplementation(({ children, ...props }) => (
<div {...props}>{children}</div>
)),
Row: jest
.fn()
.mockImplementation(({ children, ...props }) => (
<div {...props}>{children}</div>
)),
Divider: jest
.fn()
.mockImplementation(({ children, ...props }) => (
<div {...props}>{children}</div>
)),
Typography: {
Text: jest.fn().mockImplementation(({ children }) => <div>{children}</div>),
},
Space: jest
.fn()
.mockImplementation(({ children, ...props }) => (
<div {...props}>{children}</div>
)),
Input: jest
.fn()
.mockImplementation(({ children, ...props }) => (
<div {...props}>{children}</div>
)),
Button: jest
.fn()
.mockImplementation(({ children, ...props }) => (
<div {...props}>{children}</div>
)),
}));
const mockProps = {
assetData: mockedAssetData,
currentPage: 1,

View File

@ -12,9 +12,27 @@
*/
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
Button,
Card,
Col,
Divider,
Input,
Row,
Space,
Typography,
} from 'antd';
import { AxiosError } from 'axios';
import classNames from 'classnames';
import { cloneDeep, includes, isEmpty, isEqual, isUndefined } from 'lodash';
import {
cloneDeep,
includes,
isEmpty,
isEqual,
isString,
isUndefined,
kebabCase,
} from 'lodash';
import {
EntityTags,
FormattedGlossaryTermData,
@ -40,8 +58,6 @@ import {
getTagOptionsFromFQN,
} from '../../utils/TagsUtils';
import { showErrorToast } from '../../utils/ToastUtils';
import { Button } from '../buttons/Button/Button';
import Card from '../common/Card/Card';
import DescriptionV1 from '../common/description/DescriptionV1';
import NonAdminAction from '../common/non-admin-action/NonAdminAction';
import ProfilePicture from '../common/ProfilePicture/ProfilePicture';
@ -53,6 +69,7 @@ import TagsContainer from '../tags-container/tags-container';
import TagsViewer from '../tags-viewer/tags-viewer';
import Tags from '../tags/tags';
import AssetsTabs from './tabs/AssetsTabs.component';
const { Text } = Typography;
type Props = {
assetData: GlossaryTermAssets;
@ -65,6 +82,13 @@ type Props = {
handleUserRedirection?: (name: string) => void;
};
type SummaryDetailsProps = {
title: string;
children: React.ReactElement;
setShow?: (value: React.SetStateAction<boolean>) => void;
data?: FormattedGlossaryTermData[] | TermReference[] | string;
};
const GlossaryTermsV1 = ({
assetData,
isHasAccess,
@ -292,18 +316,6 @@ const GlossaryTermsV1 = ({
}
};
const handleRemoveSynonym = (_e: React.MouseEvent, synonym: string) => {
if (!isUndefined(glossaryTerm.synonyms)) {
const synonyms = glossaryTerm.synonyms.filter((d) => d !== synonym);
const updatedGlossaryTerm = {
...glossaryTerm,
synonyms: synonyms,
};
setSynonyms(synonyms.join(','));
handleGlossaryTermUpdate(updatedGlossaryTerm);
}
};
const handleTagContainerClick = () => {
if (!isTagEditable) {
fetchTags();
@ -344,33 +356,15 @@ const GlossaryTermsV1 = ({
);
};
const addButton = (title: string, onClick: () => void) => {
const addButton = (onClick: () => void) => {
return (
<NonAdminAction position="bottom" title={TITLE_FOR_NON_ADMIN_ACTION}>
<Button
className={classNames('tw-h-8 tw-rounded', {
'tw-opacity-40': isHasAccess,
})}
data-testid="add-related-term-button"
size="small"
theme="primary"
variant="outlined"
<span
className="tw-cursor-pointer"
data-testid="add-button"
onClick={onClick}>
{title}
</Button>
</NonAdminAction>
);
};
const editButton = (onClick: () => void) => {
return (
<NonAdminAction position="bottom" title={TITLE_FOR_NON_ADMIN_ACTION}>
<button
className="focus:tw-outline-none tw-text-primary"
data-testid="edit-referencfe"
onClick={onClick}>
<SVGIcons alt="edit" icon={Icons.EDIT} title="Edit" width="16px" />
</button>
<SVGIcons alt="icon-plus-primary" icon="icon-plus-primary-outlined" />
</span>
</NonAdminAction>
);
};
@ -430,46 +424,52 @@ const GlossaryTermsV1 = ({
);
};
const getSynonyms = (synonyms: string) => {
return !isEmpty(synonyms) ? (
synonyms
.split(',')
.map((synonym) => (
<Tags
editable
isRemovable
key={synonym}
removeTag={handleRemoveSynonym}
tag={synonym}
type="border"
/>
))
const getSynonyms = (synonymsList: string) => {
return !isEmpty(synonymsList) ? (
synonymsList.split(',').map((synonym, index) => (
<>
{index > 0 ? <span className="tw-mr-2">,</span> : null}
<span>{synonym}</span>
</>
))
) : (
<></>
);
};
const relatedTermActionBtn = () => {
return relatedTerms.length > 0 ? (
editButton(() => setShowRelatedTermsModal(true))
) : (
<></>
);
};
const referenceActionBtn = () => {
return references.length > 0 ? (
editButton(() => setIsReferencesEditing(true))
) : (
<></>
);
};
const summaryTab = () => {
const SummaryDetail = ({
title,
children,
setShow,
data,
...props
}: SummaryDetailsProps) => {
return (
<div className="tw-flex tw-gap-3">
<div className="tw-w-9/12">
<div className="tw-mb-4" data-testid="description-container">
<Space direction="vertical" {...props}>
<Space>
<Text type="secondary">{title}</Text>
<div className="tw-ml-2" data-testid={`section-${kebabCase(title)}`}>
{addButton(() => setShow && setShow(true))}
</div>
</Space>
{!isString(data) && !isUndefined(data) && data.length > 0 ? (
<div
className="tw-flex"
data-testid={`${kebabCase(title)}-container`}>
{children}
</div>
) : (
<div data-testid={`${kebabCase(title)}-container`}>{children}</div>
)}
</Space>
);
};
const SummaryTab = () => {
return (
<Row gutter={16}>
<Col flex="75%">
<Card className="glossary-card">
<DescriptionV1
removeBlur
description={glossaryTerm.description || ''}
@ -479,113 +479,94 @@ const GlossaryTermsV1 = ({
onDescriptionEdit={onDescriptionEdit}
onDescriptionUpdate={onDescriptionUpdate}
/>
</div>
<Card
action={relatedTermActionBtn()}
className="tw-mb-4"
heading="Related Terms">
<Fragment>
{relatedTerms.length > 0 ? (
<div className="tw-flex">
{relatedTerms.map((d, i) => (
<Fragment key={i}>
{i > 0 && <span className="tw-mr-1">,</span>}
<Divider className="m-r-1" />
<SummaryDetail
data={relatedTerms}
key="related_term"
setShow={setShowRelatedTermsModal}
title="Related Terms">
<>
{relatedTerms.map((d, i) => (
<Fragment key={i}>
{i > 0 && <span className="tw-mr-2">,</span>}
<span
className="link-text-info tw-flex"
data-testid={`related-term-${d?.name}`}
onClick={() => {
onRelatedTermClick?.(d.fullyQualifiedName);
}}>
<span
className="link-text-info tw-flex"
data-testid={`related-term-${d?.name}`}
onClick={() => {
onRelatedTermClick?.(d.fullyQualifiedName);
}}>
<span
className={classNames('tw-inline-block tw-truncate', {
'tw-w-52': (d?.name as string).length > 32,
})}
title={d?.name as string}>
{d?.name}
</span>
className={classNames('tw-inline-block tw-truncate', {
'tw-w-52': (d?.name as string).length > 32,
})}
title={d?.name as string}>
{d?.name}
</span>
</Fragment>
))}
</div>
) : (
addButton('Add Related Term', () =>
setShowRelatedTermsModal(true)
)
)}
</Fragment>
</Card>
</span>
</Fragment>
))}
</>
</SummaryDetail>
<Divider className="m-r-1" />
<Card className="tw-mb-4" heading="Synonyms">
<Fragment>
{isSynonymsEditing ? (
<div className="tw-flex tw-items-center tw-gap-1">
<input
className="tw-form-inputs tw-form-inputs-padding tw-py-0.5 tw-w-72"
data-testid="synonyms"
id="synonyms"
name="synonyms"
placeholder="Enter comma seprated term"
type="text"
value={synonyms}
onChange={handleValidation}
/>
<div className="tw-flex tw-justify-end" data-testid="buttons">
<Button
className="tw-px-1 tw-py-1 tw-rounded tw-text-sm tw-mr-1"
data-testid="cancelAssociatedTag"
size="custom"
theme="primary"
variant="contained"
onMouseDown={() => setIsSynonymsEditing(false)}>
<FontAwesomeIcon
className="tw-w-3.5 tw-h-3.5"
icon="times"
/>
</Button>
<Button
className="tw-px-1 tw-py-1 tw-rounded tw-text-sm"
data-testid="saveAssociatedTag"
size="custom"
theme="primary"
variant="contained"
onMouseDown={handleSynonymsSave}>
<FontAwesomeIcon
className="tw-w-3.5 tw-h-3.5"
icon="check"
/>
</Button>
</div>
</div>
) : (
<div className="tw-flex tw-group">
<NonAdminAction
position="right"
title={TITLE_FOR_NON_ADMIN_ACTION}>
<button
className="focus:tw-outline-none tw-text-primary"
data-testid="edit-synonyms"
onClick={() => setIsSynonymsEditing(true)}>
<Tags
className="tw-font-semibold"
startWith="+ "
tag="Synonym"
type="border"
/>
</button>
</NonAdminAction>
{getSynonyms(synonyms)}
</div>
)}
</Fragment>
</Card>
<SummaryDetail
key="synonyms"
setShow={setIsSynonymsEditing}
title="Synonyms">
<>
{isSynonymsEditing ? (
<Space>
<Input
autoFocus
data-testid="synonyms"
id="synonyms"
key="synonym-input"
name="synonyms"
placeholder="Enter comma separated term"
value={synonyms}
onChange={handleValidation}
/>
<Space data-testid="buttons">
<Button
data-testid="cancelAssociatedTag"
size="small"
type="primary"
onMouseDown={() => setIsSynonymsEditing(false)}>
<FontAwesomeIcon
className="tw-w-3.5 tw-h-3.5"
icon="times"
/>
</Button>
<Button
data-testid="saveAssociatedTag"
size="small"
type="primary"
onMouseDown={handleSynonymsSave}>
<FontAwesomeIcon
className="tw-w-3.5 tw-h-3.5"
icon="check"
/>
</Button>
</Space>
</Space>
) : (
<>{getSynonyms(synonyms)}</>
)}
</>
</SummaryDetail>
<Divider className="m-r-1" />
<Card action={referenceActionBtn()} heading="References">
<Fragment>
{references && references.length > 0 ? (
<div className="tw-flex">
{references.map((d, i) => (
<SummaryDetail
data={references}
key="references"
setShow={setIsReferencesEditing}
title="References">
<>
{references &&
references.length > 0 &&
references.map((d, i) => (
<Fragment key={i}>
{i > 0 && <span className="tw-mr-1">,</span>}
{i > 0 && <span className="tw-mr-2">,</span>}
<a
className="link-text-info tw-flex"
data-testid="owner-link"
@ -602,19 +583,23 @@ const GlossaryTermsV1 = ({
</a>
</Fragment>
))}
</div>
) : (
addButton('Add Reference', () => setIsReferencesEditing(true))
)}
</Fragment>
</>
</SummaryDetail>
</Card>
</div>
<div className="tw-px-2 tw-w-3/12">
<Card action={addReviewerButton()} heading="Reviewer">
</Col>
<Col className="tw-px-10" flex="25%">
<Card
className="glossary-card right-card"
extra={addReviewerButton()}
title={
<Text strong className="p-bt-3">
Reviewer
</Text>
}>
<div>{getReviewerTabData()}</div>
</Card>
</div>
</div>
</Col>
</Row>
);
};
@ -699,7 +684,7 @@ const GlossaryTermsV1 = ({
/>
<div className="tw-flex-grow tw-py-4">
{activeTab === 1 && summaryTab()}
{activeTab === 1 && <SummaryTab />}
{activeTab === 2 && (
<AssetsTabs

View File

@ -52,6 +52,6 @@
}
.rc-tree-title {
overflow: auto;
overflow-x: hidden;
text-overflow: ellipsis;
}

View File

@ -11,6 +11,7 @@
* limitations under the License.
*/
import { Space, Typography } from 'antd';
import classNames from 'classnames';
import { isUndefined } from 'lodash';
import { EntityFieldThreads } from 'Models';
@ -22,10 +23,10 @@ import { getHtmlForNonAdminAction } from '../../../utils/CommonUtils';
import { getEntityFeedLink } from '../../../utils/EntityUtils';
import SVGIcons, { Icons } from '../../../utils/SvgUtils';
import { ModalWithMarkdownEditor } from '../../Modals/ModalWithMarkdownEditor/ModalWithMarkdownEditor';
import Card from '../Card/Card';
import NonAdminAction from '../non-admin-action/NonAdminAction';
import PopOver from '../popover/PopOver';
import RichTextEditorPreviewer from '../rich-text-editor/RichTextEditorPreviewer';
const { Text } = Typography;
interface Props {
entityName?: string;
@ -45,7 +46,6 @@ interface Props {
onSuggest?: (value: string) => void;
onEntityFieldSelect?: (value: string) => void;
}
const DescriptionV1 = ({
owner,
hasEditAccess,
@ -76,7 +76,12 @@ const DescriptionV1 = ({
className="focus:tw-outline-none tw-text-primary"
data-testid="edit-description"
onClick={onDescriptionEdit}>
<SVGIcons alt="edit" icon={Icons.EDIT} title="Edit" width="16px" />
<SVGIcons
alt="edit"
icon={Icons.IC_EDIT_PRIMARY}
title="Edit"
width="16px"
/>
</button>
</NonAdminAction>
) : (
@ -85,27 +90,25 @@ const DescriptionV1 = ({
};
return (
<div className="schema-description tw-relative">
<Space className="schema-description tw-flex" direction="vertical">
<Space
style={{
display: 'flex',
width: '100%',
justifyContent: 'space-between',
}}>
<Text type="secondary">Description</Text>
<div>{editButton()}</div>
</Space>
<div>
<Card
action={editButton()}
className="tw-relative"
heading="Description">
<div
className="description tw-h-full tw-overflow-y-scroll tw-min-h-12 tw-relative"
data-testid="description"
id="center">
{description?.trim() ? (
<RichTextEditorPreviewer
enableSeeMoreVariant={!removeBlur}
markdown={description}
/>
) : (
<span className="tw-no-description tw-p-2">No description </span>
)}
</div>
</Card>
{description?.trim() ? (
<RichTextEditorPreviewer
enableSeeMoreVariant={!removeBlur}
markdown={description}
/>
) : (
<span className="">No description </span>
)}
{isEdit && (
<ModalWithMarkdownEditor
header={`Edit description for ${entityName}`}
@ -184,7 +187,7 @@ const DescriptionV1 = ({
)}
</div>
) : null}
</div>
</Space>
);
};

View File

@ -0,0 +1,52 @@
/*
* 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.
*/
.glossary-card {
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.12);
}
.m-r-1 {
margin: 1rem 0;
}
.p-lr-3 {
padding-left: 0.75rem;
padding-right: 0.75rem;
}
.left-panel-card {
border: 1px rgb(221, 227, 234) solid;
border-radius: 4px;
box-shadow: 1px 1px 8px rgb(0 0 0 / 6%);
height: 100%;
.header {
padding: 0.5rem 0.75rem;
}
.ant-card-body {
padding: 0px;
}
.ant-card-head {
border-bottom: none;
margin-bottom: 0.5rem;
.ant-card-head-title {
font-weight: 600;
font-size: 1rem;
line-height: 1.5rem;
}
}
}
.right-card {
.ant-card-head-wrapper {
padding: 0.37rem 0.13rem;
}
}

View File

@ -14,6 +14,7 @@
import 'tailwindcss/tailwind.css';
import '../fonts/Inter/Inter-VariableFont_slnt,wght.ttf';
import './antd-master.less';
import './components/glossary.less';
import './components/step.less';
import './fonts.css';
import './myDataDetailsTemp.css';

View File

@ -109,9 +109,11 @@ import IconWorkflows from '../assets/svg/ic-workflows.svg';
import IconChevronDown from '../assets/svg/icon-chevron-down.svg';
import IconCopy from '../assets/svg/icon-copy.svg';
import IconDown from '../assets/svg/icon-down.svg';
import IcEditPrimary from '../assets/svg/icon-edit-primary.svg';
import IconInfoSecondary from '../assets/svg/icon-info.svg';
import IconKey from '../assets/svg/icon-key.svg';
import IconNotNull from '../assets/svg/icon-notnull.svg';
import IconPlusPrimaryOutlined from '../assets/svg/icon-plus-primary-outlined.svg';
import IconRoleGrey from '../assets/svg/icon-role-grey.svg';
import IconTour from '../assets/svg/icon-tour.svg';
import IconUnique from '../assets/svg/icon-unique.svg';
@ -271,6 +273,7 @@ export const Icons = {
TOUR: 'tour',
ICON_PLUS: 'icon-plus',
ICON_PLUS_PRIMERY: 'icon-plus-primary',
ICON_PLUS_PRIMARY_OUTLINED: 'icon-plus-primary-outlined',
ICON_MINUS: 'icon-minus',
TAG: 'icon-tag',
TAG_GREY: 'icon-tag-grey',
@ -333,6 +336,7 @@ export const Icons = {
POLICIES: 'policies',
INFO_SECONDARY: 'info-secondary',
ICON_REMOVE: 'icon-remove',
IC_EDIT_PRIMARY: 'ic-edit-primary',
};
const SVGIcons: FunctionComponent<Props> = ({
@ -971,6 +975,14 @@ const SVGIcons: FunctionComponent<Props> = ({
case Icons.ICON_REMOVE:
IconComponent = IconRemove;
break;
case Icons.IC_EDIT_PRIMARY:
IconComponent = IcEditPrimary;
break;
case Icons.ICON_PLUS_PRIMARY_OUTLINED:
IconComponent = IconPlusPrimaryOutlined;
break;
case Icons.INFO_SECONDARY: