MINOR: add tooltip for icons (#15348)

* added tooltip on floating icons

* localizaion keys

* added tooltip on tables and other icons

* clipboard copy tooltip

* fix unit test

* fix cypress issue

* code smell fix

* changes as per comments and fix cypress issue
This commit is contained in:
Ashish Gupta 2024-02-28 16:41:08 +05:30 committed by GitHub
parent 6a0750eb0c
commit ec503c3afc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
68 changed files with 700 additions and 395 deletions

View File

@ -412,7 +412,7 @@ export const deleteEntity = (
displayName: string displayName: string
) => { ) => {
deletedEntityCommonChecks({ entityType: endPoint, deleted: false }); deletedEntityCommonChecks({ entityType: endPoint, deleted: false });
cy.clickOutside();
cy.get('[data-testid="manage-button"]').click(); cy.get('[data-testid="manage-button"]').click();
cy.get('[data-testid="delete-button"]').scrollIntoView().click(); cy.get('[data-testid="delete-button"]').scrollIntoView().click();
cy.get('[data-testid="delete-modal"]').then(() => { cy.get('[data-testid="delete-modal"]').then(() => {
@ -446,6 +446,7 @@ export const deleteEntity = (
); );
deletedEntityCommonChecks({ entityType: endPoint, deleted: true }); deletedEntityCommonChecks({ entityType: endPoint, deleted: true });
cy.clickOutside();
if (endPoint === EntityType.Table) { if (endPoint === EntityType.Table) {
interceptURL( interceptURL(

View File

@ -184,7 +184,7 @@ describe('Query Entity', { tags: 'DataAssets' }, () => {
cy.get('[data-testid="table_queries"]').click(); cy.get('[data-testid="table_queries"]').click();
verifyResponseStatusCode('@fetchQuery', 200); verifyResponseStatusCode('@fetchQuery', 200);
cy.get('[data-testid="more-option-btn"]').click(); cy.get('[data-testid="query-btn"]').click();
cy.get('[data-menu-id*="edit-query"]').click(); cy.get('[data-menu-id*="edit-query"]').click();
cy.get('.CodeMirror-line') cy.get('.CodeMirror-line')
.click() .click()
@ -218,7 +218,7 @@ describe('Query Entity', { tags: 'DataAssets' }, () => {
cy.get('[data-testid="query-entity-expand-button"]').click(); cy.get('[data-testid="query-entity-expand-button"]').click();
verifyResponseStatusCode('@getQueryById', 200); verifyResponseStatusCode('@getQueryById', 200);
cy.get('[data-testid="more-option-btn"]').click(); cy.get('[data-testid="query-btn"]').click();
cy.get('.ant-dropdown').should('be.visible'); cy.get('.ant-dropdown').should('be.visible');
cy.get('[data-menu-id*="delete-query"]').click(); cy.get('[data-menu-id*="delete-query"]').click();
cy.get('[data-testid="save-button"]').click(); cy.get('[data-testid="save-button"]').click();

View File

@ -361,7 +361,7 @@ describe('Permissions', { tags: 'Settings' }, () => {
interceptURL('GET', '/api/v1/queries?*', 'getQueries'); interceptURL('GET', '/api/v1/queries?*', 'getQueries');
cy.get('[data-testid="table_queries"]').click(); cy.get('[data-testid="table_queries"]').click();
verifyResponseStatusCode('@getQueries', 200); verifyResponseStatusCode('@getQueries', 200);
cy.get('[data-testid="more-option-btn"]').click(); cy.get('[data-testid="query-btn"]').click();
cy.get('[data-menu-id*="edit-query"]').click(); cy.get('[data-menu-id*="edit-query"]').click();
interceptURL('PATCH', '/api/v1/queries/*', 'updateQuery'); interceptURL('PATCH', '/api/v1/queries/*', 'updateQuery');
cy.get('.CodeMirror-line').click().type('updated'); cy.get('.CodeMirror-line').click().type('updated');

View File

@ -381,13 +381,20 @@ export const DataAssetsHeader = ({
)} )}
{editTierPermission && ( {editTierPermission && (
<Button <Tooltip
className="flex-center p-0" title={t('label.edit-entity', {
data-testid="edit-tier" entity: t('label.tier'),
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />} })}>
size="small" <Button
type="text" className="flex-center p-0"
/> data-testid="edit-tier"
icon={
<EditIcon color={DE_ACTIVE_COLOR} width="14px" />
}
size="small"
type="text"
/>
</Tooltip>
)} )}
</Space> </Space>
</TierCard> </TierCard>
@ -462,9 +469,8 @@ export const DataAssetsHeader = ({
)} )}
<Tooltip <Tooltip
open={!isEmpty(copyTooltip)} placement="topRight"
placement="bottomRight" title={copyTooltip ?? t('message.copy-to-clipboard')}>
title={copyTooltip}>
<Button <Button
icon={<Icon component={ShareIcon} />} icon={<Icon component={ShareIcon} />}
onClick={handleShareButtonClick} onClick={handleShareButtonClick}

View File

@ -537,7 +537,11 @@ const DataProductsDetailsPage = ({
placement="bottomRight" placement="bottomRight"
trigger={['click']} trigger={['click']}
onOpenChange={setShowActions}> onOpenChange={setShowActions}>
<Tooltip placement="right"> <Tooltip
placement="topRight"
title={t('label.manage-entity', {
entity: t('label.data-product'),
})}>
<Button <Button
className="domain-manage-dropdown-button tw-px-1.5" className="domain-manage-dropdown-button tw-px-1.5"
data-testid="manage-button" data-testid="manage-button"

View File

@ -11,10 +11,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { Button, Space } from 'antd'; import { Button, Space, Tooltip } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import { startCase, toLower } from 'lodash'; import { startCase, toLower } from 'lodash';
import React, { useCallback, useMemo, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ReactComponent as EditIcon } from '../../../../assets/svg/edit-new.svg'; import { ReactComponent as EditIcon } from '../../../../assets/svg/edit-new.svg';
import { import {
DE_ACTIVE_COLOR, DE_ACTIVE_COLOR,
@ -30,6 +31,7 @@ import { SeverityProps } from './Severity.interface';
import SeverityModal from './SeverityModal.component'; import SeverityModal from './SeverityModal.component';
const Severity = ({ severity, onSubmit }: SeverityProps) => { const Severity = ({ severity, onSubmit }: SeverityProps) => {
const { t } = useTranslation();
const [isEditSeverity, setIsEditSeverity] = useState<boolean>(false); const [isEditSeverity, setIsEditSeverity] = useState<boolean>(false);
const { permissions } = usePermissionProvider(); const { permissions } = usePermissionProvider();
const hasEditPermission = useMemo(() => { const hasEditPermission = useMemo(() => {
@ -63,12 +65,17 @@ const Severity = ({ severity, onSubmit }: SeverityProps) => {
NO_DATA_PLACEHOLDER NO_DATA_PLACEHOLDER
)} )}
{onSubmit && hasEditPermission && ( {onSubmit && hasEditPermission && (
<Button <Tooltip
data-testid="edit-description-icon" title={t('label.edit-entity', {
icon={<EditIcon {...ICON_DIMENSION} color={DE_ACTIVE_COLOR} />} entity: t('label.severity'),
type="text" })}>
onClick={onEditSeverity} <Button
/> data-testid="edit-severity-icon"
icon={<EditIcon {...ICON_DIMENSION} color={DE_ACTIVE_COLOR} />}
type="text"
onClick={onEditSeverity}
/>
</Tooltip>
)} )}
</Space> </Space>

View File

@ -57,9 +57,7 @@ describe('Severity', () => {
it('Should show edit icon if onSubmit is provided and edit permission is true', async () => { it('Should show edit icon if onSubmit is provided and edit permission is true', async () => {
render(<Severity onSubmit={jest.fn()} />); render(<Severity onSubmit={jest.fn()} />);
expect( expect(await screen.findByTestId('edit-severity-icon')).toBeInTheDocument();
await screen.findByTestId('edit-description-icon')
).toBeInTheDocument();
}); });
it('Should not show edit icon if edit permission is false', async () => { it('Should not show edit icon if edit permission is false', async () => {
@ -67,17 +65,15 @@ describe('Severity', () => {
const { container } = render(<Severity onSubmit={jest.fn()} />); const { container } = render(<Severity onSubmit={jest.fn()} />);
expect( expect(
queryByTestId(container, 'edit-description-icon') queryByTestId(container, 'edit-severity-icon')
).not.toBeInTheDocument(); ).not.toBeInTheDocument();
}); });
it('Should render modal onClick of edit icon', async () => { it('Should render modal onClick of edit icon', async () => {
render(<Severity onSubmit={jest.fn()} />); render(<Severity onSubmit={jest.fn()} />);
const editIcon = await screen.findByTestId('edit-description-icon'); const editIcon = await screen.findByTestId('edit-severity-icon');
expect( expect(await screen.findByTestId('edit-severity-icon')).toBeInTheDocument();
await screen.findByTestId('edit-description-icon')
).toBeInTheDocument();
await act(async () => { await act(async () => {
fireEvent.click(editIcon); fireEvent.click(editIcon);
@ -89,11 +85,9 @@ describe('Severity', () => {
it('Should call onSubmit function onClick of submit', async () => { it('Should call onSubmit function onClick of submit', async () => {
const mockSubmit = jest.fn(); const mockSubmit = jest.fn();
render(<Severity onSubmit={mockSubmit} />); render(<Severity onSubmit={mockSubmit} />);
const editIcon = await screen.findByTestId('edit-description-icon'); const editIcon = await screen.findByTestId('edit-severity-icon');
expect( expect(await screen.findByTestId('edit-severity-icon')).toBeInTheDocument();
await screen.findByTestId('edit-description-icon')
).toBeInTheDocument();
await act(async () => { await act(async () => {
fireEvent.click(editIcon); fireEvent.click(editIcon);

View File

@ -12,7 +12,7 @@
*/ */
import Icon from '@ant-design/icons/lib/components/Icon'; import Icon from '@ant-design/icons/lib/components/Icon';
import { Col, Divider, Row, Space, Typography } from 'antd'; import { Col, Divider, Row, Space, Tooltip, Typography } from 'antd';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { compare } from 'fast-json-patch'; import { compare } from 'fast-json-patch';
import { isEmpty, isUndefined } from 'lodash'; import { isEmpty, isUndefined } from 'lodash';
@ -138,12 +138,17 @@ const TestCaseResultTab = ({
{t('label.parameter-plural')} {t('label.parameter-plural')}
</Typography.Text> </Typography.Text>
{hasEditPermission && Boolean(withoutSqlParams.length) && ( {hasEditPermission && Boolean(withoutSqlParams.length) && (
<Icon <Tooltip
component={EditIcon} title={t('label.edit-entity', {
data-testid="edit-parameter-icon" entity: t('label.parameter'),
style={{ color: DE_ACTIVE_COLOR, ...ICON_DIMENSION }} })}>
onClick={() => setIsParameterEdit(true)} <Icon
/> component={EditIcon}
data-testid="edit-parameter-icon"
style={{ color: DE_ACTIVE_COLOR, ...ICON_DIMENSION }}
onClick={() => setIsParameterEdit(true)}
/>
</Tooltip>
)} )}
</Space> </Space>

View File

@ -273,7 +273,6 @@ const DataQualityTab: React.FC<DataQualityTabProps> = ({
return ( return (
<Row align="middle"> <Row align="middle">
<Tooltip <Tooltip
placement="bottomRight"
title={ title={
testCaseEditPermission testCaseEditPermission
? t('label.edit') ? t('label.edit')
@ -296,7 +295,6 @@ const DataQualityTab: React.FC<DataQualityTabProps> = ({
{removeFromTestSuite ? ( {removeFromTestSuite ? (
<Tooltip <Tooltip
placement="bottomLeft"
title={ title={
testCaseDeletePermission testCaseDeletePermission
? t('label.remove') ? t('label.remove')
@ -318,7 +316,6 @@ const DataQualityTab: React.FC<DataQualityTabProps> = ({
</Tooltip> </Tooltip>
) : ( ) : (
<Tooltip <Tooltip
placement="bottomLeft"
title={ title={
testCaseDeletePermission testCaseDeletePermission
? t('label.delete') ? t('label.delete')

View File

@ -10,7 +10,16 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Alert, Button, Form, FormProps, Input, Modal, Space } from 'antd'; import {
Alert,
Button,
Form,
FormProps,
Input,
Modal,
Space,
Tooltip,
} from 'antd';
import { useForm } from 'antd/lib/form/Form'; import { useForm } from 'antd/lib/form/Form';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
@ -62,14 +71,19 @@ const RetentionPeriod = ({
/> />
{permissions?.EditAll && ( {permissions?.EditAll && (
<Button <Tooltip
className="flex-center p-0" title={t('label.edit-entity', {
data-testid="edit-retention-period-button" entity: t('label.retention-period'),
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />} })}>
size="small" <Button
type="text" className="flex-center p-0"
onClick={() => setIsEdit(true)} data-testid="edit-retention-period-button"
/> icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
onClick={() => setIsEdit(true)}
/>
</Tooltip>
)} )}
</Space> </Space>

View File

@ -246,7 +246,11 @@ const SampleDataTable = ({
placement="bottomRight" placement="bottomRight"
trigger={['click']} trigger={['click']}
onOpenChange={setShowActions}> onOpenChange={setShowActions}>
<Tooltip placement="right"> <Tooltip
placement="topLeft"
title={t('label.manage-entity', {
entity: t('label.sample-data'),
})}>
<Button <Button
className="flex-center px-1.5" className="flex-center px-1.5"
data-testid="sample-data-manage-button" data-testid="sample-data-manage-button"

View File

@ -349,20 +349,26 @@ const SchemaTable = ({
) : null} ) : null}
{(tablePermissions?.EditAll || {(tablePermissions?.EditAll ||
tablePermissions?.EditDisplayName) && ( tablePermissions?.EditDisplayName) && (
<Button <Tooltip
className="cursor-pointer hover-cell-icon w-fit-content" placement="right"
data-testid="edit-displayName-button" title={t('label.edit-entity', {
style={{ entity: t('label.display-name'),
color: DE_ACTIVE_COLOR, })}>
padding: 0, <Button
border: 'none', className="cursor-pointer hover-cell-icon w-fit-content"
background: 'transparent', data-testid="edit-displayName-button"
}} style={{
onClick={() => handleEditDisplayNameClick(record)}> color: DE_ACTIVE_COLOR,
<IconEdit padding: 0,
style={{ color: DE_ACTIVE_COLOR, ...ICON_DIMENSION }} border: 'none',
/> background: 'transparent',
</Button> }}
onClick={() => handleEditDisplayNameClick(record)}>
<IconEdit
style={{ color: DE_ACTIVE_COLOR, ...ICON_DIMENSION }}
/>
</Button>
</Tooltip>
)} )}
</div> </div>
); );

View File

@ -11,7 +11,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Button, Space } from 'antd'; import { Button, Space, Tooltip } from 'antd';
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ReactComponent as EditIcon } from '../../../assets/svg/edit-new.svg'; import { ReactComponent as EditIcon } from '../../../assets/svg/edit-new.svg';
@ -51,18 +51,25 @@ const TableDescription = ({
{!isReadOnly ? ( {!isReadOnly ? (
<Space align="baseline" size="middle"> <Space align="baseline" size="middle">
{hasEditPermission && ( {hasEditPermission && (
<Button <Tooltip
className="cursor-pointer hover-cell-icon" title={t('label.edit-entity', {
data-testid="edit-button" entity: t('label.description'),
style={{ })}>
color: DE_ACTIVE_COLOR, <Button
padding: 0, className="cursor-pointer hover-cell-icon"
border: 'none', data-testid="edit-button"
background: 'transparent', style={{
}} color: DE_ACTIVE_COLOR,
onClick={onClick}> padding: 0,
<EditIcon style={{ color: DE_ACTIVE_COLOR, ...ICON_DIMENSION }} /> border: 'none',
</Button> background: 'transparent',
}}
onClick={onClick}>
<EditIcon
style={{ color: DE_ACTIVE_COLOR, ...ICON_DIMENSION }}
/>
</Button>
</Tooltip>
)} )}
<EntityTasks <EntityTasks

View File

@ -189,13 +189,18 @@ const QueryCardExtraOption = ({
}} }}
placement="bottomRight" placement="bottomRight"
trigger={['click']}> trigger={['click']}>
<Button <Tooltip
className="flex-center button-size" title={t('label.manage-entity', {
data-testid="more-option-btn" entity: t('label.query'),
icon={<IconDropdown />} })}>
size="small" <Button
type="text" className="flex-center button-size"
/> data-testid="query-btn"
icon={<IconDropdown />}
size="small"
type="text"
/>
</Tooltip>
</Dropdown> </Dropdown>
<ConfirmationModal <ConfirmationModal
bodyText={t('message.delete-entity-permanently', { bodyText={t('message.delete-entity-permanently', {

View File

@ -54,7 +54,7 @@ describe('QueryCardExtraOption component test', () => {
await screen.findByTestId('extra-option-container') await screen.findByTestId('extra-option-container')
).toBeInTheDocument(); ).toBeInTheDocument();
expect(await screen.findByTestId('query-line')).toBeInTheDocument(); expect(await screen.findByTestId('query-line')).toBeInTheDocument();
expect(await screen.findByTestId('more-option-btn')).toBeInTheDocument(); expect(await screen.findByTestId('query-btn')).toBeInTheDocument();
expect(await screen.findByTestId('up-vote-btn')).toBeInTheDocument(); expect(await screen.findByTestId('up-vote-btn')).toBeInTheDocument();
expect(await screen.findByTestId('down-vote-btn')).toBeInTheDocument(); expect(await screen.findByTestId('down-vote-btn')).toBeInTheDocument();
}); });
@ -183,7 +183,7 @@ describe('QueryCardExtraOption component test', () => {
it('Dropdown should show 2 menu options', async () => { it('Dropdown should show 2 menu options', async () => {
render(<QueryCardExtraOption {...mockProps} />); render(<QueryCardExtraOption {...mockProps} />);
const moreOptionBtn = await screen.findByTestId('more-option-btn'); const moreOptionBtn = await screen.findByTestId('query-btn');
expect(moreOptionBtn).toBeInTheDocument(); expect(moreOptionBtn).toBeInTheDocument();
@ -209,7 +209,7 @@ describe('QueryCardExtraOption component test', () => {
/> />
); );
const moreOptionBtn = await screen.findByTestId('more-option-btn'); const moreOptionBtn = await screen.findByTestId('query-btn');
expect(moreOptionBtn).toBeInTheDocument(); expect(moreOptionBtn).toBeInTheDocument();
@ -246,7 +246,7 @@ describe('QueryCardExtraOption component test', () => {
/> />
); );
const moreOptionBtn = await screen.findByTestId('more-option-btn'); const moreOptionBtn = await screen.findByTestId('query-btn');
expect(moreOptionBtn).toBeInTheDocument(); expect(moreOptionBtn).toBeInTheDocument();
@ -267,7 +267,7 @@ describe('QueryCardExtraOption component test', () => {
it('If there is no permission, Edit option should be disabled', async () => { it('If there is no permission, Edit option should be disabled', async () => {
render(<QueryCardExtraOption {...mockProps} />); render(<QueryCardExtraOption {...mockProps} />);
const moreOptionBtn = await screen.findByTestId('more-option-btn'); const moreOptionBtn = await screen.findByTestId('query-btn');
expect(moreOptionBtn).toBeInTheDocument(); expect(moreOptionBtn).toBeInTheDocument();
@ -284,7 +284,7 @@ describe('QueryCardExtraOption component test', () => {
it('If there is no permission, Delete option should be disabled', async () => { it('If there is no permission, Delete option should be disabled', async () => {
render(<QueryCardExtraOption {...mockProps} />); render(<QueryCardExtraOption {...mockProps} />);
const moreOptionBtn = await screen.findByTestId('more-option-btn'); const moreOptionBtn = await screen.findByTestId('query-btn');
expect(moreOptionBtn).toBeInTheDocument(); expect(moreOptionBtn).toBeInTheDocument();

View File

@ -12,7 +12,7 @@
*/ */
import Icon from '@ant-design/icons'; import Icon from '@ant-design/icons';
import { Button, Col, Drawer, Row, Space, Typography } from 'antd'; import { Button, Col, Drawer, Row, Space, Tooltip, Typography } from 'antd';
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@ -93,13 +93,18 @@ const TableQueryRightPanel = ({
hasPermission={EditAll || EditOwner} hasPermission={EditAll || EditOwner}
owner={query.owner} owner={query.owner}
onUpdate={handleUpdateOwner}> onUpdate={handleUpdateOwner}>
<Button <Tooltip
className="cursor-pointer flex-center" title={t('label.edit-entity', {
data-testid="edit-owner" entity: t('label.owner-lowercase'),
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />} })}>
size="small" <Button
type="text" className="cursor-pointer flex-center"
/> data-testid="edit-owner"
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
/>
</Tooltip>
</UserTeamSelectableList> </UserTeamSelectableList>
)} )}
</Space> </Space>
@ -114,14 +119,19 @@ const TableQueryRightPanel = ({
</Typography.Text> </Typography.Text>
{(EditDescription || EditAll) && ( {(EditDescription || EditAll) && (
<Button <Tooltip
className="flex-center p-0" title={t('label.edit-entity', {
data-testid="edit-description-btn" entity: t('label.description'),
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />} })}>
size="small" <Button
type="text" className="flex-center p-0"
onClick={() => setIsEditDescription(true)} data-testid="edit-description-btn"
/> icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
onClick={() => setIsEditDescription(true)}
/>
</Tooltip>
)} )}
</Space> </Space>
<Description <Description

View File

@ -598,7 +598,11 @@ const DomainDetailsPage = ({
placement="bottomRight" placement="bottomRight"
trigger={['click']} trigger={['click']}
onOpenChange={setShowActions}> onOpenChange={setShowActions}>
<Tooltip placement="right"> <Tooltip
placement="topRight"
title={t('label.manage-entity', {
entity: t('label.domain'),
})}>
<Button <Button
className="domain-manage-dropdown-button tw-px-1.5" className="domain-manage-dropdown-button tw-px-1.5"
data-testid="manage-button" data-testid="manage-button"

View File

@ -10,7 +10,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Button, Col, Row, Space, Typography } from 'antd'; import { Button, Col, Row, Space, Tooltip, Typography } from 'antd';
import { cloneDeep, includes, isEqual } from 'lodash'; import { cloneDeep, includes, isEqual } from 'lodash';
import React, { useMemo, useState } from 'react'; import React, { useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -193,13 +193,18 @@ const DocumentationTab = ({
hasPermission hasPermission
owner={domain.owner} owner={domain.owner}
onUpdate={handleUpdatedOwner}> onUpdate={handleUpdatedOwner}>
<Button <Tooltip
className="cursor-pointer flex-center m-l-xss" title={t('label.edit-entity', {
data-testid="edit-owner" entity: t('label.owner'),
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />} })}>
size="small" <Button
type="text" className="cursor-pointer flex-center m-l-xss"
/> data-testid="edit-owner"
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
/>
</Tooltip>
</UserTeamSelectableList> </UserTeamSelectableList>
)} )}
</div> </div>
@ -244,13 +249,18 @@ const DocumentationTab = ({
popoverProps={{ placement: 'topLeft' }} popoverProps={{ placement: 'topLeft' }}
selectedUsers={domain.experts ?? []} selectedUsers={domain.experts ?? []}
onUpdate={handleExpertsUpdate}> onUpdate={handleExpertsUpdate}>
<Button <Tooltip
className="cursor-pointer flex-center m-l-xss" title={t('label.edit-entity', {
data-testid="edit-expert-button" entity: t('label.expert-plural'),
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />} })}>
size="small" <Button
type="text" className="cursor-pointer flex-center m-l-xss"
/> data-testid="edit-expert-button"
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
/>
</Tooltip>
</UserSelectableList> </UserSelectableList>
)} )}
</div> </div>
@ -295,14 +305,19 @@ const DocumentationTab = ({
</Typography.Text> </Typography.Text>
{editAllPermission && (domain as Domain).domainType && ( {editAllPermission && (domain as Domain).domainType && (
<Button <Tooltip
className="cursor-pointer flex-center m-l-xss" title={t('label.edit-entity', {
data-testid="edit-domainType-button" entity: t('label.domain-type'),
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />} })}>
size="small" <Button
type="text" className="cursor-pointer flex-center m-l-xss"
onClick={() => setEditDomainType(true)} data-testid="edit-domainType-button"
/> icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
onClick={() => setEditDomainType(true)}
/>
</Tooltip>
)} )}
</div> </div>
{!editDomainType && ( {!editDomainType && (

View File

@ -311,23 +311,29 @@ const CustomControls: FC<ControlProps> = ({
</Tooltip> </Tooltip>
{!deleted && ( {!deleted && (
<Button <Tooltip
className={classNames( placement="topRight"
'custom-control-edit-button rounded-full', title={t('label.edit-entity', {
{ entity: t('label.lineage'),
active: isEditMode, })}>
<Button
className={classNames(
'custom-control-edit-button rounded-full',
{
active: isEditMode,
}
)}
data-testid="edit-lineage"
disabled={!hasEditAccess}
icon={getLoadingStatusValue(editIcon, loading, status)}
title={
hasEditAccess
? t('label.edit-entity', { entity: t('label.lineage') })
: NO_PERMISSION_FOR_ACTION
} }
)} onClick={onLineageEditClick}
data-testid="edit-lineage" />
disabled={!hasEditAccess} </Tooltip>
icon={getLoadingStatusValue(editIcon, loading, status)}
title={
hasEditAccess
? t('label.edit-entity', { entity: t('label.lineage') })
: NO_PERMISSION_FOR_ACTION
}
onClick={onLineageEditClick}
/>
)} )}
</Space> </Space>
</Col> </Col>

View File

@ -10,7 +10,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Button, Col, Row, Space, Typography } from 'antd'; import { Button, Col, Row, Space, Tooltip, Typography } from 'antd';
import { t } from 'i18next'; import { t } from 'i18next';
import { cloneDeep, includes, isEmpty, isEqual } from 'lodash'; import { cloneDeep, includes, isEmpty, isEqual } from 'lodash';
import React, { ReactNode, useCallback, useMemo } from 'react'; import React, { ReactNode, useCallback, useMemo } from 'react';
@ -224,13 +224,18 @@ const GlossaryDetailsRightPanel = ({
hasPermission={permissions.EditOwner || permissions.EditAll} hasPermission={permissions.EditOwner || permissions.EditAll}
owner={selectedData.owner} owner={selectedData.owner}
onUpdate={handleUpdatedOwner}> onUpdate={handleUpdatedOwner}>
<Button <Tooltip
className="cursor-pointer flex-center m-l-xss" title={t('label.edit-entity', {
data-testid="edit-owner" entity: t('label.owner'),
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />} })}>
size="small" <Button
type="text" className="cursor-pointer flex-center m-l-xss"
/> data-testid="edit-owner"
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
/>
</Tooltip>
</UserTeamSelectableList> </UserTeamSelectableList>
)} )}
</div> </div>
@ -272,13 +277,18 @@ const GlossaryDetailsRightPanel = ({
popoverProps={{ placement: 'topLeft' }} popoverProps={{ placement: 'topLeft' }}
selectedUsers={selectedData.reviewers ?? []} selectedUsers={selectedData.reviewers ?? []}
onUpdate={handleReviewerSave}> onUpdate={handleReviewerSave}>
<Button <Tooltip
className="cursor-pointer flex-center m-l-xss" title={t('label.edit-entity', {
data-testid="edit-reviewer-button" entity: t('label.reviewer-plural'),
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />} })}>
size="small" <Button
type="text" className="cursor-pointer flex-center m-l-xss"
/> data-testid="edit-reviewer-button"
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
/>
</Tooltip>
</UserSelectableList> </UserSelectableList>
)} )}
</div> </div>

View File

@ -555,7 +555,13 @@ const GlossaryHeader = ({
placement="bottomRight" placement="bottomRight"
trigger={['click']} trigger={['click']}
onOpenChange={setShowActions}> onOpenChange={setShowActions}>
<Tooltip placement="right"> <Tooltip
placement="topRight"
title={t('label.manage-entity', {
entity: isGlossary
? t('label.glossary')
: t('label.glossary-term'),
})}>
<Button <Button
className="glossary-manage-dropdown-button tw-px-1.5" className="glossary-manage-dropdown-button tw-px-1.5"
data-testid="manage-button" data-testid="manage-button"

View File

@ -528,13 +528,18 @@ const AssetsTabs = forwardRef(
overlayStyle={{ width: '350px' }} overlayStyle={{ width: '350px' }}
placement="bottomRight" placement="bottomRight"
trigger={['click']}> trigger={['click']}>
<Button <Tooltip
className={classNames('flex-center px-1.5')} placement="topRight"
data-testid={`manage-button-${_source.fullyQualifiedName}`} title={t('label.manage-entity', {
title="Manage" entity: t('label.asset'),
type="text"> })}>
<IconDropdown className="anticon self-center manage-dropdown-icon" /> <Button
</Button> className={classNames('flex-center px-1.5')}
data-testid={`manage-button-${_source.fullyQualifiedName}`}
type="text">
<IconDropdown className="anticon self-center manage-dropdown-icon" />
</Button>
</Tooltip>
</Dropdown> </Dropdown>
) : null ) : null
} }

View File

@ -194,7 +194,9 @@ const GlossaryTermReferences = ({
<Tooltip <Tooltip
title={ title={
permissions.EditAll permissions.EditAll
? t('label.edit') ? t('label.edit-entity', {
entity: t('label.reference-plural'),
})
: NO_PERMISSION_FOR_ACTION : NO_PERMISSION_FOR_ACTION
}> }>
<Button <Button

View File

@ -186,9 +186,13 @@ const GlossaryTermSynonyms = ({
</Typography.Text> </Typography.Text>
{permissions.EditAll && synonyms.length > 0 && isViewMode && ( {permissions.EditAll && synonyms.length > 0 && isViewMode && (
<Tooltip <Tooltip
placement="bottomLeft" placement="top"
title={ title={
permissions.EditAll ? t('label.edit') : NO_PERMISSION_FOR_ACTION permissions.EditAll
? t('label.edit-entity', {
entity: t('label.synonym-plural'),
})
: NO_PERMISSION_FOR_ACTION
}> }>
<Button <Button
className="cursor-pointer flex-center m-l-xss" className="cursor-pointer flex-center m-l-xss"

View File

@ -282,7 +282,11 @@ const RelatedTerms = ({
{permissions.EditAll && selectedOption.length > 0 && ( {permissions.EditAll && selectedOption.length > 0 && (
<Tooltip <Tooltip
title={ title={
permissions.EditAll ? t('label.edit') : NO_PERMISSION_FOR_ACTION permissions.EditAll
? t('label.edit-entity', {
entity: t('label.related-term-plural'),
})
: NO_PERMISSION_FOR_ACTION
}> }>
<Button <Button
className="cursor-pointer flex-center m-l-xss" className="cursor-pointer flex-center m-l-xss"

View File

@ -10,7 +10,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Button, Popover, Space, Typography } from 'antd'; import { Button, Popover, Space, Tooltip, Typography } from 'antd';
import { t } from 'i18next'; import { t } from 'i18next';
import React, { useCallback, useState } from 'react'; import React, { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -135,13 +135,18 @@ export const PersonaSelectableList = ({
onOpenChange={setPopupVisible} onOpenChange={setPopupVisible}
{...popoverProps}> {...popoverProps}>
{children ?? ( {children ?? (
<Button <Tooltip
className="p-0 flex-center" title={t('label.edit-entity', {
data-testid="add-user" entity: t('label.persona'),
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />} })}>
size="small" <Button
type="text" className="p-0 flex-center"
/> data-testid="edit-persona"
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
/>
</Tooltip>
)} )}
</Popover> </Popover>
); );

View File

@ -22,6 +22,7 @@ import {
Row, Row,
Select, Select,
Space, Space,
Tooltip,
} from 'antd'; } from 'antd';
import { CookieStorage } from 'cookie-storage'; import { CookieStorage } from 'cookie-storage';
import i18next from 'i18next'; import i18next from 'i18next';
@ -496,13 +497,15 @@ const NavBar = ({
placement="bottomRight" placement="bottomRight"
trigger={['click']} trigger={['click']}
onOpenChange={handleBellClick}> onOpenChange={handleBellClick}>
<Badge dot={hasTaskNotification || hasMentionNotification}> <Tooltip placement="top" title={t('label.notification-plural')}>
<Icon <Badge dot={hasTaskNotification || hasMentionNotification}>
className="align-middle" <Icon
component={IconBell} className="align-middle"
style={{ fontSize: '24px' }} component={IconBell}
/> style={{ fontSize: '24px' }}
</Badge> />
</Badge>
</Tooltip>
</Dropdown> </Dropdown>
<Dropdown <Dropdown
@ -510,11 +513,13 @@ const NavBar = ({
overlayStyle={{ width: 175 }} overlayStyle={{ width: 175 }}
placement="bottomRight" placement="bottomRight"
trigger={['click']}> trigger={['click']}>
<Icon <Tooltip placement="top" title={t('label.need-help')}>
className="align-middle" <Icon
component={Help} className="align-middle"
style={{ fontSize: '24px' }} component={Help}
/> style={{ fontSize: '24px' }}
/>
</Tooltip>
</Dropdown> </Dropdown>
<UserProfileIcon /> <UserProfileIcon />

View File

@ -453,7 +453,11 @@ const AppDetails = () => {
placement="bottomRight" placement="bottomRight"
trigger={['click']} trigger={['click']}
onOpenChange={setShowActions}> onOpenChange={setShowActions}>
<Tooltip placement="right"> <Tooltip
placement="topRight"
title={t('label.manage-entity', {
entity: t('label.application'),
})}>
<Button <Button
className="glossary-manage-dropdown-button p-x-xs" className="glossary-manage-dropdown-button p-x-xs"
data-testid="manage-button" data-testid="manage-button"

View File

@ -12,7 +12,16 @@
*/ */
import { CheckOutlined, CloseOutlined } from '@ant-design/icons'; import { CheckOutlined, CloseOutlined } from '@ant-design/icons';
import { Button, Card, Col, Input, Row, Space, Typography } from 'antd'; import {
Button,
Card,
Col,
Input,
Row,
Space,
Tooltip,
Typography,
} from 'antd';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { toLower } from 'lodash'; import { toLower } from 'lodash';
import React, { FC, useEffect, useMemo, useState } from 'react'; import React, { FC, useEffect, useMemo, useState } from 'react';
@ -157,13 +166,18 @@ const BotDetails: FC<BotsDetailProps> = ({
</Typography.Text> </Typography.Text>
)} )}
{(displayNamePermission || editAllPermission) && ( {(displayNamePermission || editAllPermission) && (
<Button <Tooltip
className="p-0" title={t('label.edit-entity', {
data-testid="edit-displayName" entity: t('label.display-name'),
icon={<EditIcon width={16} />} })}>
type="text" <Button
onClick={() => setIsDisplayNameEdit(true)} className="p-0"
/> data-testid="edit-displayName"
icon={<EditIcon width={16} />}
type="text"
onClick={() => setIsDisplayNameEdit(true)}
/>
</Tooltip>
)} )}
</Space> </Space>
)} )}

View File

@ -118,7 +118,14 @@ export const CustomPropertyTable: FC<CustomPropertyTableProp> = ({
key: 'actions', key: 'actions',
render: (_, record) => ( render: (_, record) => (
<Space align="center" size={14}> <Space align="center" size={14}>
<Tooltip title={!hasAccess && NO_PERMISSION_FOR_ACTION}> <Tooltip
title={
hasAccess
? t('label.edit-entity', {
entity: t('label.property'),
})
: NO_PERMISSION_FOR_ACTION
}>
<Button <Button
className="cursor-pointer p-0" className="cursor-pointer p-0"
data-testid="edit-button" data-testid="edit-button"
@ -132,7 +139,14 @@ export const CustomPropertyTable: FC<CustomPropertyTableProp> = ({
<IconEdit name={t('label.edit')} width={16} /> <IconEdit name={t('label.edit')} width={16} />
</Button> </Button>
</Tooltip> </Tooltip>
<Tooltip title={!hasAccess && NO_PERMISSION_FOR_ACTION}> <Tooltip
title={
hasAccess
? t('label.delete-entity', {
entity: t('label.property'),
})
: NO_PERMISSION_FOR_ACTION
}>
<Button <Button
className="cursor-pointer p-0" className="cursor-pointer p-0"
data-testid="delete-button" data-testid="delete-button"

View File

@ -91,7 +91,7 @@ const ListEntities = ({
render: (_, record) => { render: (_, record) => {
return ( return (
<Tooltip <Tooltip
placement="bottomRight" placement="left"
title={hasAccess ? t('label.remove') : NO_PERMISSION_FOR_ACTION}> title={hasAccess ? t('label.remove') : NO_PERMISSION_FOR_ACTION}>
<Button <Button
data-testid={`remove-action-${getEntityName(record)}`} data-testid={`remove-action-${getEntityName(record)}`}

View File

@ -1138,13 +1138,18 @@ const TeamDetailsV1 = ({
{t('label.description')} {t('label.description')}
</Typography.Text> </Typography.Text>
{editDescriptionPermission && ( {editDescriptionPermission && (
<EditIcon <Tooltip
className="cursor-pointer align-middle" title={t('label.edit-entity', {
color={DE_ACTIVE_COLOR} entity: t('label.description'),
data-testid="edit-description" })}>
{...ICON_DIMENSION} <EditIcon
onClick={() => descriptionHandler(true)} className="cursor-pointer align-middle"
/> color={DE_ACTIVE_COLOR}
data-testid="edit-description"
{...ICON_DIMENSION}
onClick={() => descriptionHandler(true)}
/>
</Tooltip>
)} )}
</Space> </Space>
}> }>

View File

@ -189,7 +189,6 @@ const TeamsInfo = ({
</Typography.Text> </Typography.Text>
{hasEditPermission && ( {hasEditPermission && (
<Tooltip <Tooltip
placement="right"
title={ title={
hasEditPermission hasEditPermission
? t('label.edit-entity', { ? t('label.edit-entity', {
@ -241,23 +240,28 @@ const TeamsInfo = ({
</Typography.Text> </Typography.Text>
{hasEditPermission && ( {hasEditPermission && (
<Icon <Tooltip
className={classNames('vertical-middle m-l-xs', { title={t('label.edit-entity', {
'opacity-50': isGroupType, entity: t('label.team-type'),
})} })}>
data-testid="edit-team-type-icon" <Icon
title={ className={classNames('vertical-middle m-l-xs', {
isGroupType 'opacity-50': isGroupType,
? t('message.group-team-type-change-message') })}
: t('label.edit-entity', { data-testid="edit-team-type-icon"
entity: t('label.team-type'), title={
}) isGroupType
} ? t('message.group-team-type-change-message')
onClick={ : t('label.edit-entity', {
isGroupType ? undefined : () => setShowTypeSelector(true) entity: t('label.team-type'),
}> })
<EditIcon /> }
</Icon> onClick={
isGroupType ? undefined : () => setShowTypeSelector(true)
}>
<EditIcon />
</Icon>
</Tooltip>
)} )}
</> </>
)} )}

View File

@ -10,7 +10,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Form, Input, Modal, Select, Space, Typography } from 'antd'; import { Form, Input, Modal, Select, Space, Tooltip, Typography } from 'antd';
import { useForm } from 'antd/lib/form/Form'; import { useForm } from 'antd/lib/form/Form';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
@ -76,13 +76,18 @@ const TeamsSubscription = ({
data-testid="subscription-no-data"> data-testid="subscription-no-data">
{t('label.none')} {t('label.none')}
</Typography.Text> </Typography.Text>
<EditIcon <Tooltip
className="cursor-pointer" title={t('label.edit-entity', {
color={DE_ACTIVE_COLOR} entity: t('label.subscription'),
data-testid="edit-team-subscription" })}>
width={14} <EditIcon
onClick={() => setEditSubscription(true)} className="cursor-pointer"
/> color={DE_ACTIVE_COLOR}
data-testid="edit-team-subscription"
width={14}
onClick={() => setEditSubscription(true)}
/>
</Tooltip>
</div> </div>
); );
} }
@ -136,13 +141,18 @@ const TeamsSubscription = ({
{subscriptionRenderElement} {subscriptionRenderElement}
{!editSubscription && !isEmpty(subscription) && hasEditPermission && ( {!editSubscription && !isEmpty(subscription) && hasEditPermission && (
<EditIcon <Tooltip
className="cursor-pointer align-middle" title={t('label.edit-entity', {
color={DE_ACTIVE_COLOR} entity: t('label.subscription'),
data-testid="edit-team-subscription" })}>
{...ICON_DIMENSION} <EditIcon
onClick={() => setEditSubscription(true)} className="cursor-pointer align-middle"
/> color={DE_ACTIVE_COLOR}
data-testid="edit-team-subscription"
{...ICON_DIMENSION}
onClick={() => setEditSubscription(true)}
/>
</Tooltip>
)} )}
{editSubscription && ( {editSubscription && (

View File

@ -191,7 +191,7 @@ export const UserTab = ({
className="w-full justify-center remove-icon" className="w-full justify-center remove-icon"
size={8}> size={8}>
<Tooltip <Tooltip
placement="bottomRight" placement="left"
title={ title={
permission.EditAll permission.EditAll
? t('label.remove') ? t('label.remove')

View File

@ -11,7 +11,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Button, Divider, Input, Space, Typography } from 'antd'; import { Button, Divider, Input, Space, Tooltip, Typography } from 'antd';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import React, { useCallback, useMemo, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -142,13 +142,18 @@ const UserProfileDetails = ({
: getEntityName(userData)} : getEntityName(userData)}
</Typography.Text> </Typography.Text>
{hasEditPermission && ( {hasEditPermission && (
<EditIcon <Tooltip
className="cursor-pointer align-middle" title={t('label.edit-entity', {
color={DE_ACTIVE_COLOR} entity: t('label.display-name'),
data-testid="edit-displayName" })}>
{...ICON_DIMENSION} <EditIcon
onClick={() => setIsDisplayNameEdit(true)} className="cursor-pointer align-middle"
/> color={DE_ACTIVE_COLOR}
data-testid="edit-displayName"
{...ICON_DIMENSION}
onClick={() => setIsDisplayNameEdit(true)}
/>
</Tooltip>
)} )}
</Space> </Space>
), ),

View File

@ -11,7 +11,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Card, Select, Space, Typography } from 'antd'; import { Card, Select, Space, Tooltip, Typography } from 'antd';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { isEmpty, toLower } from 'lodash'; import { isEmpty, toLower } from 'lodash';
import React, { useEffect, useMemo, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
@ -153,13 +153,18 @@ const UserProfileRoles = ({
{t('label.role-plural')} {t('label.role-plural')}
</Typography.Text> </Typography.Text>
{!isRolesEdit && isAdminUser && ( {!isRolesEdit && isAdminUser && (
<EditIcon <Tooltip
className="cursor-pointer align-middle" title={t('label.edit-entity', {
color={DE_ACTIVE_COLOR} entity: t('label.role-plural'),
data-testid="edit-roles-button" })}>
{...ICON_DIMENSION} <EditIcon
onClick={() => setIsRolesEdit(true)} className="cursor-pointer align-middle"
/> color={DE_ACTIVE_COLOR}
data-testid="edit-roles-button"
{...ICON_DIMENSION}
onClick={() => setIsRolesEdit(true)}
/>
</Tooltip>
)} )}
</Space> </Space>
}> }>

View File

@ -11,7 +11,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Card, Space, Typography } from 'antd'; import { Card, Space, Tooltip, Typography } from 'antd';
import React, { useEffect, useMemo, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ReactComponent as EditIcon } from '../../../../../assets/svg/edit-new.svg'; import { ReactComponent as EditIcon } from '../../../../../assets/svg/edit-new.svg';
@ -75,13 +75,18 @@ const UserProfileTeams = ({
</Typography.Text> </Typography.Text>
{!isTeamsEdit && isAdminUser && ( {!isTeamsEdit && isAdminUser && (
<EditIcon <Tooltip
className="cursor-pointer align-middle" title={t('label.edit-entity', {
color={DE_ACTIVE_COLOR} entity: t('label.team-plural'),
data-testid="edit-teams-button" })}>
{...ICON_DIMENSION} <EditIcon
onClick={() => setIsTeamsEdit(true)} className="cursor-pointer align-middle"
/> color={DE_ACTIVE_COLOR}
data-testid="edit-teams-button"
{...ICON_DIMENSION}
onClick={() => setIsTeamsEdit(true)}
/>
</Tooltip>
)} )}
</Space> </Space>
}> }>

View File

@ -10,7 +10,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Button, Modal } from 'antd'; import { Button, Modal, Tooltip } from 'antd';
import { isNil } from 'lodash'; import { isNil } from 'lodash';
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -90,14 +90,19 @@ export const UsersTab = ({ users, onRemoveUser }: UsersTabProps) => {
render: (_: string, record: User) => { render: (_: string, record: User) => {
return ( return (
onRemoveUser && ( onRemoveUser && (
<Button <Tooltip
data-testid="remove-user-btn" title={t('label.remove-entity', {
icon={ entity: t('label.user'),
<IconRemove height={16} name={t('label.remove')} width={16} /> })}>
} <Button
type="text" data-testid="remove-user-btn"
onClick={() => handleRemoveButtonClick(record)} icon={
/> <IconRemove height={16} name={t('label.remove')} width={16} />
}
type="text"
onClick={() => handleRemoveButtonClick(record)}
/>
</Tooltip>
) )
); );
}, },

View File

@ -21,7 +21,7 @@ import { useHistory } from 'react-router-dom';
import { ReactComponent as IconComments } from '../../../assets/svg/comment.svg'; import { ReactComponent as IconComments } from '../../../assets/svg/comment.svg';
import { ReactComponent as EditIcon } from '../../../assets/svg/edit-new.svg'; import { ReactComponent as EditIcon } from '../../../assets/svg/edit-new.svg';
import { ReactComponent as IconRequest } from '../../../assets/svg/request-icon.svg'; import { ReactComponent as IconRequest } from '../../../assets/svg/request-icon.svg';
import { DE_ACTIVE_COLOR } from '../../../constants/constants'; import { DE_ACTIVE_COLOR, ICON_DIMENSION } from '../../../constants/constants';
import { import {
GLOSSARY_CONSTANT, GLOSSARY_CONSTANT,
TAG_CONSTANT, TAG_CONSTANT,
@ -273,13 +273,18 @@ const TagsContainerV2 = ({
<Row gutter={12}> <Row gutter={12}>
{!isEmpty(tags?.[tagType]) && !isEditTags && ( {!isEmpty(tags?.[tagType]) && !isEditTags && (
<Col> <Col>
<EditIcon <Tooltip
className="cursor-pointer align-middle" title={t('label.edit-entity', {
color={DE_ACTIVE_COLOR} entity: t('label.tag-plural'),
data-testid="edit-button" })}>
width="14px" <EditIcon
onClick={handleAddClick} className="cursor-pointer align-middle"
/> color={DE_ACTIVE_COLOR}
data-testid="edit-button"
width="14px"
onClick={handleAddClick}
/>
</Tooltip>
</Col> </Col>
)} )}
{showTaskHandler && ( {showTaskHandler && (
@ -308,16 +313,21 @@ const TagsContainerV2 = ({
const editTagButton = useMemo( const editTagButton = useMemo(
() => () =>
permission && !isEmpty(tags?.[tagType]) ? ( permission && !isEmpty(tags?.[tagType]) ? (
<Button <Tooltip
className="hover-cell-icon cursor-pointer align-middle p-0" title={t('label.edit-entity', {
data-testid="edit-button" entity: t('label.tag-plural'),
style={{ })}>
color: DE_ACTIVE_COLOR, <Button
}} className="hover-cell-icon cursor-pointer align-middle p-0"
type="text" data-testid="edit-button"
onClick={handleAddClick}> style={{
<EditIcon /> color: DE_ACTIVE_COLOR,
</Button> }}
type="text"
onClick={handleAddClick}>
<EditIcon {...ICON_DIMENSION} />
</Button>
</Tooltip>
) : null, ) : null,
[permission, tags, tagType, handleAddClick] [permission, tags, tagType, handleAddClick]
); );

View File

@ -46,22 +46,18 @@ describe('Test CopyToClipboardButton Component', () => {
expect(callBack).toHaveBeenCalled(); expect(callBack).toHaveBeenCalled();
}); });
it('Should show success message and hide after timeout', async () => { it('Should show success message on clipboard click', async () => {
jest.useFakeTimers(); jest.useFakeTimers();
await act(async () => { render(<CopyToClipboardButton copyText={value} />);
render(<CopyToClipboardButton copyText={value} />);
});
await act(async () => { await act(async () => {
fireEvent.click(screen.getByTestId('copy-secret')); fireEvent.click(screen.getByTestId('copy-secret'));
}); });
fireEvent.mouseOver(screen.getByTestId('copy-secret'));
jest.advanceTimersByTime(1000);
expect(screen.getByTestId('copy-success')).toBeInTheDocument(); expect(screen.getByTestId('copy-success')).toBeInTheDocument();
jest.advanceTimersByTime(1500);
// success message should not be in the dom after timeout
expect(screen.queryByTestId('copy-success')).not.toBeInTheDocument();
}); });
it('Should have copied text in clipboard', async () => { it('Should have copied text in clipboard', async () => {

View File

@ -40,14 +40,18 @@ export const CopyToClipboardButton: FunctionComponent<Props> = ({
return ( return (
<Tooltip <Tooltip
destroyTooltipOnHide destroyTooltipOnHide
open={hasCopied}
placement={position} placement={position}
title={ title={
<span className="text-xs font-medium" data-testid="copy-success"> hasCopied ? (
{t('message.copied-to-clipboard')} <span className="text-xs font-medium" data-testid="copy-success">
</span> {t('message.copied-to-clipboard')}
} </span>
trigger="click"> ) : (
<span className="text-xs font-medium" data-testid="copy-tooltip">
{t('message.copy-to-clipboard')}
</span>
)
}>
<Button <Button
className="h-8 m-l-md relative" className="h-8 m-l-md relative"
data-testid="copy-secret" data-testid="copy-secret"

View File

@ -12,7 +12,7 @@
*/ */
import Icon from '@ant-design/icons'; import Icon from '@ant-design/icons';
import { Typography } from 'antd'; import { Tooltip, Typography } from 'antd';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { t } from 'i18next'; import { t } from 'i18next';
import { isUndefined, toNumber } from 'lodash'; import { isUndefined, toNumber } from 'lodash';
@ -168,12 +168,16 @@ export const PropertyValue: FC<Props> = ({
<div className="d-flex gap-2 items-center"> <div className="d-flex gap-2 items-center">
{getValueElement()} {getValueElement()}
{hasEditPermissions && ( {hasEditPermissions && (
<Icon <Tooltip
component={EditIconComponent} placement="left"
data-testid="edit-icon" title={t('label.edit-entity', { entity: propertyName })}>
style={{ color: DE_ACTIVE_COLOR, ...ICON_DIMENSION }} <Icon
onClick={onShowInput} component={EditIconComponent}
/> data-testid="edit-icon"
style={{ color: DE_ACTIVE_COLOR, ...ICON_DIMENSION }}
onClick={onShowInput}
/>
</Tooltip>
)} )}
</div> </div>
</Fragment> </Fragment>

View File

@ -152,7 +152,13 @@ const DomainSelectableList = ({
{children ?? ( {children ?? (
<Tooltip <Tooltip
placement="topRight" placement="topRight"
title={hasPermission ? '' : NO_PERMISSION_FOR_ACTION}> title={
hasPermission
? t('label.edit-entity', {
entity: t('label.domain'),
})
: NO_PERMISSION_FOR_ACTION
}>
<Button <Button
className="p-0 flex-center" className="p-0 flex-center"
data-testid="add-domain" data-testid="add-domain"

View File

@ -179,15 +179,19 @@ const Description: FC<DescriptionProps> = ({
const DescriptionActions = () => { const DescriptionActions = () => {
return !isReadOnly ? ( return !isReadOnly ? (
<Space align="end" size={0}> <div className="d-flex items-end">
{hasEditAccess && ( {hasEditAccess && (
<Button <Tooltip
className="w-7 h-7 p-0 flex-center" placement="topRight"
data-testid="edit-description" title={t('label.edit-entity', { entity: t('label.description') })}>
icon={<IconEdit color={DE_ACTIVE_COLOR} {...ICON_DIMENSION} />} <Button
type="text" className="w-7 h-7 p-0 flex-center"
onClick={handleUpdate} data-testid="edit-description"
/> icon={<IconEdit color={DE_ACTIVE_COLOR} {...ICON_DIMENSION} />}
type="text"
onClick={handleUpdate}
/>
</Tooltip>
)} )}
{isTaskSupported(entityType as EntityType) ? ( {isTaskSupported(entityType as EntityType) ? (
<Fragment> <Fragment>
@ -197,13 +201,13 @@ const Description: FC<DescriptionProps> = ({
) : null} ) : null}
<DescriptionThreadEl descriptionThread={thread} /> <DescriptionThreadEl descriptionThread={thread} />
</Space> </div>
) : null; ) : null;
}; };
return ( return (
<div className={`schema-description relative ${className}`}> <div className={`schema-description relative ${className}`}>
<div className="description-inner-main-container d-flex items-end"> <div className="description-inner-main-container d-flex items-baseline">
<div <div
className="description h-full relative overflow-y-scroll m-r-xss" className="description h-full relative overflow-y-scroll m-r-xss"
data-testid="description" data-testid="description"

View File

@ -126,12 +126,17 @@ const DescriptionV1 = ({
() => ( () => (
<Space size={12}> <Space size={12}>
{!isReadOnly && hasEditAccess && ( {!isReadOnly && hasEditAccess && (
<Icon <Tooltip
component={EditIcon} title={t('label.edit-entity', {
data-testid="edit-description" entity: t('label.description'),
style={{ color: DE_ACTIVE_COLOR }} })}>
onClick={onDescriptionEdit} <Icon
/> component={EditIcon}
data-testid="edit-description"
style={{ color: DE_ACTIVE_COLOR }}
onClick={onDescriptionEdit}
/>
</Tooltip>
)} )}
{taskActionButton} {taskActionButton}
{showCommentsIcon && ( {showCommentsIcon && (

View File

@ -15,7 +15,7 @@ import { Button, Dropdown, Modal, Tooltip, Typography } from 'antd';
import { ItemType } from 'antd/lib/menu/hooks/useItems'; import { ItemType } from 'antd/lib/menu/hooks/useItems';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import classNames from 'classnames'; import classNames from 'classnames';
import { isUndefined } from 'lodash'; import { capitalize, isUndefined } from 'lodash';
import React, { FC, useCallback, useMemo, useState } from 'react'; import React, { FC, useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ReactComponent as IconAnnouncementsBlack } from '../../../../assets/svg/announcements-black.svg'; import { ReactComponent as IconAnnouncementsBlack } from '../../../../assets/svg/announcements-black.svg';
@ -271,13 +271,18 @@ const ManageButton: FC<ManageButtonProps> = ({
overlayStyle={{ width: '350px' }} overlayStyle={{ width: '350px' }}
placement="bottomRight" placement="bottomRight"
trigger={['click']}> trigger={['click']}>
<Button <Tooltip
className={classNames('flex-center px-1.5', buttonClassName)} placement="topRight"
data-testid="manage-button" title={t('label.manage-entity', {
title="Manage" entity: capitalize(entityType),
type="default"> })}>
<IconDropdown className="anticon self-center manage-dropdown-icon" /> <Button
</Button> className={classNames('flex-center px-1.5', buttonClassName)}
data-testid="manage-button"
type="default">
<IconDropdown className="anticon self-center manage-dropdown-icon" />
</Button>
</Tooltip>
</Dropdown> </Dropdown>
) : ( ) : (
<></> <></>

View File

@ -10,7 +10,15 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Button, Checkbox, List, Popover, Space, Typography } from 'antd'; import {
Button,
Checkbox,
List,
Popover,
Space,
Tooltip,
Typography,
} from 'antd';
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ReactComponent as FilterIcon } from '../../../assets/svg/ic-feeds-filter.svg'; import { ReactComponent as FilterIcon } from '../../../assets/svg/ic-feeds-filter.svg';
@ -123,11 +131,13 @@ const FeedsFilterPopover = ({
showArrow={false} showArrow={false}
trigger="click" trigger="click"
onOpenChange={setPopupVisible}> onOpenChange={setPopupVisible}>
<Button <Tooltip title={t('label.feed-filter-plural')}>
className="flex-center" <Button
data-testid="filter-button" className="flex-center"
icon={<FilterIcon height={16} />} data-testid="filter-button"
/> icon={<FilterIcon height={16} />}
/>
</Tooltip>
</Popover> </Popover>
); );
}; };

View File

@ -10,7 +10,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Button, Card, Space, Tag } from 'antd'; import { Button, Card, Space, Tag, Tooltip } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import { split } from 'lodash'; import { split } from 'lodash';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
@ -51,12 +51,14 @@ const QueryViewer = ({
<Tag className="query-lines" data-testid="query-line"> <Tag className="query-lines" data-testid="query-line">
{queryLine} {queryLine}
</Tag> </Tag>
<Button <Tooltip placement="topRight" title={t('message.copy-to-clipboard')}>
className="flex-center button-size bg-white" <Button
data-testid="query-entity-copy-button" className="flex-center button-size bg-white"
icon={<CopyIcon height={16} width={16} />} data-testid="query-entity-copy-button"
onClick={onCopyToClipBoard} icon={<CopyIcon height={16} width={16} />}
/> onClick={onCopyToClipBoard}
/>
</Tooltip>
</Space> </Space>
} }
title={title}> title={title}>

View File

@ -12,7 +12,7 @@
*/ */
import { CheckOutlined, CloseOutlined } from '@ant-design/icons'; import { CheckOutlined, CloseOutlined } from '@ant-design/icons';
import { Button, Card, Select, Space } from 'antd'; import { Button, Card, Select, Space, Tooltip } from 'antd';
import { isArray, isNil, toLower } from 'lodash'; import { isArray, isNil, toLower } from 'lodash';
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -85,13 +85,19 @@ const RolesCard = ({
className="ant-card-feed relative page-layout-v1-left-panel" className="ant-card-feed relative page-layout-v1-left-panel"
extra={ extra={
!isRolesEdit && ( !isRolesEdit && (
<Button <Tooltip
className="m-l-xs" title={t('label.edit-entity', {
data-testid="edit-roles" entity: t('label.role-plural'),
icon={<EditIcon width={16} />} })}>
type="text" {' '}
onClick={() => setIsRolesEdit(true)} <Button
/> className="m-l-xs"
data-testid="edit-roles"
icon={<EditIcon width={16} />}
type="text"
onClick={() => setIsRolesEdit(true)}
/>
</Tooltip>
) )
} }
key="roles-card" key="roles-card"

View File

@ -11,9 +11,9 @@
* limitations under the License. * limitations under the License.
*/ */
import Icon from '@ant-design/icons/lib/components/Icon'; import Icon from '@ant-design/icons/lib/components/Icon';
import { Button, Popover, Space, Tabs, Typography } from 'antd'; import { Button, Popover, Space, Tabs, Tooltip, Typography } from 'antd';
import { isEmpty, noop, toString } from 'lodash'; import { isEmpty, noop, toString } from 'lodash';
import React, { useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ReactComponent as EditIcon } from '../../../assets/svg/edit-new.svg'; import { ReactComponent as EditIcon } from '../../../assets/svg/edit-new.svg';
import { ReactComponent as IconTeamsGrey } from '../../../assets/svg/teams-grey.svg'; import { ReactComponent as IconTeamsGrey } from '../../../assets/svg/teams-grey.svg';
@ -189,6 +189,8 @@ export const UserTeamSelectableList = ({
} }
}; };
const openPopover = useCallback(() => setPopupVisible(true), []);
useEffect(() => { useEffect(() => {
fetchCount(); fetchCount();
}, [popupVisible]); }, [popupVisible]);
@ -268,14 +270,22 @@ export const UserTeamSelectableList = ({
onOpenChange={setPopupVisible}> onOpenChange={setPopupVisible}>
{children ?? {children ??
(hasPermission && ( (hasPermission && (
<Button <Tooltip
className="flex-center p-0" title={
data-testid="edit-owner" !popupVisible &&
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />} t('label.edit-entity', {
size="small" entity: t('label.owner'),
type="text" })
onClick={() => setPopupVisible(true)} }>
/> <Button
className="flex-center p-0"
data-testid="edit-owner"
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
onClick={openPopover}
/>
</Tooltip>
))} ))}
</Popover> </Popover>
); );

View File

@ -696,6 +696,7 @@
"my-data": "Meine Daten", "my-data": "Meine Daten",
"name": "Name", "name": "Name",
"name-lowercase": "name", "name-lowercase": "name",
"need-help": "Need Help",
"new": "Neu", "new": "Neu",
"new-password": "Neues Passwort", "new-password": "Neues Passwort",
"new-term": "Neuer Begriff", "new-term": "Neuer Begriff",

View File

@ -696,6 +696,7 @@
"my-data": "My Data", "my-data": "My Data",
"name": "Name", "name": "Name",
"name-lowercase": "name", "name-lowercase": "name",
"need-help": "Need Help",
"new": "New", "new": "New",
"new-password": "New Password", "new-password": "New Password",
"new-term": "New Term", "new-term": "New Term",

View File

@ -696,6 +696,7 @@
"my-data": "Mis Datos", "my-data": "Mis Datos",
"name": "Nombre", "name": "Nombre",
"name-lowercase": "nombre", "name-lowercase": "nombre",
"need-help": "Need Help",
"new": "Nuevo", "new": "Nuevo",
"new-password": "Nueva Contraseña", "new-password": "Nueva Contraseña",
"new-term": "Nuevo Término", "new-term": "Nuevo Término",

View File

@ -696,6 +696,7 @@
"my-data": "Mes Données", "my-data": "Mes Données",
"name": "Nom", "name": "Nom",
"name-lowercase": "nom", "name-lowercase": "nom",
"need-help": "Need Help",
"new": "Nouveau", "new": "Nouveau",
"new-password": "Nouveau mot de passe", "new-password": "Nouveau mot de passe",
"new-term": "Nouveau Terme", "new-term": "Nouveau Terme",

View File

@ -696,6 +696,7 @@
"my-data": "הנתונים שלי", "my-data": "הנתונים שלי",
"name": "שם", "name": "שם",
"name-lowercase": "שם", "name-lowercase": "שם",
"need-help": "Need Help",
"new": "חדש", "new": "חדש",
"new-password": "סיסמה חדשה", "new-password": "סיסמה חדשה",
"new-term": "מונח עיסקי חדש", "new-term": "מונח עיסקי חדש",

View File

@ -696,6 +696,7 @@
"my-data": "マイデータ", "my-data": "マイデータ",
"name": "名前", "name": "名前",
"name-lowercase": "名前", "name-lowercase": "名前",
"need-help": "Need Help",
"new": "新しい", "new": "新しい",
"new-password": "新しいパスワード", "new-password": "新しいパスワード",
"new-term": "New Term", "new-term": "New Term",

View File

@ -696,6 +696,7 @@
"my-data": "Mijn data", "my-data": "Mijn data",
"name": "Naam", "name": "Naam",
"name-lowercase": "naam", "name-lowercase": "naam",
"need-help": "Need Help",
"new": "Nieuw", "new": "Nieuw",
"new-password": "Nieuw wachtwoord", "new-password": "Nieuw wachtwoord",
"new-term": "Nieuwe term", "new-term": "Nieuwe term",

View File

@ -696,6 +696,7 @@
"my-data": "Meus Dados", "my-data": "Meus Dados",
"name": "Nome", "name": "Nome",
"name-lowercase": "nome", "name-lowercase": "nome",
"need-help": "Need Help",
"new": "Novo", "new": "Novo",
"new-password": "Nova Senha", "new-password": "Nova Senha",
"new-term": "Novo Termo", "new-term": "Novo Termo",

View File

@ -696,6 +696,7 @@
"my-data": "Мои данные", "my-data": "Мои данные",
"name": "Наименование", "name": "Наименование",
"name-lowercase": "наименование", "name-lowercase": "наименование",
"need-help": "Need Help",
"new": "Новый", "new": "Новый",
"new-password": "Новый пароль", "new-password": "Новый пароль",
"new-term": "Новый термин", "new-term": "Новый термин",

View File

@ -696,6 +696,7 @@
"my-data": "我的数据", "my-data": "我的数据",
"name": "名称", "name": "名称",
"name-lowercase": "名称", "name-lowercase": "名称",
"need-help": "Need Help",
"new": "新", "new": "新",
"new-password": "新密码", "new-password": "新密码",
"new-term": "新术语", "new-term": "新术语",

View File

@ -257,7 +257,7 @@ const GlossaryPage = () => {
fetchGlossaryList(); fetchGlossaryList();
} catch (error) { } catch (error) {
showErrorToast( showErrorToast(
error, error as AxiosError,
t('server.delete-entity-error', { t('server.delete-entity-error', {
entity: t('label.glossary'), entity: t('label.glossary'),
}) })

View File

@ -126,7 +126,7 @@ describe('PersonaDetailsPage', () => {
expect( expect(
await screen.findByText('DescriptionV1.component') await screen.findByText('DescriptionV1.component')
).toBeInTheDocument(); ).toBeInTheDocument();
expect(await screen.findByTestId('add-user-button')).toBeInTheDocument(); expect(await screen.findByTestId('add-persona-button')).toBeInTheDocument();
}); });
it('NoDataPlaceholder', async () => { it('NoDataPlaceholder', async () => {

View File

@ -222,7 +222,7 @@ export const PersonaDetailsPage = () => {
selectedUsers={personaDetails.users ?? []} selectedUsers={personaDetails.users ?? []}
onUpdate={(users) => handlePersonaUpdate({ users })}> onUpdate={(users) => handlePersonaUpdate({ users })}>
<Button <Button
data-testid="add-user-button" data-testid="add-persona-button"
size="small" size="small"
type="primary"> type="primary">
{t('label.add-entity', { entity: t('label.user') })} {t('label.add-entity', { entity: t('label.user') })}

View File

@ -23,6 +23,7 @@ import {
Row, Row,
Space, Space,
Tabs, Tabs,
Tooltip,
Typography, Typography,
} from 'antd'; } from 'antd';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
@ -283,15 +284,21 @@ const PoliciesDetailPage = () => {
} }
placement="bottomRight" placement="bottomRight"
trigger={['click']}> trigger={['click']}>
<Button <Tooltip
data-testid={`manage-button-${rule.name}`} placement="topRight"
icon={<EllipsisOutlined className="text-grey-body" rotate={90} />} title={t('label.manage-entity', {
size="small" entity: t('label.rule'),
type="text" })}>
onClick={(e) => { <Button
e.stopPropagation(); data-testid={`manage-button-${rule.name}`}
}} icon={<EllipsisOutlined className="text-grey-body" rotate={90} />}
/> size="small"
type="text"
onClick={(e) => {
e.stopPropagation();
}}
/>
</Tooltip>
</Dropdown> </Dropdown>
); );
}, },

View File

@ -204,7 +204,13 @@ const PoliciesListPage = () => {
return ( return (
<Tooltip <Tooltip
placement="left" placement="left"
title={!deletePolicyPermission && NO_PERMISSION_FOR_ACTION}> title={
deletePolicyPermission
? t('label.delete-entity', {
entity: t('label.policy'),
})
: NO_PERMISSION_FOR_ACTION
}>
<Button <Button
data-testid={`delete-action-${getEntityName(record)}`} data-testid={`delete-action-${getEntityName(record)}`}
disabled={!deletePolicyPermission} disabled={!deletePolicyPermission}

View File

@ -201,7 +201,13 @@ const RolesListPage = () => {
return ( return (
<Tooltip <Tooltip
placement="left" placement="left"
title={!deleteRolePermission && NO_PERMISSION_FOR_ACTION}> title={
deleteRolePermission
? t('label.delete-entity', {
entity: t('label.role-plural'),
})
: NO_PERMISSION_FOR_ACTION
}>
<Button <Button
data-testid={`delete-action-${getEntityName(record)}`} data-testid={`delete-action-${getEntityName(record)}`}
disabled={!deleteRolePermission} disabled={!deleteRolePermission}

View File

@ -313,9 +313,18 @@ const UserListPageV1 = () => {
className="w-full justify-center action-icons" className="w-full justify-center action-icons"
size={8}> size={8}>
{showRestore && ( {showRestore && (
<Tooltip placement="bottom" title={t('label.restore')}> <Tooltip
placement={isAdminUser ? 'bottom' : 'left'}
title={
isAdminUser
? t('label.restore-entity', {
entity: t('label.user'),
})
: ADMIN_ONLY_ACTION
}>
<Button <Button
data-testid={`restore-user-btn-${record.name}`} data-testid={`restore-user-btn-${record.name}`}
disabled={!isAdminUser}
icon={<IconRestore name={t('label.restore')} width="16px" />} icon={<IconRestore name={t('label.restore')} width="16px" />}
type="text" type="text"
onClick={() => { onClick={() => {
@ -325,7 +334,15 @@ const UserListPageV1 = () => {
/> />
</Tooltip> </Tooltip>
)} )}
<Tooltip placement="left" title={!isAdminUser && ADMIN_ONLY_ACTION}> <Tooltip
placement={isAdminUser ? 'bottom' : 'left'}
title={
isAdminUser
? t('label.delete-entity', {
entity: t('label.user'),
})
: ADMIN_ONLY_ACTION
}>
<Button <Button
disabled={!isAdminUser} disabled={!isAdminUser}
icon={ icon={