mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-23 00:18:06 +00:00
Co-authored-by: Shailesh Parmar <shailesh.parmar.webdev@gmail.com>
This commit is contained in:
parent
2b05f6a17a
commit
bdfee26533
@ -96,13 +96,10 @@ describe('Glossary page should work properly', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.goToHomePage();
|
cy.goToHomePage();
|
||||||
// redirecting to glossary page
|
// redirecting to glossary page
|
||||||
cy.get(
|
cy.get('[data-testid="appbar-item-glossary"]')
|
||||||
'.tw-ml-5 > [data-testid="dropdown-item"] > div > [data-testid="menu-button"]'
|
|
||||||
)
|
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
cy.get('[data-testid="menu-item-Glossaries"]').should('be.visible').click();
|
|
||||||
// Todo: need to remove below uncaught exception once tree-view error resolves
|
// Todo: need to remove below uncaught exception once tree-view error resolves
|
||||||
cy.on('uncaught:exception', () => {
|
cy.on('uncaught:exception', () => {
|
||||||
// return false to prevent the error from
|
// return false to prevent the error from
|
||||||
@ -321,13 +318,10 @@ describe('Glossary page should work properly', () => {
|
|||||||
|
|
||||||
addNewTagToEntity(entity, term);
|
addNewTagToEntity(entity, term);
|
||||||
|
|
||||||
cy.get(
|
cy.get('[data-testid="appbar-item-glossary"]')
|
||||||
'.tw-ml-5 > [data-testid="dropdown-item"] > div > [data-testid="menu-button"]'
|
|
||||||
)
|
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
cy.get('[data-testid="menu-item-Glossaries"]').should('be.visible').click();
|
|
||||||
goToAssetsTab(term);
|
goToAssetsTab(term);
|
||||||
cy.get('[data-testid="column"] > :nth-child(1)')
|
cy.get('[data-testid="column"] > :nth-child(1)')
|
||||||
.contains(entity)
|
.contains(entity)
|
||||||
@ -377,13 +371,11 @@ describe('Glossary page should work properly', () => {
|
|||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
cy.get('[data-testid="saveAssociatedTag"]').scrollIntoView().click();
|
cy.get('[data-testid="saveAssociatedTag"]').scrollIntoView().click();
|
||||||
cy.get(
|
|
||||||
'.tw-ml-5 > [data-testid="dropdown-item"] > div > [data-testid="menu-button"]'
|
cy.get('[data-testid="appbar-item-glossary"]')
|
||||||
)
|
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
cy.get('[data-testid="menu-item-Glossaries"]').should('be.visible').click();
|
|
||||||
cy.wait(500);
|
cy.wait(500);
|
||||||
goToAssetsTab(term);
|
goToAssetsTab(term);
|
||||||
cy.get('.tableBody-cell')
|
cy.get('.tableBody-cell')
|
||||||
|
@ -17,12 +17,7 @@ import { NEW_TAG, NEW_TAG_CATEGORY, SEARCH_ENTITY_TABLE } from '../../constants/
|
|||||||
describe('Tags page should work', () => {
|
describe('Tags page should work', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.goToHomePage();
|
cy.goToHomePage();
|
||||||
cy.get(
|
cy.get('[data-testid="appbar-item-tags"]').should('be.visible').click();
|
||||||
'.tw-ml-5 > [data-testid="dropdown-item"] > div > [data-testid="menu-button"]'
|
|
||||||
)
|
|
||||||
.should('be.visible')
|
|
||||||
.click();
|
|
||||||
cy.get('[data-testid="menu-item-Tags"]').should('be.visible').click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Required Details should be available', () => {
|
it('Required Details should be available', () => {
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
import { Card } from 'antd';
|
||||||
import { capitalize } from 'lodash';
|
import { capitalize } from 'lodash';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { TITLE_FOR_NON_ADMIN_ACTION } from '../../constants/constants';
|
import { TITLE_FOR_NON_ADMIN_ACTION } from '../../constants/constants';
|
||||||
@ -22,7 +23,7 @@ import { getActiveCatClass, getCountBadge } from '../../utils/CommonUtils';
|
|||||||
import { getActiveUsers } from '../../utils/TeamUtils';
|
import { getActiveUsers } from '../../utils/TeamUtils';
|
||||||
import { Button } from '../buttons/Button/Button';
|
import { Button } from '../buttons/Button/Button';
|
||||||
import NonAdminAction from '../common/non-admin-action/NonAdminAction';
|
import NonAdminAction from '../common/non-admin-action/NonAdminAction';
|
||||||
import PageLayout from '../containers/PageLayout';
|
import PageLayout, { leftPanelAntCardStyle } from '../containers/PageLayout';
|
||||||
import Loader from '../Loader/Loader';
|
import Loader from '../Loader/Loader';
|
||||||
import TeamDetails from '../TeamDetails/TeamDetails';
|
import TeamDetails from '../TeamDetails/TeamDetails';
|
||||||
import UserDetails from '../UserDetails/UserDetails';
|
import UserDetails from '../UserDetails/UserDetails';
|
||||||
@ -88,104 +89,106 @@ const TeamsAndUsers = ({
|
|||||||
*/
|
*/
|
||||||
const fetchLeftPanel = () => {
|
const fetchLeftPanel = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<Card data-testid="data-summary-container" style={leftPanelAntCardStyle}>
|
||||||
<div className="tw-mb-8">
|
<>
|
||||||
<div
|
<div className="tw-mb-8">
|
||||||
className="tw-flex tw-justify-between tw-items-center tw-mb-2 tw-border-b"
|
|
||||||
data-testid="add-team-container">
|
|
||||||
<p className="tw-heading">Teams</p>
|
|
||||||
{hasAccess && (
|
|
||||||
<NonAdminAction
|
|
||||||
position="bottom"
|
|
||||||
title={TITLE_FOR_NON_ADMIN_ACTION}>
|
|
||||||
<Button
|
|
||||||
className="tw-h-7 tw-px-2 tw-mb-4"
|
|
||||||
data-testid="add-team-button"
|
|
||||||
size="small"
|
|
||||||
theme="primary"
|
|
||||||
variant="contained"
|
|
||||||
onClick={() => {
|
|
||||||
handleAddTeam(true);
|
|
||||||
}}>
|
|
||||||
<FontAwesomeIcon icon="plus" />
|
|
||||||
</Button>
|
|
||||||
</NonAdminAction>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{teams.map((team) => (
|
|
||||||
<div
|
<div
|
||||||
className="tw-flex tw-items-center tw-justify-between tw-mb-2 tw-cursor-pointer"
|
className="tw-flex tw-justify-between tw-items-center tw-mb-2 tw-border-b"
|
||||||
data-testid={`team-${team.name}`}
|
data-testid="add-team-container">
|
||||||
key={team.name}
|
<p className="tw-heading">Teams</p>
|
||||||
onClick={() => {
|
|
||||||
changeCurrentTeam(team.name, false);
|
|
||||||
}}>
|
|
||||||
<div
|
|
||||||
className={`tw-group tw-text-grey-body tw-cursor-pointer tw-text-body tw-flex tw-justify-between ${getActiveCatClass(
|
|
||||||
team.name,
|
|
||||||
currentTeam?.name
|
|
||||||
)}`}>
|
|
||||||
<p
|
|
||||||
className="tag-category label-category tw-self-center tw-truncate tw-w-52"
|
|
||||||
data-testid="team-name"
|
|
||||||
title={team.displayName ?? team.name}>
|
|
||||||
{team.displayName ?? team.name}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{getCountBadge(
|
|
||||||
getActiveUsers(team.users).length,
|
|
||||||
'',
|
|
||||||
currentTeam?.name === team.name
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
{hasAccess && (
|
|
||||||
<div>
|
|
||||||
<div className="tw-flex tw-justify-between tw-items-center tw-mb-2 tw-border-b">
|
|
||||||
<p className="tw-heading">All Users</p>
|
|
||||||
{hasAccess && (
|
{hasAccess && (
|
||||||
<NonAdminAction
|
<NonAdminAction
|
||||||
position="bottom"
|
position="bottom"
|
||||||
title={TITLE_FOR_NON_ADMIN_ACTION}>
|
title={TITLE_FOR_NON_ADMIN_ACTION}>
|
||||||
<Button
|
<Button
|
||||||
className="tw-h-7 tw-px-2 tw-mb-4"
|
className="tw-h-7 tw-px-2 tw-mb-4"
|
||||||
data-testid="add-user-button"
|
data-testid="add-team-button"
|
||||||
size="small"
|
size="small"
|
||||||
theme="primary"
|
theme="primary"
|
||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={handleAddNewUser}>
|
onClick={() => {
|
||||||
|
handleAddTeam(true);
|
||||||
|
}}>
|
||||||
<FontAwesomeIcon icon="plus" />
|
<FontAwesomeIcon icon="plus" />
|
||||||
</Button>
|
</Button>
|
||||||
</NonAdminAction>
|
</NonAdminAction>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{usersData.map((user) => (
|
{teams.map((team) => (
|
||||||
<div
|
<div
|
||||||
className="tw-flex tw-items-center tw-justify-between tw-mb-2 tw-cursor-pointer"
|
className="tw-flex tw-items-center tw-justify-between tw-mb-2 tw-cursor-pointer"
|
||||||
data-testid={user.name}
|
data-testid={`team-${team.name}`}
|
||||||
key={user.name}
|
key={team.name}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
changeCurrentTeam(user.name, true);
|
changeCurrentTeam(team.name, false);
|
||||||
}}>
|
}}>
|
||||||
<div
|
<div
|
||||||
className={`tw-group tw-text-grey-body tw-cursor-pointer tw-text-body tw-flex tw-justify-between ${getActiveCatClass(
|
className={`tw-group tw-text-grey-body tw-cursor-pointer tw-text-body tw-flex tw-justify-between ${getActiveCatClass(
|
||||||
user.name,
|
team.name,
|
||||||
activeUserTab
|
currentTeam?.name
|
||||||
)}`}>
|
)}`}>
|
||||||
<p
|
<p
|
||||||
className="tag-category label-category tw-self-center tw-truncate tw-w-52"
|
className="tag-category label-category tw-self-center tw-truncate tw-w-52"
|
||||||
data-testid="user-type"
|
data-testid="team-name"
|
||||||
title={capitalize(user.name)}>
|
title={team.displayName ?? team.name}>
|
||||||
{capitalize(user.name)}
|
{team.displayName ?? team.name}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{getCountBadge(user.count, '', activeUserTab === user.name)}
|
{getCountBadge(
|
||||||
|
getActiveUsers(team.users).length,
|
||||||
|
'',
|
||||||
|
currentTeam?.name === team.name
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
{hasAccess && (
|
||||||
</>
|
<div>
|
||||||
|
<div className="tw-flex tw-justify-between tw-items-center tw-mb-2 tw-border-b">
|
||||||
|
<p className="tw-heading">All Users</p>
|
||||||
|
{hasAccess && (
|
||||||
|
<NonAdminAction
|
||||||
|
position="bottom"
|
||||||
|
title={TITLE_FOR_NON_ADMIN_ACTION}>
|
||||||
|
<Button
|
||||||
|
className="tw-h-7 tw-px-2 tw-mb-4"
|
||||||
|
data-testid="add-user-button"
|
||||||
|
size="small"
|
||||||
|
theme="primary"
|
||||||
|
variant="contained"
|
||||||
|
onClick={handleAddNewUser}>
|
||||||
|
<FontAwesomeIcon icon="plus" />
|
||||||
|
</Button>
|
||||||
|
</NonAdminAction>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{usersData.map((user) => (
|
||||||
|
<div
|
||||||
|
className="tw-flex tw-items-center tw-justify-between tw-mb-2 tw-cursor-pointer"
|
||||||
|
data-testid={user.name}
|
||||||
|
key={user.name}
|
||||||
|
onClick={() => {
|
||||||
|
changeCurrentTeam(user.name, true);
|
||||||
|
}}>
|
||||||
|
<div
|
||||||
|
className={`tw-group tw-text-grey-body tw-cursor-pointer tw-text-body tw-flex tw-justify-between ${getActiveCatClass(
|
||||||
|
user.name,
|
||||||
|
activeUserTab
|
||||||
|
)}`}>
|
||||||
|
<p
|
||||||
|
className="tag-category label-category tw-self-center tw-truncate tw-w-52"
|
||||||
|
data-testid="user-type"
|
||||||
|
title={capitalize(user.name)}>
|
||||||
|
{capitalize(user.name)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{getCountBadge(user.count, '', activeUserTab === user.name)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -195,8 +198,9 @@ const TeamsAndUsers = ({
|
|||||||
<Loader />
|
<Loader />
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
className="tw-pb-3 tw-w-full tw-h-full tw-flex tw-flex-col"
|
className="tw-pb-3 tw-w-full tw-h-full tw-flex tw-flex-col tw-bg-white"
|
||||||
data-testid="team-and-user-container">
|
data-testid="team-and-user-container"
|
||||||
|
style={{ padding: '14px' }}>
|
||||||
{!isTeamVisible ? (
|
{!isTeamVisible ? (
|
||||||
<UserDetails
|
<UserDetails
|
||||||
currentUserPage={currentUserPage}
|
currentUserPage={currentUserPage}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Card } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { cloneDeep, isNil, startCase } from 'lodash';
|
import { cloneDeep, isNil, startCase } from 'lodash';
|
||||||
import React, { FunctionComponent, useEffect, useState } from 'react';
|
import React, { FunctionComponent, useEffect, useState } from 'react';
|
||||||
@ -25,7 +26,7 @@ import ErrorPlaceHolder from '../common/error-with-placeholder/ErrorPlaceHolder'
|
|||||||
import NextPrevious from '../common/next-previous/NextPrevious';
|
import NextPrevious from '../common/next-previous/NextPrevious';
|
||||||
import NonAdminAction from '../common/non-admin-action/NonAdminAction';
|
import NonAdminAction from '../common/non-admin-action/NonAdminAction';
|
||||||
import WebhookDataCard from '../common/webhook-data-card/WebhookDataCard';
|
import WebhookDataCard from '../common/webhook-data-card/WebhookDataCard';
|
||||||
import PageLayout from '../containers/PageLayout';
|
import PageLayout, { leftPanelAntCardStyle } from '../containers/PageLayout';
|
||||||
import { WebhooksProps } from './Webhooks.interface';
|
import { WebhooksProps } from './Webhooks.interface';
|
||||||
|
|
||||||
const statuses = [
|
const statuses = [
|
||||||
@ -86,55 +87,57 @@ const Webhooks: FunctionComponent<WebhooksProps> = ({
|
|||||||
|
|
||||||
const fetchLeftPanel = () => {
|
const fetchLeftPanel = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<Card data-testid="data-summary-container" style={leftPanelAntCardStyle}>
|
||||||
<h6 className="tw-heading tw-text-base">Webhooks</h6>
|
<>
|
||||||
<div className="tw-flex tw-justify-between tw-flex-col">
|
<h6 className="tw-heading tw-text-base">Webhooks</h6>
|
||||||
<h6 className="tw-heading tw-mb-0" data-testid="filter-heading">
|
<div className="tw-flex tw-justify-between tw-flex-col">
|
||||||
Status
|
<h6 className="tw-heading tw-mb-0" data-testid="filter-heading">
|
||||||
</h6>
|
Status
|
||||||
<div className="tw-flex tw-mt-2" />
|
</h6>
|
||||||
</div>
|
<div className="tw-flex tw-mt-2" />
|
||||||
<div
|
</div>
|
||||||
className="sidebar-my-data-holder"
|
<div
|
||||||
data-testid="filter-containers-1">
|
className="sidebar-my-data-holder"
|
||||||
{statuses.map((statusType, index) => (
|
data-testid="filter-containers-1">
|
||||||
<div
|
{statuses.map((statusType, index) => (
|
||||||
className="filter-group tw-justify-between tw-mb-3"
|
<div
|
||||||
data-testid={`status-type-${statusType.value}`}
|
className="filter-group tw-justify-between tw-mb-3"
|
||||||
key={index}>
|
data-testid={`status-type-${statusType.value}`}
|
||||||
<div className="tw-flex">
|
key={index}>
|
||||||
<input
|
<div className="tw-flex">
|
||||||
checked={selectedStatus.includes(statusType.value)}
|
<input
|
||||||
className="tw-mr-1 custom-checkbox"
|
checked={selectedStatus.includes(statusType.value)}
|
||||||
data-testid="checkbox"
|
className="tw-mr-1 custom-checkbox"
|
||||||
type="checkbox"
|
data-testid="checkbox"
|
||||||
onChange={() => {
|
type="checkbox"
|
||||||
handleStatusSelection(statusType.value);
|
onChange={() => {
|
||||||
}}
|
handleStatusSelection(statusType.value);
|
||||||
/>
|
}}
|
||||||
<div
|
/>
|
||||||
className="tw-flex tw-items-center filters-title tw-truncate custom-checkbox-label"
|
<div
|
||||||
data-testid="checkbox-label">
|
className="tw-flex tw-items-center filters-title tw-truncate custom-checkbox-label"
|
||||||
<div className="tw-ml-1">{statusType.name}</div>
|
data-testid="checkbox-label">
|
||||||
|
<div className="tw-ml-1">{statusType.name}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</>
|
||||||
</>
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchRightPanel = () => {
|
const fetchRightPanel = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<Card data-testid="data-summary-container" style={leftPanelAntCardStyle}>
|
||||||
<div className="tw-mb-5 tw-mt-11">
|
<div className="tw-my-2">
|
||||||
The webhook allows external services to be notified of the metadata
|
The webhook allows external services to be notified of the metadata
|
||||||
change events happening in your organization through APIs. Register
|
change events happening in your organization through APIs. Register
|
||||||
callback URLs with webhook integration to receive metadata event
|
callback URLs with webhook integration to receive metadata event
|
||||||
notifications. You can add, list, update, and delete webhooks.
|
notifications. You can add, list, update, and delete webhooks.
|
||||||
</div>
|
</div>
|
||||||
</>
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -167,7 +170,7 @@ const Webhooks: FunctionComponent<WebhooksProps> = ({
|
|||||||
|
|
||||||
return data.length ? (
|
return data.length ? (
|
||||||
<PageLayout leftPanel={fetchLeftPanel()} rightPanel={fetchRightPanel()}>
|
<PageLayout leftPanel={fetchLeftPanel()} rightPanel={fetchRightPanel()}>
|
||||||
<div>
|
<div className="tw-bg-white" style={{ padding: '14px' }}>
|
||||||
{filteredData.length ? (
|
{filteredData.length ? (
|
||||||
<>
|
<>
|
||||||
<div className="tw-flex tw-justify-end tw-items-center">
|
<div className="tw-flex tw-justify-end tw-items-center">
|
||||||
|
@ -24,6 +24,14 @@ interface PageLayoutProp {
|
|||||||
classes?: string;
|
classes?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const leftPanelAntCardStyle = {
|
||||||
|
border: '1px rgb(221, 227, 234) solid',
|
||||||
|
borderRadius: '8px',
|
||||||
|
boxShadow: '1px 1px 6px rgb(0 0 0 / 12%)',
|
||||||
|
marginRight: '4px',
|
||||||
|
marginLeft: '4px',
|
||||||
|
};
|
||||||
|
|
||||||
const PageLayout: FC<PageLayoutProp> = ({
|
const PageLayout: FC<PageLayoutProp> = ({
|
||||||
leftPanel,
|
leftPanel,
|
||||||
header,
|
header,
|
||||||
|
@ -134,7 +134,7 @@ const DropDown: React.FC<DropDownProp> = ({
|
|||||||
|
|
||||||
{isDropDownIconVisible ? (
|
{isDropDownIconVisible ? (
|
||||||
<DropdownIcon
|
<DropdownIcon
|
||||||
style={{ marginTop: '7px', color: normalLink }}
|
style={{ marginTop: '5px', color: normalLink }}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
|
@ -89,6 +89,26 @@ const NavBar = ({
|
|||||||
label="Settings"
|
label="Settings"
|
||||||
type="link"
|
type="link"
|
||||||
/>
|
/>
|
||||||
|
<NavLink
|
||||||
|
className="tw-nav focus:tw-no-underline"
|
||||||
|
data-testid="appbar-item-glossary"
|
||||||
|
id="glossary"
|
||||||
|
style={navStyle(pathname.startsWith('/glossary'))}
|
||||||
|
to={{
|
||||||
|
pathname: '/glossary',
|
||||||
|
}}>
|
||||||
|
Glossaries
|
||||||
|
</NavLink>
|
||||||
|
<NavLink
|
||||||
|
className="tw-nav focus:tw-no-underline"
|
||||||
|
data-testid="appbar-item-tags"
|
||||||
|
id="tags"
|
||||||
|
style={navStyle(pathname.startsWith('/tags'))}
|
||||||
|
to={{
|
||||||
|
pathname: '/tags',
|
||||||
|
}}>
|
||||||
|
Tags
|
||||||
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -417,10 +417,8 @@ export const navLinkSettings = [
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
isAdminOnly: true,
|
isAdminOnly: true,
|
||||||
},
|
},
|
||||||
{ name: 'Glossaries', to: '/glossary', disabled: false },
|
|
||||||
{ name: 'Roles', to: '/roles', disabled: false, isAdminOnly: true },
|
{ name: 'Roles', to: '/roles', disabled: false, isAdminOnly: true },
|
||||||
{ name: 'Services', to: '/services', disabled: false },
|
{ name: 'Services', to: '/services', disabled: false },
|
||||||
{ name: 'Tags', to: '/tags', disabled: false },
|
|
||||||
{
|
{
|
||||||
name: 'Teams & Users',
|
name: 'Teams & Users',
|
||||||
to: ROUTES.TEAMS_AND_USERS,
|
to: ROUTES.TEAMS_AND_USERS,
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Card } from 'antd';
|
||||||
import { AxiosError, AxiosResponse } from 'axios';
|
import { AxiosError, AxiosResponse } from 'axios';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { compare } from 'fast-json-patch';
|
import { compare } from 'fast-json-patch';
|
||||||
@ -37,7 +38,9 @@ import Description from '../../components/common/description/Description';
|
|||||||
import ErrorPlaceHolder from '../../components/common/error-with-placeholder/ErrorPlaceHolder';
|
import ErrorPlaceHolder from '../../components/common/error-with-placeholder/ErrorPlaceHolder';
|
||||||
import NonAdminAction from '../../components/common/non-admin-action/NonAdminAction';
|
import NonAdminAction from '../../components/common/non-admin-action/NonAdminAction';
|
||||||
import PageContainerV1 from '../../components/containers/PageContainerV1';
|
import PageContainerV1 from '../../components/containers/PageContainerV1';
|
||||||
import PageLayout from '../../components/containers/PageLayout';
|
import PageLayout, {
|
||||||
|
leftPanelAntCardStyle,
|
||||||
|
} from '../../components/containers/PageLayout';
|
||||||
import Loader from '../../components/Loader/Loader';
|
import Loader from '../../components/Loader/Loader';
|
||||||
import ConfirmationModal from '../../components/Modals/ConfirmationModal/ConfirmationModal';
|
import ConfirmationModal from '../../components/Modals/ConfirmationModal/ConfirmationModal';
|
||||||
import AddRoleModal from '../../components/Modals/RoleModal/AddRoleModal';
|
import AddRoleModal from '../../components/Modals/RoleModal/AddRoleModal';
|
||||||
@ -579,33 +582,39 @@ const RolesPage = () => {
|
|||||||
|
|
||||||
const fetchLeftPanel = (roles: Array<Role>) => {
|
const fetchLeftPanel = (roles: Array<Role>) => {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Card
|
||||||
<div className="tw-flex tw-justify-between tw-items-center tw-mb-3 tw-border-b">
|
data-testid="data-summary-container"
|
||||||
<h6
|
style={leftPanelAntCardStyle}
|
||||||
className="tw-heading tw-text-base"
|
title={
|
||||||
data-testid="left-panel-title">
|
<div className="tw-flex tw-justify-between tw-items-center">
|
||||||
Roles
|
<h6
|
||||||
</h6>
|
className="tw-heading tw-text-base"
|
||||||
</div>
|
data-testid="left-panel-title">
|
||||||
{roles &&
|
Roles
|
||||||
roles.map((role) => (
|
</h6>
|
||||||
<div
|
</div>
|
||||||
className={`tw-group tw-text-grey-body tw-cursor-pointer tw-text-body tw-mb-3 tw-flex tw-justify-between ${getActiveCatClass(
|
}>
|
||||||
role.name,
|
<Fragment>
|
||||||
currentRole?.name
|
{roles &&
|
||||||
)}`}
|
roles.map((role) => (
|
||||||
data-testid="role-name-container"
|
<div
|
||||||
key={role.name}
|
className={`tw-group tw-text-grey-body tw-cursor-pointer tw-text-body tw-mb-3 tw-flex tw-justify-between ${getActiveCatClass(
|
||||||
onClick={() => setCurrentRole(role)}>
|
role.name,
|
||||||
<p
|
currentRole?.name
|
||||||
className="tag-category label-category tw-self-center tw-truncate tw-w-52"
|
)}`}
|
||||||
title={role.displayName}>
|
data-testid="role-name-container"
|
||||||
<span>{role.displayName}</span>{' '}
|
key={role.name}
|
||||||
</p>
|
onClick={() => setCurrentRole(role)}>
|
||||||
{role.defaultRole ? getDefaultBadge() : null}
|
<span
|
||||||
</div>
|
className="tag-category label-category tw-self-center tw-truncate tw-w-52"
|
||||||
))}
|
title={role.displayName}>
|
||||||
</Fragment>
|
<span>{role.displayName}</span>{' '}
|
||||||
|
</span>
|
||||||
|
{role.defaultRole ? getDefaultBadge() : null}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</Fragment>
|
||||||
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1113,7 +1122,10 @@ const RolesPage = () => {
|
|||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Loader />
|
<Loader />
|
||||||
) : (
|
) : (
|
||||||
<div className="tw-pb-3" data-testid="role-container">
|
<div
|
||||||
|
className="tw-pb-3 tw-bg-white"
|
||||||
|
data-testid="role-container"
|
||||||
|
style={{ padding: '14px' }}>
|
||||||
{getRolesContainer()}
|
{getRolesContainer()}
|
||||||
|
|
||||||
{getAddRoleForm()}
|
{getAddRoleForm()}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Card } from 'antd';
|
||||||
import { AxiosError, AxiosResponse } from 'axios';
|
import { AxiosError, AxiosResponse } from 'axios';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { isNil } from 'lodash';
|
import { isNil } from 'lodash';
|
||||||
@ -25,7 +26,9 @@ import NextPrevious from '../../components/common/next-previous/NextPrevious';
|
|||||||
import NonAdminAction from '../../components/common/non-admin-action/NonAdminAction';
|
import NonAdminAction from '../../components/common/non-admin-action/NonAdminAction';
|
||||||
import RichTextEditorPreviewer from '../../components/common/rich-text-editor/RichTextEditorPreviewer';
|
import RichTextEditorPreviewer from '../../components/common/rich-text-editor/RichTextEditorPreviewer';
|
||||||
import PageContainerV1 from '../../components/containers/PageContainerV1';
|
import PageContainerV1 from '../../components/containers/PageContainerV1';
|
||||||
import PageLayout from '../../components/containers/PageLayout';
|
import PageLayout, {
|
||||||
|
leftPanelAntCardStyle,
|
||||||
|
} from '../../components/containers/PageLayout';
|
||||||
import Loader from '../../components/Loader/Loader';
|
import Loader from '../../components/Loader/Loader';
|
||||||
import {
|
import {
|
||||||
getServiceDetailsPath,
|
getServiceDetailsPath,
|
||||||
@ -231,36 +234,41 @@ const ServicesPage = () => {
|
|||||||
|
|
||||||
const fetchLeftPanel = () => {
|
const fetchLeftPanel = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<Card
|
||||||
<div className="tw-flex tw-justify-between tw-items-center tw-mb-3 tw-border-b">
|
data-testid="data-summary-container"
|
||||||
<h6 className="tw-heading tw-text-base">Services</h6>
|
style={leftPanelAntCardStyle}
|
||||||
</div>
|
title={
|
||||||
|
<div className="tw-flex tw-justify-between tw-items-center">
|
||||||
|
<h6 className="tw-heading tw-text-base">Services</h6>
|
||||||
|
</div>
|
||||||
|
}>
|
||||||
|
<>
|
||||||
|
{getServiceTabs()?.map((tab, index) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`tw-group tw-text-grey-body tw-cursor-pointer tw-text-body tw-mb-3 tw-flex tw-justify-between ${getActiveCatClass(
|
||||||
|
tab.name,
|
||||||
|
serviceName
|
||||||
|
)}`}
|
||||||
|
data-testid="tab"
|
||||||
|
key={index}
|
||||||
|
onClick={() => {
|
||||||
|
handleTabChange(tab.name);
|
||||||
|
}}>
|
||||||
|
<p className="tw-text-center tw-self-center label-category">
|
||||||
|
{tab.displayName}
|
||||||
|
</p>
|
||||||
|
|
||||||
{getServiceTabs()?.map((tab, index) => {
|
{getCountBadge(
|
||||||
return (
|
servicesCount[tab.name],
|
||||||
<div
|
'tw-self-center',
|
||||||
className={`tw-group tw-text-grey-body tw-cursor-pointer tw-text-body tw-mb-3 tw-flex tw-justify-between ${getActiveCatClass(
|
tab.name === serviceName
|
||||||
tab.name,
|
)}
|
||||||
serviceName
|
</div>
|
||||||
)}`}
|
);
|
||||||
data-testid="tab"
|
})}
|
||||||
key={index}
|
</>
|
||||||
onClick={() => {
|
</Card>
|
||||||
handleTabChange(tab.name);
|
|
||||||
}}>
|
|
||||||
<p className="tw-text-center tw-self-center label-category">
|
|
||||||
{tab.displayName}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{getCountBadge(
|
|
||||||
servicesCount[tab.name],
|
|
||||||
'tw-self-center',
|
|
||||||
tab.name === serviceName
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -406,53 +414,56 @@ const ServicesPage = () => {
|
|||||||
className="tw-grid xl:tw-grid-cols-4 tw-grid-cols-2 tw-gap-4 tw-mb-4"
|
className="tw-grid xl:tw-grid-cols-4 tw-grid-cols-2 tw-gap-4 tw-mb-4"
|
||||||
data-testid="data-container">
|
data-testid="data-container">
|
||||||
{serviceList.map((service, index) => (
|
{serviceList.map((service, index) => (
|
||||||
<div
|
<Card key={index} style={leftPanelAntCardStyle}>
|
||||||
className="tw-card tw-flex tw-py-2 tw-px-3 tw-justify-between tw-text-grey-muted"
|
<div
|
||||||
data-testid="service-card"
|
className="tw-flex tw-py-2 tw-px-3 tw-justify-between tw-text-grey-muted"
|
||||||
key={index}>
|
data-testid="service-card">
|
||||||
<div className="tw-flex tw-flex-col tw-justify-between tw-truncate">
|
<div className="tw-flex tw-flex-col tw-justify-between tw-truncate">
|
||||||
<div>
|
<div>
|
||||||
<Link to={getServiceDetailsPath(service.name, serviceName)}>
|
<Link to={getServiceDetailsPath(service.name, serviceName)}>
|
||||||
<button>
|
<button>
|
||||||
<h6
|
<h6
|
||||||
className="tw-text-base tw-text-grey-body tw-font-medium tw-text-left tw-truncate tw-w-48"
|
className="tw-text-base tw-text-grey-body tw-font-medium tw-text-left tw-truncate tw-w-48"
|
||||||
data-testid={`service-name-${getEntityName(
|
data-testid={`service-name-${getEntityName(
|
||||||
service as EntityReference
|
service as EntityReference
|
||||||
)}`}
|
)}`}
|
||||||
title={getEntityName(service as EntityReference)}>
|
title={getEntityName(service as EntityReference)}>
|
||||||
{getEntityName(service as EntityReference)}
|
{getEntityName(service as EntityReference)}
|
||||||
</h6>
|
</h6>
|
||||||
</button>
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
<div
|
<div
|
||||||
className="tw-text-grey-body tw-pb-1 tw-break-all description-text"
|
className="tw-text-grey-body tw-pb-1 tw-break-all description-text"
|
||||||
data-testid="service-description">
|
data-testid="service-description">
|
||||||
{service.description ? (
|
{service.description ? (
|
||||||
<RichTextEditorPreviewer
|
<RichTextEditorPreviewer
|
||||||
enableSeeMoreVariant={false}
|
enableSeeMoreVariant={false}
|
||||||
markdown={service.description}
|
markdown={service.description}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<span className="tw-no-description">No description</span>
|
<span className="tw-no-description">
|
||||||
)}
|
No description
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{getOptionalFields(service)}
|
||||||
|
</div>
|
||||||
|
<div className="" data-testid="service-type">
|
||||||
|
<label className="tw-mb-0">Type:</label>
|
||||||
|
<span className=" tw-ml-1 tw-font-normal tw-text-grey-body">
|
||||||
|
{service.serviceType}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{getOptionalFields(service)}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="" data-testid="service-type">
|
<div className="tw-flex tw-flex-col tw-justify-between tw-flex-none">
|
||||||
<label className="tw-mb-0">Type:</label>
|
<div
|
||||||
<span className=" tw-ml-1 tw-font-normal tw-text-grey-body">
|
className="tw-flex tw-justify-end"
|
||||||
{service.serviceType}
|
data-testid="service-icon">
|
||||||
</span>
|
{getServiceLogo(service.serviceType || '', 'tw-h-8')}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="tw-flex tw-flex-col tw-justify-between tw-flex-none">
|
</Card>
|
||||||
<div
|
|
||||||
className="tw-flex tw-justify-end"
|
|
||||||
data-testid="service-icon">
|
|
||||||
{getServiceLogo(service.serviceType || '', 'tw-h-8')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
@ -490,7 +501,7 @@ const ServicesPage = () => {
|
|||||||
<ErrorPlaceHolder>{errorMessage}</ErrorPlaceHolder>
|
<ErrorPlaceHolder>{errorMessage}</ErrorPlaceHolder>
|
||||||
) : (
|
) : (
|
||||||
<PageLayout leftPanel={fetchLeftPanel()}>
|
<PageLayout leftPanel={fetchLeftPanel()}>
|
||||||
<div data-testid="services-container">
|
<div data-testid="services-container" style={{ padding: '14px' }}>
|
||||||
{getServiceList()}
|
{getServiceList()}
|
||||||
|
|
||||||
{getPagination()}
|
{getPagination()}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
import { Card } from 'antd';
|
||||||
import { AxiosError, AxiosResponse } from 'axios';
|
import { AxiosError, AxiosResponse } from 'axios';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { isUndefined, toLower } from 'lodash';
|
import { isUndefined, toLower } from 'lodash';
|
||||||
@ -34,7 +35,9 @@ import ErrorPlaceHolder from '../../components/common/error-with-placeholder/Err
|
|||||||
import NonAdminAction from '../../components/common/non-admin-action/NonAdminAction';
|
import NonAdminAction from '../../components/common/non-admin-action/NonAdminAction';
|
||||||
import RichTextEditorPreviewer from '../../components/common/rich-text-editor/RichTextEditorPreviewer';
|
import RichTextEditorPreviewer from '../../components/common/rich-text-editor/RichTextEditorPreviewer';
|
||||||
import PageContainerV1 from '../../components/containers/PageContainerV1';
|
import PageContainerV1 from '../../components/containers/PageContainerV1';
|
||||||
import PageLayout from '../../components/containers/PageLayout';
|
import PageLayout, {
|
||||||
|
leftPanelAntCardStyle,
|
||||||
|
} from '../../components/containers/PageLayout';
|
||||||
import Loader from '../../components/Loader/Loader';
|
import Loader from '../../components/Loader/Loader';
|
||||||
import ConfirmationModal from '../../components/Modals/ConfirmationModal/ConfirmationModal';
|
import ConfirmationModal from '../../components/Modals/ConfirmationModal/ConfirmationModal';
|
||||||
import FormModal from '../../components/Modals/FormModal';
|
import FormModal from '../../components/Modals/FormModal';
|
||||||
@ -397,52 +400,56 @@ const TagsPage = () => {
|
|||||||
|
|
||||||
const fetchLeftPanel = () => {
|
const fetchLeftPanel = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<Card data-testid="data-summary-container" style={leftPanelAntCardStyle}>
|
||||||
<div className="tw-flex tw-justify-between tw-items-center tw-mb-3 tw-border-b">
|
<>
|
||||||
<h6 className="tw-heading tw-text-base">Tag Categories</h6>
|
<div className="tw-flex tw-justify-between tw-items-center tw-mb-3 tw-border-b">
|
||||||
<NonAdminAction position="bottom" title={TITLE_FOR_NON_ADMIN_ACTION}>
|
<h6 className="tw-heading tw-text-base">Tag Categories</h6>
|
||||||
<Button
|
<NonAdminAction
|
||||||
className={classNames('tw-h-7 tw-px-2 tw-mb-4', {
|
position="bottom"
|
||||||
'tw-opacity-40': !isAdminUser && !isAuthDisabled,
|
title={TITLE_FOR_NON_ADMIN_ACTION}>
|
||||||
})}
|
<Button
|
||||||
data-testid="add-category"
|
className={classNames('tw-h-7 tw-px-2 tw-mb-4', {
|
||||||
size="small"
|
'tw-opacity-40': !isAdminUser && !isAuthDisabled,
|
||||||
theme="primary"
|
})}
|
||||||
variant="contained"
|
data-testid="add-category"
|
||||||
onClick={() => {
|
size="small"
|
||||||
setIsAddingCategory((prevState) => !prevState);
|
theme="primary"
|
||||||
setErrorDataCategory(undefined);
|
variant="contained"
|
||||||
}}>
|
onClick={() => {
|
||||||
<FontAwesomeIcon icon="plus" />
|
setIsAddingCategory((prevState) => !prevState);
|
||||||
</Button>
|
setErrorDataCategory(undefined);
|
||||||
</NonAdminAction>
|
}}>
|
||||||
</div>
|
<FontAwesomeIcon icon="plus" />
|
||||||
{categories &&
|
</Button>
|
||||||
categories.map((category: TagCategory) => (
|
</NonAdminAction>
|
||||||
<div
|
</div>
|
||||||
className={`tw-group tw-text-grey-body tw-cursor-pointer tw-text-body tw-mb-3 tw-flex tw-justify-between ${getActiveCatClass(
|
{categories &&
|
||||||
category.name,
|
categories.map((category: TagCategory) => (
|
||||||
currentCategory?.name
|
<div
|
||||||
)}`}
|
className={`tw-group tw-text-grey-body tw-cursor-pointer tw-text-body tw-mb-3 tw-flex tw-justify-between ${getActiveCatClass(
|
||||||
data-testid="side-panel-category"
|
category.name,
|
||||||
key={category.name}
|
currentCategory?.name
|
||||||
onClick={() => {
|
)}`}
|
||||||
fetchCurrentCategory(category.name);
|
data-testid="side-panel-category"
|
||||||
}}>
|
key={category.name}
|
||||||
<p className="tw-text-center tw-self-center tag-category label-category">
|
onClick={() => {
|
||||||
{category.displayName ?? category.name}
|
fetchCurrentCategory(category.name);
|
||||||
</p>
|
}}>
|
||||||
|
<p className="tw-text-center tw-self-center tag-category label-category">
|
||||||
|
{category.displayName ?? category.name}
|
||||||
|
</p>
|
||||||
|
|
||||||
{getCountBadge(
|
{getCountBadge(
|
||||||
currentCategory?.name === category.name
|
currentCategory?.name === category.name
|
||||||
? currentCategory.children?.length
|
? currentCategory.children?.length
|
||||||
: category.children?.length || 0,
|
: category.children?.length || 0,
|
||||||
'tw-self-center',
|
'tw-self-center',
|
||||||
currentCategory?.name === category.name
|
currentCategory?.name === category.name
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -458,7 +465,10 @@ const TagsPage = () => {
|
|||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Loader />
|
<Loader />
|
||||||
) : (
|
) : (
|
||||||
<div className="full-height" data-testid="tags-container">
|
<div
|
||||||
|
className="full-height tw-bg-white"
|
||||||
|
data-testid="tags-container"
|
||||||
|
style={{ padding: '14px' }}>
|
||||||
{currentCategory && (
|
{currentCategory && (
|
||||||
<div
|
<div
|
||||||
className="tw-flex tw-justify-between tw-items-center"
|
className="tw-flex tw-justify-between tw-items-center"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user